[javascript] Scrolling an iframe with JavaScript?

I dynamically load an iframe with JavaScript. After it's loaded, how can I make it scroll down a specific number of pixels (ie. after the page in the iframe has loaded, how can I make the iframe scroll by itself to the a specified region of the page?)

This question is related to javascript iframe scroll

The answer is


Based on Chris's comment

CSS
.amazon-rating {
  width: 55px;
  height: 12px;
  overflow: hidden;
}

.rating-stars {
  left: -18px;
  top: -102px;
  position: relative;
}
HAML
.amazon-rating
  %iframe.rating-stars{src: $item->ratingURL, seamless: 'seamless', frameborder: 0, scrolling: 'no'}

Or, you can set a margin-top on the iframe...a bit of a hack but works in FF so far.

#frame {
margin-top:200px;
}

Use the scrollTop property of the frame's content to set the content's vertical scroll-offset to a specific number of pixels (like 100):

<iframe src="foo.html" onload="this.contentWindow.document.documentElement.scrollTop=100"></iframe>

A jQuery solution:

$("#frame1").ready( function() {

  $("#frame1").contents().scrollTop( $("#frame1").contents().scrollTop() + 10 );

});

var $iframe = document.getElementByID('myIfreme');
var childDocument = iframe.contentDocument ? iframe.contentDocument : iframe.contentWindow.document;
 childDocument.documentElement.scrollTop = 0;

You can use the onload event to detect when the iframe has finished loading, and there you can use the scrollTo function on the contentWindow of the iframe, to scroll to a defined position of pixels, from left and top (x, y):

var myIframe = document.getElementById('iframe');
myIframe.onload = function () {
    myIframe.contentWindow.scrollTo(xcoord,ycoord);
}

You can check a working example here.

Note: This will work if both pages reside on the same domain.


I've also had trouble using any type of javascript "scrollTo" function in an iframe on an iPad. Finally found an "old" solution to the problem, just hash to an anchor.

In my situation after an ajax return my error messages were set to display at the top of the iframe but if the user had scrolled down in what is an admittedly long form the submission goes out and the error appears "above the fold". Additionally, assuming the user did scroll way down the top level page was scrolled away from 0,0 and was also hidden.

I added

<a name="ptop"></a>

to the top of my iframe document and

<a name="atop"></a>

to the top of my top level page

then

    $(document).ready(function(){
      $("form").bind("ajax:complete",
        function() {
          location.hash = "#";
          top.location.hash = "#";
          setTimeout('location.hash="#ptop"',150);
          setTimeout('top.location.hash="#atop"',350);
        }
      )
    });

in the iframe.

You have to hash the iframe before the top page or only the iframe will scroll and the top will remain hidden but while it's a tiny bit "jumpy" due to the timeout intervals it works. I imagine tags throughout would allow various "scrollTo" points.


Inspired by Nelson's comment I made this.

Workaround for javascript Same-origin policy with regards to using.ScrollTo( ) on document originating on an external domain.

Very simple workaround for this involves creating a dummy HTML page that hosts the external website within it, then calling .ScrollTo(x,y) on that page once it's loaded. Then the only thing you need to do is have a frame or an iframe bring up this website.

There are a lot of other ways to do it, this is by far the most simplified way to do it.

*note the height must be large to accommodate the scroll bars maximum value.

--home.html

<html>
<head>
<title>Home</title>
</head>

<frameset rows="*,170">
<frame src=body.htm noresize=yes frameborder=0 marginheight=0 marginwidth=0 scrolling="no">
<frame src="weather.htm" noresize=yes frameborder=0 marginheight=0 marginwidth=0 scrolling="no">
</frameset>
</html>

--weather.html

<html>
<head>
<title>Weather</title>
</head>

<body onLoad="window.scrollTo(0,170)">

<iframe id="iframe" src="http://forecast.weather.gov/MapClick.php?CityName=Las+Vegas&state=NV&site=VEF&textField1=36.175&textField2=-115.136&e=0" height=1000 width=100% frameborder=0 marginheight=0 marginwidth=0 scrolling=no>
</iframe>

</body>
</html>

Inspired by Nelson's and Chris' comments, I've found a way to workaround the same origin policy with a div and an iframe:

HTML:

<div id='div_iframe'><iframe id='frame' src='...'></iframe></div>

CSS:

#div_iframe {
  border-style: inset;
  border-color: grey;
  overflow: scroll;
  height: 500px;
  width: 90%
}

#frame {
  width: 100%;
  height: 1000%;   /* 10x the div height to embrace the whole page */
}

Now suppose I want to skip the first 438 (vertical) pixels of the iframe page, by scrolling to that position.

JS solution:

document.getElementById('div_iframe').scrollTop = 438

JQuery solution:

$('#div_iframe').scrollTop(438)

CSS solution:

#frame { margin-top: -438px }

(Each solution alone is enough, and the effect of the CSS one is a little different since you can't scroll up to see the top of the iframed page.)