5

当然,scrollIntoViewIfNeeded 似乎是仅由 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>  
4

3 回答 3

10

老问题,但在今天的浏览器(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/

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

于 2015-11-30T16:30:40.283 回答
9

getBoundingClientRectIE从IE4开始就支持美元素法。虽然它在 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();
于 2012-07-12T22:53:10.630 回答
2

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

于 2014-05-09T09:17:20.870 回答