If course it seems scrollIntoViewIfNeeded is a feature tendered only by WebKit. However I'm working on something that needs to be compatible with IE back to 7, and I need to detect whether something is visible, and if not, then call scrollIntoView() on it.
It's also important to note that I'm not dealing with whole windows, I could be dealing with a smaller DIV in which an element may be scrolled out of the viewable box.
For example, the element with id "pleaseFindMe" should be scrolled into view only if overflowed out of the viewable area of the div.
<div style='border:1px solid black;width:40%; overflow:scroll;'>
<span id='e2' style='white-space: nowrap;' >Lorem ipsum aliqua proident veniam et quis consectetur esse dolore non Ut nulla dolor eu culpa. Lorem ipsum sint cupidatat non et adipisicing esse elit officia. proident, sunt in culpa qui officia deserunt mollit anim <span id='pleaseFindMe'>id est</span> laborum. </span>
</div>
If course it seems scrollIntoViewIfNeeded is a feature tendered only by WebKit. However I'm working on something that needs to be compatible with IE back to 7, and I need to detect whether something is visible, and if not, then call scrollIntoView() on it.
It's also important to note that I'm not dealing with whole windows, I could be dealing with a smaller DIV in which an element may be scrolled out of the viewable box.
For example, the element with id "pleaseFindMe" should be scrolled into view only if overflowed out of the viewable area of the div.
<div style='border:1px solid black;width:40%; overflow:scroll;'>
<span id='e2' style='white-space: nowrap;' >Lorem ipsum aliqua proident veniam et quis consectetur esse dolore non Ut nulla dolor eu culpa. Lorem ipsum sint cupidatat non et adipisicing esse elit officia. proident, sunt in culpa qui officia deserunt mollit anim <span id='pleaseFindMe'>id est</span> laborum. </span>
</div>
Share
Improve this question
asked Jul 12, 2012 at 22:34
andyortliebandyortlieb
2,4063 gold badges23 silver badges34 bronze badges
3 Answers
Reset to default 13Old question, but it seems still relevant on browsers today (IE, Fx). So I wrote some polyfill for 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/
The code is designed to work well in the presence of nested scrollable areas and relatively positioned elements.
IE has supported the beautiful element method getBoundingClientRect
since IE4. Although it has some minor flaws in IE<8, it can definitely be used for your purpose.
So here's the trick:
var findMe = document.getElementById("pleaseFindMe"),
contRect = container.getBoundingClientRect(),
findMeRect = findMe.getBoundingClientRect();
if (findMeRect.top < contRect.top || findMeRect.bottom > contRect.bottom
|| findMeRect.right > contRect.right || findMeRect.left < contRect.left)
findMe.scrollIntoView();
Check out this polyfill on Github. It provides a JavaScript implementation of the non-standard WebKit method scrollIntoViewIfNeeded.