Reset scroll position when sticky header search input receives focus to fix Safari bug

I haven't found any code responsible for making the scroll position
jump. It looks like Safari is doing this on its own. Looking at the
focus event in detail [1], it looks like there is an `preventScroll`
option you can pass to .focus() which might help in this situation, but
unfortunately, Safari doesn't seem to support this. Therfore, a hack
like this may be necessary.

[1] https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus

Bug: T297636
Change-Id: I90651293b7dd0f7f2970ba06255a12617b43661f
This commit is contained in:
Nicholas Ray 2021-12-14 10:53:50 -07:00
parent 42fec59f54
commit 17e742e2ab
1 changed files with 17 additions and 0 deletions

View File

@ -71,7 +71,24 @@ function bindToggleClickHandler( searchBox, header, searchToggle ) {
const searchInput = /** @type {HTMLInputElement|null} */ ( searchBox.querySelector( 'input[type="search"]' ) );
if ( searchInput ) {
const beforeScrollX = window.scrollX;
const beforeScrollY = window.scrollY;
searchInput.focus();
// For some reason, Safari 14,15 tends to undesirably change the scroll
// position of `input` elements inside fixed position elements.
// While an Internet search suggests similar problems with mobile Safari
// it didn't yield any results for desktop Safari.
// This line resets any unexpected scrolling that occurred while the
// input received focus.
// If you are in the future with a modern version of Safari, where 14 and 15
// receive a low amount of page views, please reference T297636 and test
// to see whether this line of code can be removed.
// Additionally, these lines might become unnecessary when/if Safari
// supports the `preventScroll` focus option [1] in the future:
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus#parameters
if ( beforeScrollX !== undefined && beforeScrollY !== undefined ) {
window.scroll( beforeScrollX, beforeScrollY );
}
}
} );
};