6

Why does the following JavaScript script open a new window, but fails to scroll down the page? (Note that I ran this script in the Web Console in Firefox 4.)

w=window.open("http://stackoverflow.com");w.scrollTo(0,150);

How can I open a page in a new browser window and instruct that window to scroll to a specific position?

Derek Mahar
  • 25,458
  • 37
  • 115
  • 164

6 Answers6

7

I found something interesting on this...

I've always known you can scroll to an anchor with a name -- in fact, that's the way we were all taught. But I just tried to scroll to a div with an id and it worked!

So, for example, if the target page has a div with id="bobo" then the link http://www.example.com/index.php/home#bobo just worked for me.

Perhaps it's flaky behavior on my end. I feel like I would have heard of this before if it were possible. But all I know is I was trying to do the same thing and for whatever reason it's working.

FWIW, the link I'm using is http://www.religionnews.com/index.php?/rnsblog#blog

user624385
  • 323
  • 1
  • 6
  • 13
2

If you own both domains, you can use window.postMessage to communicate the scroll position to the other window.
In one page you make the postMessage, and in the other you add an event listener.

If you need to support older browsers, you can use window.name to transfer some data between windows.

If you don't own both domains, you're out of luck, due to the SOP. It is a built-in protection in browsers to avoid cross domain abuses.

Mic
  • 23,536
  • 8
  • 55
  • 69
  • Does a script that runs outside the context of a window fall under the same security restriction? For example, the Session Manager extension for Firefox can open a page in a new tab and scroll to an arbitrary position in that page. – Derek Mahar May 18 '11 at 20:38
  • 1
    I don't think browser extensions are under a domain, you install them locally and that's it. – Mic May 18 '11 at 21:05
1

You're trying to scroll before the window is ready. Notice that the following works:

w=window.open("http://stackoverflow.com");
setTimeout(function() { w.scrollTo(0,150) }, 1000);

It would be best to execute the scroll in a w.onload or DOM ready function, but I can't seem to get that to work.

mVChr
  • 46,510
  • 10
  • 101
  • 99
  • 1
    This did not work for me, either. Nor does it work if instead of setting the timeout, I simply wait a few seconds before invoking `w.scrollTo()`. The browser complains, "Error: Permission denied to access property 'scrollTo'". – Derek Mahar May 18 '11 at 19:34
  • Interesting, it works for me in Chrome. I'll do some more testing in FF. – mVChr May 18 '11 at 19:49
  • Though the article is over six years old, http://www.leftontheweb.com/message/ErroruncaughtexceptionPermissiondeniedtogetproperty may explain why this does not work. How can I bypass this cross-domain security for a harmless operation like scrolling? – Derek Mahar May 18 '11 at 19:52
  • Here is another reference to an error due to cross-domain security: http://www.webdeveloper.com/forum/showthread.php?t=189515. – Derek Mahar May 18 '11 at 19:58
1

The script does not work because it breaches cross-domain security. See this and this. Chrome reports a similar error:

> w=window.open("http://stackoverflow.com");
DOMWindow
84Unsafe JavaScript attempt to access frame with URL http://stackoverflow.com/ from frame with URL chrome://newtab/. Domains, protocols and ports must match.
> w.scrollTo(0,150);
89Unsafe JavaScript attempt to access frame with URL http://stackoverflow.com/ from frame with URL chrome://newtab/. Domains, protocols and ports must match.
TypeError: Object [object DOMWindow] has no method 'scrollTo'
Derek Mahar
  • 25,458
  • 37
  • 115
  • 164
0

Originally answered here, there's a hack where if the page supports iframe embedding, you can open a document that embeds the page and then scrolls the document rather than the embedded page. The issue is that we can't get the height of the page, so instead we just hijack the scrolling event to make the document taller once we approach the bottom:

data:text/html,<html><body style="margin:0; padding:0;"><iframe id='i' src='http://forecast.weather.gov/MapClick.php?CityName=Las+Vegas&state=NV&site=VEF&textField1=36.175&textField2=-115.136&e=0' width=100% frameborder=0 margin=0 scrolling=no style="height: calc(100vh + 170px + 200px);"></iframe></body><script>window.scrollTo(0, 170);window.onscroll = function(e) {if((window.innerHeight + window.scrollY) >= document.body.offsetHeight - 200) {document.getElementById('i').style.height = window.innerHeight + window.scrollY + 200;}};</script></html>
CTurt
  • 1
-1

Derek is correct about the cross-domain security preventing you from doing this. So one answer is to disable the domain security by loading chrome: Chrome --disable-web-security This from THIS chrome instance, run your javascript. The child windows will inherit the load switch and your scrollTo will now work.

Rick
  • 1
  • Translated: "Load Chrome with web-security turned off." First, the OP said he was running in Firefox. Second, he's not asking how to do it to test - he's asking how to do it to use on a client-facing website (assumption); what if the client doesn't have Chrome, and better yet, why on earth would it be a good idea to launch Chrome on a client-computer with web-security disabled? Also, is it even possible to, from javascript, launch an instance of Chrome (with or even without that flag set)? – newfurniturey Oct 29 '12 at 02:13