scrollIntoViewIfNeeded() for IE7



如果课程看起来滚动IntoViewIfNeeded是仅由WebKit提供的功能。然而,我正在研究一些需要与IE兼容的东西,回到7,我需要检测一些东西是否可见,如果不可见,那么调用它的scrollIntoView()。

同样重要的是要注意,我不是在处理整个窗口,我可能是在处理一个较小的DIV,其中一个元素可以从可视框中滚动出来。

例如,id为"pleaseFindMe"的元素只有在溢出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>  

这个老问题,但它在今天的浏览器(IE、Fx)上似乎仍然相关。所以我为scrollIntoViewIfNeeded()写了一些polyfill。

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/

该代码被设计为在存在嵌套的可滚动区域和相对定位的元素的情况下工作良好。

IE从IE4开始就支持漂亮元素方法getBoundingClientRect。尽管它在IE<8,它绝对可以用于你的目的。

诀窍是:

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();

在Github上查看这个polyfill。它提供了非标准WebKit方法scrollIntoViewIfNeeded的JavaScript实现。

最新更新