зеркало из https://github.com/mozilla/gecko-dev.git
57 строки
2.1 KiB
JavaScript
57 строки
2.1 KiB
JavaScript
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
"use strict";
|
|
|
|
// Make this available to both AMD and CJS environments
|
|
define(function (require, exports, module) {
|
|
/**
|
|
* Scroll the document so that the element "elem" appears in the viewport.
|
|
*
|
|
* @param {DOMNode} elem
|
|
* The element that needs to appear in the viewport.
|
|
* @param {Boolean} centered
|
|
* true if you want it centered, false if you want it to appear on the
|
|
* top of the viewport. It is true by default, and that is usually what
|
|
* you want.
|
|
*/
|
|
function scrollIntoViewIfNeeded(elem, centered = true) {
|
|
let win = elem.ownerDocument.defaultView;
|
|
let clientRect = elem.getBoundingClientRect();
|
|
|
|
// The following are always from the {top, bottom}
|
|
// of the viewport, to the {top, …} of the box.
|
|
// Think of them as geometrical vectors, it helps.
|
|
// The origin is at the top left.
|
|
|
|
let topToBottom = clientRect.bottom;
|
|
let bottomToTop = clientRect.top - win.innerHeight;
|
|
// We allow one translation on the y axis.
|
|
let yAllowed = true;
|
|
|
|
// Whatever `centered` is, the behavior is the same if the box is
|
|
// (even partially) visible.
|
|
if ((topToBottom > 0 || !centered) && topToBottom <= elem.offsetHeight) {
|
|
win.scrollBy(0, topToBottom - elem.offsetHeight);
|
|
yAllowed = false;
|
|
} else if ((bottomToTop < 0 || !centered) &&
|
|
bottomToTop >= -elem.offsetHeight) {
|
|
win.scrollBy(0, bottomToTop + elem.offsetHeight);
|
|
yAllowed = false;
|
|
}
|
|
|
|
// If we want it centered, and the box is completely hidden,
|
|
// then we center it explicitly.
|
|
if (centered) {
|
|
if (yAllowed && (topToBottom <= 0 || bottomToTop >= 0)) {
|
|
win.scroll(win.scrollX,
|
|
win.scrollY + clientRect.top
|
|
- (win.innerHeight - elem.offsetHeight) / 2);
|
|
}
|
|
}
|
|
}
|
|
// Exports from this module
|
|
module.exports.scrollIntoViewIfNeeded = scrollIntoViewIfNeeded;
|
|
});
|