最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - scrollIntoViewIfNeeded() for IE7 - Stack Overflow

programmeradmin0浏览0评论

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
Add a comment  | 

3 Answers 3

Reset to default 13

Old 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.

发布评论

评论列表(0)

  1. 暂无评论