用于IE7的scrollIntoViewIfNeeded()

时间:2012-07-12 22:34:51

标签: javascript html

如果当然看起来scrollIntoViewIfNeeded是仅由WebKit提供的功能。但是我正在研究一些需要与IE兼容的东西,我需要检测某些东西是否可见,如果没有,则调用它上面的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>  

3 个答案:

答案 0 :(得分:9)

老问题,但它似乎仍然适用于今天的浏览器(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/

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

答案 1 :(得分:7)

自IE4以来,IE一直支持漂亮的元素方法getBoundingClientRect。虽然它在IE&lt; 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();

答案 2 :(得分:2)

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