Last active
March 6, 2019 15:22
-
-
Save termi/5063286 to your computer and use it in GitHub Desktop.
Support centering an element when scrolling into view w3c issue: https://www.w3.org/Bugs/Public/show_bug.cgi?id=17152
Original code from http://jsbin.com/ilecok/16/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//////////////////////////////////////////////////////////////////////////////// | |
// Author: Thaddee Tyl 2012. | |
// The following work is under CC0. | |
void function() { | |
// Hook the polyfill. | |
Element.prototype._scrollIntoView = function scrollIntoView(options) { | |
if( !this.ownerDocument )return; | |
var _window = this.ownerDocument.defaultView; | |
// Traditional scrollIntoView. | |
if( !arguments.length || typeof options != "object" ) { | |
return this.scrollIntoView.apply(this, arguments); | |
} | |
// Fetch positional information. | |
// | |
// The following are always from the {top, bottom, left, right} | |
// of the viewport, to the {top, …} of the box. | |
// Think of them as geometrical vectors, it helps. | |
// The axes are directed downwards and towards the right. | |
var rect = this.getBoundingClientRect(), | |
topToBottom = rect.bottom, | |
bottomToTop = rect.top - _window.innerHeight, | |
leftToRight = rect.right, | |
rightToLeft = rect.left - _window.innerWidth, | |
xAllowed = true, // We allow one translation on the x axis, | |
yAllowed = true; // and one on the y axis. | |
// Read options. | |
// | |
// We have the following options: | |
// - float vertical = 0.5 (from 0 to 1). | |
// - float horizontal = 0.0 (from 0 to 1). | |
// - boolean notIfViewed = true | |
if (options.vertical === undefined) options.vertical = 0.5; | |
if (options.horizontal === undefined) options.horizontal = 0.5; | |
if (options.evenIfViewed === undefined) options.evenIfViewed = false; | |
// Whatever `horizontal` and `vertical` are, | |
// the behavior is the same if the box is (even partially) visible. | |
if (topToBottom > 0 && topToBottom <= this.offsetHeight) { | |
if (yAllowed) { | |
_window.scrollBy(0, topToBottom - this.offsetHeight); | |
yAllowed = false; | |
} | |
} | |
else if (bottomToTop < 0 && bottomToTop >= -this.offsetHeight) { | |
if (yAllowed) { | |
_window.scrollBy(0, bottomToTop + this.offsetHeight); | |
yAllowed = false; | |
} | |
} | |
if (leftToRight > 0 && leftToRight <= this.offsetWidth) { | |
if (xAllowed) { | |
_window.scrollBy(leftToRight - this.offsetWidth, 0); | |
xAllowed = false; | |
} | |
} | |
else if (rightToLeft < 0 && rightToLeft >= -this.offsetWidth) { | |
if (xAllowed) { | |
_window.scrollBy(rightToLeft + this.offsetWidth, 0); | |
xAllowed = false; | |
} | |
} | |
// If we want it positioned in the viewport, | |
// and the box is completely hidden, | |
// then we position it explicitly. | |
if( yAllowed | |
&& (options.evenIfViewed ? true : (topToBottom <= 0 || bottomToTop >= 0)) | |
) { | |
_window.scroll( | |
_window.scrollX | |
, _window.scrollY + rect.top - (_window.innerHeight - this.offsetHeight) * options.vertical | |
); | |
} | |
if( xAllowed | |
&& (options.evenIfViewed ? true : (leftToRight <= 0 || rightToLeft <= 0)) | |
) { | |
_window.scroll( | |
_window.scrollX + rect.left - (_window.innerWidth - this.offsetWidth) * options.horizontal | |
, _window.scrollY | |
); | |
} | |
if (_window.parent !== _window) { | |
// We are inside a scrollable element. | |
var frame = _window.frameElement; | |
scrollIntoView.call(frame, options); | |
} | |
}; | |
}.call(this); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Привет! Работает ? )