22

jQuery's scrollTop returns null when window is an iframe. Has anyone been able to figure out how to get scrollTop of an iframe?

more info:

my script is running in the iframe itself, the parent window is on another domain, so I can't access the ID of the iframe or anything like that

Zanon
  • 29,231
  • 20
  • 113
  • 126
mkoryak
  • 57,086
  • 61
  • 201
  • 257

10 Answers10

32

I found this question while trying to SET scrollTop inside an iframe... not exactly your question (you wanted to GET) but here's a solution inside iframes for people that also end up here trying to SET.

If you want to scroll to the top of the page this will NOT work inside an iframe:

$("html,body").scrollTop(0);

However, this will work:

document.getElementById("wrapper").scrollIntoView();

Or the equivilent with jQuery:

 $("#wrapper")[0].scrollIntoView();

For this markup (contained inside an iframe):

<html>
  <body>
    <div id="wrapper">
      <!-- lots of content -->
    </div>
  </body>
</html>
Andrew
  • 18,680
  • 13
  • 103
  • 118
Chris Jacob
  • 11,878
  • 7
  • 47
  • 42
  • 1
    Thanks for this point @chris. For Firefox, Only the DOM scrollIntoView did work for the page that was within an iframe (Google Chrome works with just $("body").scrollTop(0); ). For the jquery lovers, it is $("#wrapper")[0].scrollIntoView(); – rsmoorthy May 11 '11 at 06:07
  • 2
    very nice. from outside the iframe `document.getElementsByTagName('iframe')[0].contentWindow.document.getElementById('myElementId').scrollIntoView();` – But those new buttons though.. Nov 23 '15 at 16:12
25
$('#myIframe').contents().scrollTop()
Adam V.
  • 1,765
  • 1
  • 16
  • 18
  • Don't know about OP but this solved it for me all the way. I was dealing with an iframe, and completely forgot to apply scrollTop() to the contents of it. Duh! – William S Aug 14 '16 at 14:10
  • Cheers. THis worked perfectly for my case - an iframe taking up 100% of the viewport with a modal/overlay loaded in it. Thanks! – Barry Chapman Nov 18 '17 at 03:19
  • I need to set (0) to make it work. see other Anser by @Peppeneppe – Sarah Trees Nov 28 '20 at 16:47
12

You can set scrollTop by using this setup:

$("html,body").scrollTop(25);

So you could try getting it like this:

$("html,body").scrollTop();

Because different browsers set the scrollTop on different elements (body or html).

From the scrollTo plugin:

But that will probably still fail in certain browsers. Here is the relevant section from the source code of Ariel Flesher's scrollTo plugin for jQuery:

// Hack, hack, hack :)
// Returns the real elements to scroll (supports window/iframes, documents and regular nodes)
$.fn._scrollable = function(){
  return this.map(function(){
    var elem = this,
      isWin = !elem.nodeName || $.inArray( elem.nodeName.toLowerCase(), ['iframe','#document','html','body'] ) != -1;

    if( ! isWin ) {
      return elem;
    }


    var doc = (elem.contentWindow || elem).document || elem.ownerDocument || elem;

     return $.browser.safari || doc.compatMode == 'BackCompat' ?
       doc.body : 
       doc.documentElement;
  });
};

You may then run:

$(window)._scrollable().scrollTop();

To determine how far the iframe has scrolled down.

mikemaccana
  • 110,530
  • 99
  • 389
  • 494
Doug Neiner
  • 65,509
  • 13
  • 109
  • 118
8

Good old javascript:

scrollTop = document.getElementById(IFRAME_ID).contentWindow.document.body.scrollTop;
dudkaman
  • 97
  • 1
  • 1
  • 3
    For javascript inside the iframe, leave off the portion that returns the iframe itself: `scrollTop = document.body.scrollTop;` – Sabrina S Jan 08 '16 at 18:18
3
$('#myIframe').contents().scrollTop(0);

Only works with "0" as parameter

Peppeneppe
  • 131
  • 2
  • 4
  • If the argument `0` is given, the frame will scroll to top (0 pixels from top). Without the argument, the amount of pixels from the top will be returned => that's what this question is about! – Jacob van Lingen May 30 '17 at 06:35
  • In my case nothing scroll without (0). Only by setting (0) it scrolls to the top. That should by the correct answer. – Sarah Trees Nov 28 '20 at 16:49
1

I have try to

$('#myIframe').contents().scrollTop(0);

and

 let scrollTop = document.getElementById(IFRAME_ID).contentWindow.document.body.scrollTop;

the first function work success in desktop browser. not working in mobile browser. so I use another function with scrollIntoView

$("#ButtonId").click(function() {
        var win = document.getElementById(IFRAMEID).contentWindow;
        var scrollTop = win.document.documentElement.scrollTop || win.pageYOffset || win.document.body.scrollTop;
        // scrollTop can getted
        if (scrollTop) {
            win.document.documentElement.scrollTop = 0;
            win.pageYOffset = 0; // safari
            win.document.body.scrollTop = 0;
        } else {
            win.document.body.scrollIntoView(true); // let scroll to the target view 
        }
    });

scrollIntoView() view in scrollIntoView - MDN

林平君
  • 111
  • 1
  • 2
0

or use this one

sample.showLoader = function() {
// show cursor wait
document.getElementsByTagName('body')[0].style.cursor = 'wait';
var loader = $('#statusloader');
// check if we're runnign within an iframe
var isIframe = top !== self;
if (isIframe) {
    var topPos = top.pageYOffset + 300;
    // show up loader in middle of the screen
    loader.show().css({
        top : topPos,
        left : '50%'
    });
} else {
    // show up loader in middle of the screen
    loader.show().css({
        top : '50%',
        left : '50%'
    });
}
};
hypery2k
  • 1,681
  • 15
  • 20
0

I know I'm late to the game here, but I was trying to figure this out for a long list on mobile. scrollTop() wasn't working for me due to cross-domain conflicts(and I didn't have access to parent window), but changing the height did:

$('#someClickableElementInIFrame').on('click', function(e){
      $("html body").animate({
      'height' : "0"
    }, {
        complete: function(){
          $("html body").css({
            'height' : "auto"
            })
          }
      })
});
BenTheHumanMan
  • 327
  • 2
  • 11
0

Cause you using iFrame you will need to use it that way with windows "message" event

Read here for more Info

On Child View (Iframe)

window.top.postMessage(0 + '$' + 'form-iframe-top', "*");

On Parent View

   window.addEventListener("message",function(e) {
       if (e && e.data && typeof e.data == "string" && e.data != undefined) {
         var data = e.data.split("$");
             if (data.length == 2) {
               var scroll_height = data[0], iframe_id = data[1];
               if(iframe_id=="form-iframe-top"){
                   window.scrollTo(0,scroll_height);
                   return;
                  }
               }
          }
         },
        false
      );

**Note i used "*" as separator you can use anything

eliprodigy
  • 600
  • 6
  • 8
0

I have faced the same problem in my iframe. My whole website comming white iframe and scrolling not working So I used this code and it's work fine.

Step 1. put this code to your iframe

var offsettop =  120;
window.parent.postMessage({"setAnchor": offsettop}, "*");

Step 2. put this code where your call you iframe

window.addEventListener('message', function(event) {
  if(event.data['setAnchor']>0) {
    var offsetHeight =event.data['setAnchor'];
    jQuery('html, body').animate({
      scrollTop: offsetHeight
    }, 200);
  } 
})
Azametzin
  • 5,223
  • 12
  • 28
  • 46