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

javascript - Scroll to a particular ID within an iframe while retaining parent page position - Stack Overflow

programmeradmin3浏览0评论

I needed to be able to load a particular page in an iframe on demand, so I used a simple wrapper:

function updateFrame(url) {
    frames[0].location = url;
}

Then I was asked to load the page to a particular point, which was non-trivial, since the pages were not within my control and there weren't always <a name> anchors to rely on. So some poking around showed that IDs could be used as anchors.

That is to say, you can scroll to <div id = "somewhere-down-the-line"> with:

updateFrame("http://host/page#somewhere-down-the-line");

except this call also scrolls the entire viewport up so that the above <div> goes to the top and everything in the parent page above it scrolls out of view.

How do I modify updateFrame(url) so that it scrolls the page within the <iframe> but leaves the rest of the page as it is?

This hack worked for me on Firefox 20.0.1/Windows. Essentially, I load the page first, then jump to the target:

function updateFrame(url) {
    if (url.indexOf('#') > -1) {
        mainPage = url.split('#')[0];
        frames[0].location = mainPage;
    }
    frames[0].location = url;
}

I would like to be able to use this in other browsers as well. I have been trying to get it to work in Chrome. Maybe I'll even try Internet Explorer...

I needed to be able to load a particular page in an iframe on demand, so I used a simple wrapper:

function updateFrame(url) {
    frames[0].location = url;
}

Then I was asked to load the page to a particular point, which was non-trivial, since the pages were not within my control and there weren't always <a name> anchors to rely on. So some poking around showed that IDs could be used as anchors.

That is to say, you can scroll to <div id = "somewhere-down-the-line"> with:

updateFrame("http://host/page#somewhere-down-the-line");

except this call also scrolls the entire viewport up so that the above <div> goes to the top and everything in the parent page above it scrolls out of view.

How do I modify updateFrame(url) so that it scrolls the page within the <iframe> but leaves the rest of the page as it is?

This hack worked for me on Firefox 20.0.1/Windows. Essentially, I load the page first, then jump to the target:

function updateFrame(url) {
    if (url.indexOf('#') > -1) {
        mainPage = url.split('#')[0];
        frames[0].location = mainPage;
    }
    frames[0].location = url;
}

I would like to be able to use this in other browsers as well. I have been trying to get it to work in Chrome. Maybe I'll even try Internet Explorer...

Share Improve this question edited Jul 22, 2013 at 7:18 icedwater asked May 15, 2013 at 8:10 icedwatericedwater 4,9063 gold badges38 silver badges53 bronze badges 9
  • Also, I was wondering since when the IDs became valid anchors. Can't seem to find the W3C remendation that changed this. – icedwater Commented May 15, 2013 at 8:21
  • Is the iframe on the same domain, or could it be a different domain? – Jordan Gray Commented Jul 25, 2013 at 13:11
  • It could be on a different domain. Does that make a difference? I know about CSRF and security measures, but I'm not sure how this may affect the scrolling / refreshing behaviour. – icedwater Commented Jul 26, 2013 at 1:30
  • It doesn't stop scrolling from working, but it does rule out a few ideas I had. The best candidate so far is a nasty hack. – Jordan Gray Commented Jul 26, 2013 at 8:06
  • @JordanGray I've even used <meta http-equiv = "refresh" content = "0;site#marker"> in an interstitial, but that didn't help matters. – icedwater Commented Jul 26, 2013 at 8:11
 |  Show 4 more ments

3 Answers 3

Reset to default 3 +75

If a hack is ok, and what you're looking for is cross-browser try using scrollTop to reset where you were.

E.g. if it is the body that scrolls

function updateFrame(url) {
    //save where you were
    var oldScroll = document.body.scrollTop;

    //this moves our body!
    frames[0].location = url;

    //move it back
    document.body.scrollTop = oldScroll;
}

Of course if it doesn't actually scrolls the entire viewport and instead modifies a parent div or something, the scrollTop property will be on that element too.

Let me know if this works, but screws up the scrolling on the frame, because I can modify this to account for a difference between the two scrollTops

You could try turning the bolts yourself by detecting the height of the element you want, and forcing the scrollTop of the frame.

function updateFrame(url) {
    //get the parts
    var parts = url.split('#');
    //go to the url
    frames[0].location = parts[0];

    //if there was an anchor
    var anchor;
    if (parts.length > 0 && parts[1].length > 0) {
        //may want to account for a[name="PARTS[1]"] too
        anchor = frames[0].document.getElementById(parts[1]);

        //set the scroll of it yourself, using some sort of library to get "fullTop"
        frames[0].document.body.scrollTop = anchor.fullTop();
    }
}

Where "fullTop" is equivalent to the distance between the top of the iframe, and the element.
Like jQuery's .offset() or YUI's getXY(el).[1]

What worked for me on Firefox 20.0.1/Windows. Essentially, I load the page first, then jump to the target:

function updateFrame(url) {
    if (url.indexOf('#') > -1) {
        mainPage = url.split('#')[0];
        frames[0].location = mainPage;
    }
    frames[0].location = url;
}

On Chrome 28.0/Windows, calling updateFrame(url) followed by setting document.body.scrollTop = 0 (thanks to this answer) had the desired effect, though only in the console. I am still testing on other browsers; a more elegant solution is always appreciated :)

As mentioned in the question, though, I would like to be able to use this in other browsers as well. Maybe I'll even try Internet Explorer...

发布评论

评论列表(0)

  1. 暂无评论