8

I open a new blank tab. Now from this tab I need to open a website in a new tab. I do this as following. In its console I write:

var wild = window.open("https://css-tricks.com/", "mywin", '');

That works fine. Now I have the access of this new window with wild.document. Now I wish to execute some code on that page after its dom will have been loaded. I use the onload event as:

function foo(){
    var mytext = wild.document.body.textContent;
    alert( mytext );
}
wild.addEventListener("load", foo);

But unfortunately the alert doesn't happen. I also tried putting the event listener in anonymous self calling function as explained in this answer, but that didn't work too. I also tried ondomload event but unfortunately that didn't work too. So,

Why doesn't onload event work on a tab opend with window.open? And How to get it working properly?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
user31782
  • 7,087
  • 14
  • 68
  • 143
  • 2
    Most likely due to the [same origin policy](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy). If you're loading an external site, you can't run events on it. – Mitya Jul 29 '16 at 11:28
  • @Utkanos If instead of `onload` function I use `setTimeout` function with 5sec delay then it works perfectly. So I guess it's not because of same origin policy. – user31782 Jul 29 '16 at 11:31
  • did you try wild.onload = foo; or wild.addEventListener("load", foo, true); ? – Olivier Boissé Jul 29 '16 at 11:34
  • @oliv37 Tried both. But none worked. – user31782 Jul 29 '16 at 11:44
  • I changed the new window url from google.com to something else to make things simpler. – user31782 Aug 09 '16 at 11:01

5 Answers5

6

As described in Detecting the onload event of a window opened with window.open the following demo works fine:

var wild;

window.addEventListener('DOMContentLoaded', function(e) {
  wild = window.open("myLocalStaticPage.html", "mywin", '');
  wild[wild.addEventListener ? 'addEventListener' : 'attachEvent'](
    (wild.attachEvent ? 'on' : '') + 'load', function (e) {
      alert("loaded")
    }, false);
});

// the following handler only used for test purposes
document.addEventListener('click', function(e) {
  try {
    alert(wild);
  } catch(err) {
    alert(err);
  }
}, false);

I added a listener on the source page so that you can test the value of the wild variable simply clicking on the page.

For a static page there is no problem.

But, if you need to open the classic "http://google.com/" page you will see, clicking on the starting page the following errors:

enter image description here

and, from the debugging environment:

enter image description here

What does they mean? When you open the google page, google redirects by itself and this is out of your control.

Why does this happen? To avoid scraping..... just for instance and more.

Is it possible to add such a listener (load)? Yes, but the only way I know is creating a chrome extension, or FF extension or IE..... because the extension api (javascript) offers you the possibility to do this with no pain.

If you are interested in Chrome api you may take a look to manifest and more in detail to a section called "content_scripts" like:

"content_scripts": [{
"matches":    ["*://*/*"],
"js":         ["content.js"],
"run_at": "document_end",
"all_frames": true

}],

where the "run_at" parameter:

Controls when the files in js are injected. Can be "document_start", "document_end", or "document_idle". Defaults to "document_idle".

Community
  • 1
  • 1
gaetanoM
  • 41,594
  • 6
  • 42
  • 61
  • I added your code in the console. It opens new page but it doesn't show alert on `load` event. – user31782 Aug 04 '16 at 13:08
  • @user31782 Which url did you use? If it is "http://google.com/" this is exactly the content of my answer. – gaetanoM Aug 04 '16 at 13:17
  • @user31782 I created the following fiddle, you can try it: https://jsfiddle.net/5ueurpzg/ in order to see the block error message. – gaetanoM Aug 04 '16 at 13:22
  • Your jsfiddle only opens https://google.com/ it doesn't show any block error message. – user31782 Aug 06 '16 at 05:35
  • Not only with google.com. The `onload` event doesn't work for any static page website. – user31782 Aug 09 '16 at 09:47
  • You are right if the static page is almost empty. The onload event is fired only one time and if the page is loaded too fast you are right. But, for sites like Google.... The reason is well described in the answer. Let me know. – gaetanoM Aug 09 '16 at 10:51
  • So, there is no way to add onload event on web pages opened with window.open? – user31782 Aug 09 '16 at 10:59
  • Yes, you can add the onload event but the page cannot work like Google or similar. If you create a simple page and use my snippet the event if fired correctly. I tested it on windows 10 with chrome, ff and ie. The only problem I see is: What are you trying to do? If you refer to Google search page you cannot, this is my answer. Let me know. – gaetanoM Aug 09 '16 at 11:17
  • I tested again your snippet now on localhost. I understand google redirects itself, so it doesn't work on that. Even on simpler site there comes cross origin error. But the cross origin error can be by passed by opening a new blank tab(no _origin_.) with `window.opn` then appending script to that new tab. But still `onload` doesn't seem to work in console of new tab. – user31782 Aug 23 '16 at 11:15
  • 1
    @user31782 You cannot avoid the CORS. It is a security issue. I'm sorry, but, time after time, the CORS policy has been improved drastically and there is no way to escape. So, " But the cross origin error can be by passed by opening a new blank tab(no origin.) with window.opn" is wrong. The only way I know is to create a plugin, but this is another story.... Bye – gaetanoM Aug 23 '16 at 12:37
  • Ok, bye. ``````````````````````````````````````````````````````````````````````` – user31782 Aug 23 '16 at 12:41
  • No, because I can escape CORS by using scripts in console. And I want to know why dom ready doesn't work there. May be dom ready works only for the current tab? – user31782 Aug 23 '16 at 12:46
  • @user31782 It's up to you. I explained correctly the problem. If it's hard to understand, I may only apologize for this. So, good luck and I hope you will learn what is CORS. – gaetanoM Aug 23 '16 at 12:48
  • @user31782 "May be dom ready works only for the current tab?" YES. – gaetanoM Aug 23 '16 at 12:51
  • So If I have `wild = window.open("myLocalStaticPage.html", "mywin", '');` then `wild.document.addEventListener("DOMContentLoaded", function(){ alert("never pops up")});` is meaningless because dom ready works only for the current tab? – user31782 Aug 23 '16 at 12:57
  • The alert pops up in the original window, not the new window... how do I attach a script to run in the new window? – Mark Mar 06 '20 at 19:18
  • nice one! it works fine on IE11 that was giving me problems to have this event working... I replaced setTimeout() that was really ugly! thank you Gaetà! – 100ferhas Apr 19 '21 at 13:42
1

You're loading an external site, so you should be getting a cross-origin frame error (I did when I tested your code in the Chrome console).When I test it in Firefox, the window object is null. In Safari, the object is undefined.

Even with setTimeout the objects are null or the error is thrown, so if you say it worked using setTimeout I would share that code. You aren't allowed to access the document of another window unless the origin is identical (so the same page). At least that is my understanding.

I would have one script on the first page that opens the other window:

<body>
 <script type="text/javascript">
   window.open('http://www.linktoyourotherpage.com/', 'mywin', '');
 </script>
</body>

And a script for the other page that manipulates the document

<body onload="foo()">
  <script type="text/javascript">
    function foo() {
      var mytext = document.body.textContent;
      alert( mytext );
    }
  </script>
</body>
kag359six
  • 1,693
  • 2
  • 16
  • 21
  • I do not get a cross origin error because I always open a blank new tab which has no host. As you suggest to attach `onload` event on the `body` of the other page. How can I attach this event on body before the `dom` has actually loaded? – user31782 Aug 01 '16 at 09:55
  • Do it exactly the way I explained above – kag359six Aug 02 '16 at 14:08
  • How do I add the script tag for the other page? – user31782 Aug 03 '16 at 12:41
  • Well, you wouldn't be able to add the script tag to google.com. You could add the first snippet to one of your pages and the other snippet to another one of your pages. I assumed opening Google was some sort of test for something you are doing with your own site. – kag359six Aug 04 '16 at 13:35
  • I do not have any site. I just test the code in console of a blank new tab. – user31782 Aug 06 '16 at 05:36
0

Please try this,

function foo() {
    var wild = window.open("http://google.com/", "mywin", '');
    wild.addEventListener("load", function(){
        var mytext = wild.document.body.textContent;
        alert( mytext );        
    });
}
Lumi Lu
  • 3,289
  • 1
  • 11
  • 21
  • I tried this but the onload event is never executed. – user31782 Aug 01 '16 at 09:50
  • I'm having the same problem. I do: window.open (window.top.location, '_blank'); which is served from my own local server. The onload() happens when is Refresh/Reload the page the so th eonload handler is there. But it does not trigger when I programmatically do the above. So it's a GOOD QUESTION, why not, how to make it trigger – Panu Logic Jun 26 '19 at 18:15
0

window.onload event fires when every document loaded.

var wild=null;

      function load() {
            if(wild !=null)
            {
               alert("load event detected!  :"+wild.location.hostname+wild.location.pathname);
             }
             else
               alert("not yet loaded");
          }
      window.onload = load;

      wild = window.open("https://www.google.co.in/", "mywin", ''); // Security Exception raise due to Cross orgin security enabled google.co.in
     // wild = window.open("https://localhost:5555/test.html", "mywin", ''); //This will  work when same origin policy
     console.log("After Loading ...");
tsb
  • 179
  • 1
  • 9
  • URL should be same origin or URL server should allow cross origin. // Security Exception raise due to Cross origin security enabled for https://google.co.in – tsb Aug 09 '16 at 09:52
  • I do not get cross origin error because I use the code in the console of new blank tab. – user31782 Aug 09 '16 at 10:58
0

You wrote: "In its console I write: ....". Does that mean you open it interactively? If so then that window opens. If you then AFTER that add a load-listener to it that will probably do nothing because the DOM has already loaded. Adding an event-handler does not react to events that have already happened.

I struggled with the same problem of wondering why I did not see the onload-event happen when I programmatically open a new tab. What I did differently was log a message on the console. That is a more reliable way of getting information about what is going on. Alert-popups can be prevented for many reasons but console messages should not be.

But I didn't see a message on the console about the new window load-event, even though the window did open properly. It was very confusing and I thought (wrongly) that the load-event simply didn't happen because I saw nothing about it on the console. I thought perhaps because I was loading the same URL in the other tab the content of that was already cached by the browser so it did not have to be "loaded" (from the server) and thus did not cause the onload-event, since it had been already loaded earlier.

But turns out the explanation was simpler. The load-event DID happen, but I did not see a console-message about it because ... I was looking at the console of the OPENER-window/tab! I was NOT looking at the console of the tab that was opened.

Each tab/window has its own debugger (-window). Messages from a tab only show in the console of its own debugger window, not on the consoles of others tabs. You can have multiple debugger-windows open, one per tab. That can get confusing because it is then hard to know which debugger-window belongs to which browser window.

So after opening the same URL in a new tab, I had to focus on that tab and THEN OPEN a NEW debugger-window while looking at that tab. THEN I could see the message about the load-event handler in that new console. It took me some time to figure this out, so hopefully this can help others who wonder why they don't see the onload -event. If the window opens, the event probably does happen, you are just looking at the wrong console.

What caused my confusion? It was probably that we always talk about "THE console". That seems to imply that there is (a single) "the" console. But there can be MULTIPLE consoles, open at the same or different times, showing different messages.

This of course can apply to any other event as well. Just because you don't see a log-entry for it on the console you are looking at, does not necessarily mean it didn't happen.

Panu Logic
  • 2,193
  • 1
  • 17
  • 21