UNPKG

focus-options-polyfill

Version:

JavaScript polyfill for the WHATWG spec of focusOptions, that enables a set of options to be passed to the focus method.

101 lines (91 loc) 2.83 kB
// focus - focusOptions - preventScroll polyfill (function() { if ( typeof window === "undefined" || typeof document === "undefined" || typeof HTMLElement === "undefined" ) { return; } var supportsPreventScrollOption = false; try { var focusElem = document.createElement("div"); focusElem.addEventListener( "focus", function(event) { event.preventDefault(); event.stopPropagation(); }, true ); focusElem.focus( Object.defineProperty({}, "preventScroll", { get: function() { // Edge v18 gives a false positive for supporting inputs if ( navigator && typeof navigator.userAgent !== 'undefined' && navigator.userAgent && navigator.userAgent.match(/Edge\/1[7-8]/)) { return supportsPreventScrollOption = false } supportsPreventScrollOption = true; } }) ); } catch (e) {} if ( HTMLElement.prototype.nativeFocus === undefined && !supportsPreventScrollOption ) { HTMLElement.prototype.nativeFocus = HTMLElement.prototype.focus; var calcScrollableElements = function(element) { var parent = element.parentNode; var scrollableElements = []; var rootScrollingElement = document.scrollingElement || document.documentElement; while (parent && parent !== rootScrollingElement) { if ( parent.offsetHeight < parent.scrollHeight || parent.offsetWidth < parent.scrollWidth ) { scrollableElements.push([ parent, parent.scrollTop, parent.scrollLeft ]); } parent = parent.parentNode; } parent = rootScrollingElement; scrollableElements.push([parent, parent.scrollTop, parent.scrollLeft]); return scrollableElements; }; var restoreScrollPosition = function(scrollableElements) { for (var i = 0; i < scrollableElements.length; i++) { scrollableElements[i][0].scrollTop = scrollableElements[i][1]; scrollableElements[i][0].scrollLeft = scrollableElements[i][2]; } scrollableElements = []; }; var patchedFocus = function(args) { if (args && args.preventScroll) { var evScrollableElements = calcScrollableElements(this); if (typeof setTimeout === 'function') { var thisElem = this; setTimeout(function () { thisElem.nativeFocus(); restoreScrollPosition(evScrollableElements); }, 0); } else { this.nativeFocus(); restoreScrollPosition(evScrollableElements); } } else { this.nativeFocus(); } }; HTMLElement.prototype.focus = patchedFocus; } })();