简体   繁体   中英

Center focused element of webpages vertically

When changing the focus to another element of a website (eg to another input field by pressing TAB) which is not in your viewing area (eg you're at the bottom of the page and the new element is at the top) all browsers (tested Internet Explorer, Firefox, Chrome at Windows OS) seem to scroll just enough so that the element with the new focus is visible.

Example:

Image
Text
Input text
...
Footer

When you're at the Footer and Image to Input text is not inside your viewing area and you're now pressing tab so the focus jumps to Input text this field is now visible for you but not Image nor Text .

While this behaviour might be appropriate in most of the cases, in my case it isn't. To prevent it I suggest that focused elements are centered vertically. How can this be done?

To make it more clear:

This is the whole page:

在此输入图像描述

I'm scrolling down to the bottom so only "This is the footer" is visible:

在此输入图像描述

I'm now changing the focus by pressing tab. The focus jumps to the text input. Unfortunately the elements above this text field aren't visible:

在此输入图像描述

If one wrap both image and text with the input into a label, it appears to work without script.

 <label for="input1"> <img src="http://placehold.it/350x50"><br> Some text that should be visible <input id="input1" type="text"> </label> <br> <br> <br> <label for="input2"> <img src="http://placehold.it/350x50"><br> Some text that should be visible <input id="input2" type="text"> </label> <br> <br> <br> <label for="input3"> <img src="http://placehold.it/350x50"><br> Some text that should be visible <input id="input3" type="text"> </label> <br> <br> <br> <label for="input4"> <img src="http://placehold.it/350x50"><br> Some text that should be visible <input id="input4" type="text"> </label> <br> 

I you can't use labels, I suggest you add an event handler, where you catch the "tab key", get the element with focus and either get its parent element (which likely contains your input and text and image) and scroll that parent into view

document.activeElement.parentNode.scrollIntoView();

or you need to calculate the document.activeElement 's position and scroll it to the center, and here is a excellent way made by ThinkingStiff which I updated with a scrollIntoViewCenter method.

Element.prototype.documentOffsetTop = function () {
    return this.offsetTop + ( this.offsetParent ? this.offsetParent.documentOffsetTop() : 0 );
};
Element.prototype.scrollIntoViewCenter = function () {
  window.scrollTo( 0, this.documentOffsetTop() - (window.innerHeight / 2 ) );
};

And here is a snippet showing the scrollIntoViewCenter method.

 Element.prototype.documentOffsetTop = function () { return this.offsetTop + ( this.offsetParent ? this.offsetParent.documentOffsetTop() : 0 ); }; Element.prototype.scrollIntoViewCenter = function () { window.scrollTo( 0, this.documentOffsetTop() - (window.innerHeight / 2 ) ); }; window.addEventListener("keyup", myScript); function myScript(e) { if ('9' == e.keyCode) { // tab = 9 //find and vertically center focused input document.activeElement.scrollIntoViewCenter(); } } 
 <img src="http://placehold.it/350x50"><br> Some text that should be visible <input id="input1" type="text"> <br> <br> <br> <img src="http://placehold.it/350x50"><br> Some text that should be visible <input id="input2" type="text"> <br> <br> <br> <img src="http://placehold.it/350x50"><br> Some text that should be visible <input id="input3" type="text"> <br> <br> <br> <img src="http://placehold.it/350x50"><br> Some text that should be visible <input id="input4" type="text"> <br> <br> <br> <img src="http://placehold.it/350x50"><br> Some text that should be visible <input id="input5" type="text"> <br> <br> <br> <img src="http://placehold.it/350x50"><br> Some text that should be visible <input id="input6" type="text"> <br> <br> <br> 

sorry but I don't understand why you want to center vertically the elements? You can get focused event and prevent it when the element focused be the hidden.

var items = $(document).getElementsByTagName("*");
for (var i = items.length; i--;) {
    $(this).focus(function() {
        if ($(this).attr('id') == 'ID FOR THE HIDDEN ELEMENT') {
            // Disabled focus or pass focus to next element
            $(this).blur(); // Disabled
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM