老问题,但在今天的浏览器(IE,Fx)上似乎仍然相关。所以我为scrollIntoViewIfNeeded()
.
if (!Element.prototype.scrollIntoViewIfNeeded) {
Element.prototype.scrollIntoViewIfNeeded = function (centerIfNeeded) {
"use strict";
function makeRange(start, length) {
return {"start": start, "length": length, "end": start + length};
}
function coverRange(inner, outer) {
if (false === centerIfNeeded ||
(outer.start < inner.end && inner.start < outer.end))
{
return Math.min(
inner.start, Math.max(outer.start, inner.end - outer.length)
);
}
return (inner.start + inner.end - outer.length) / 2;
}
function makePoint(x, y) {
return {
"x": x, "y": y,
"translate": function translate(dX, dY) {
return makePoint(x + dX, y + dY);
}
};
}
function absolute(elem, pt) {
while (elem) {
pt = pt.translate(elem.offsetLeft, elem.offsetTop);
elem = elem.offsetParent;
}
return pt;
}
var target = absolute(this, makePoint(0, 0)),
extent = makePoint(this.offsetWidth, this.offsetHeight),
elem = this.parentNode,
origin;
while (elem instanceof HTMLElement) {
// Apply desired scroll amount.
origin = absolute(elem, makePoint(elem.clientLeft, elem.clientTop));
elem.scrollLeft = coverRange(
makeRange(target.x - origin.x, extent.x),
makeRange(elem.scrollLeft, elem.clientWidth)
);
elem.scrollTop = coverRange(
makeRange(target.y - origin.y, extent.y),
makeRange(elem.scrollTop, elem.clientHeight)
);
// Determine actual scroll amount by reading back scroll properties.
target = target.translate(-elem.scrollLeft, -elem.scrollTop);
elem = elem.parentNode;
}
};
}
http://jsfiddle.net/obnpd7ra/
该代码旨在在存在嵌套可滚动区域和相对定位的元素的情况下运行良好。