9

I use the following to open new tab (in new process) with some page content,

var p = document.getElementById("myElement"); 
var a = document.createElement('a');
a.setAttribute('href',".../mypage.html");
a.setAttribute('rel',"noreferrer");
a.setAttribute('target',"_blank");
p.appendChild(a);
a.click();

http://news.softpedia.com/news/Force-Google-Chrome-to-Open-Links-in-New-Processes-128962.shtml

This is working and the new tab is open with myPage.html content.

Assume that this is myPage(just for sample...) how should I access it?

<!DOCTYPE html>
<html>
<body>

<h1> Heading</h1>
<p> paragraph.</p>
 <button type="button">Click Me!</button>

</body>
</html>

Now Let's go to the tricky/advanced :) part...

when you use window.open (which I cannot use )this is quite simple since you can use various techniques .

 1. using window object
 2. post message
 https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
 3. cookies 
 4. localStorage

But here I open this new page without the reference which is got with window.open

My question is:

How can I access to this new tab dom if I want to change something

John Jerrby
  • 1,683
  • 7
  • 31
  • 68
  • 1
    Hi, I am +1ing you for searching before posting – Marny Lopez Oct 18 '16 at 20:14
  • @MarnyA.López - Thanks :) – John Jerrby Oct 18 '16 at 20:14
  • I hope you have no problems with same origin policy. 1) can any page be a "parent"? 2) do you need to send messages in both directions? (parent -> child or child -> parent) – fremail Oct 18 '16 at 20:28
  • @fremail - Currently I dont have domain issue...I need from the "child tab" to send message to the "parent tab",if you have idea please provide some example,Thanks! – John Jerrby Oct 18 '16 at 20:36
  • You said you can't use window.open API then said you can't use window at all? How come? Asking to avoid XY... – Dan Def Oct 18 '16 at 21:14
  • If you can't use window (actually that's weird!), you can check localStorage changes in timer (setInterval). It's not an elegant solution.. Why you can't use window? – fremail Oct 18 '16 at 21:23
  • @fremail - in chrome when you use window open and open child tab you see and you debug the child tab the parent tab is freeze, check this post...http://stackoverflow.com/questions/39748078/check-if-pop-up-blocker-is-enbled-when-open-new-tab – John Jerrby Oct 19 '16 at 05:38
  • @DanDef - in chrome when you use window open and open child tab you see and you debug the child tab the parent tab is freeze, check this post...stackoverflow.com/questions/39748078/…,this is not xy :) – John Jerrby Oct 19 '16 at 05:39

4 Answers4

4

Parent page JavaScript:

var lastMessage;
setInterval(function() {
  var message = localStorage.getItem('message-to-parent');
  if (message && message !== lastMessage) {
    lastMessage = message;
    // your code here
    alert('There is a new message for you: ' + message);
  }
}, 100);

Child page JavaScript:

localStorage.setItem('message-to-parent', 'hello, my parent!');

If you have a lot of animations and other huge JS code, I'd suggest to increase the timer interval, or better to solve the issue with window.

fremail
  • 330
  • 4
  • 8
  • Thanks, How does this solution will perform in the browser, i mean from performance or load on it... – John Jerrby Oct 19 '16 at 05:43
  • @JohnJerrby The timer will add a job (callback function) to check the message with a delay in 100ms, but the problem is that this job might run later than in 100ms. Read more about JS timers here http://ejohn.org/blog/how-javascript-timers-work/ If you use 100ms or greater delay and the callback function for the interval is simple (like my code), you may be calm about perfomance. – fremail Oct 19 '16 at 10:32
  • Thanks you ! , Im not sure that I can use this solution since its not reliable...(as the link you posted tell...), do you think there is other solution which I can use? – John Jerrby Oct 19 '16 at 13:47
  • @JohnJerrby Did you try to use this solution? http://stackoverflow.com/a/28230846/3816979 – fremail Oct 19 '16 at 15:26
  • I read this post (I put a link at my question) but there is a window $(window).on('storage', message_receive); , There is a way to bind it to something else?if so this can be great and I can use it... – John Jerrby Oct 19 '16 at 17:40
  • I don't know how to use it without `window` – fremail Oct 19 '16 at 21:22
3

I faced a similar issue and build a small lib to make function calls via localStorage with paramter possible. You can find it here. Service worker are currently not supported by all browsers.

Here is an example how to use it:

//Register a function: 
RegisterLocalStorageFunction("test", function(param){ 
    return param+param; 
});

//Call a function: 
let str = "testing"; 
CallLocalStorageFunction("test",str,function(para){ 
    console.log(para); 
});

In your context:

RegisterLocalStorageFunction("CallAlert", function(param){ 
    alert(param);
    return "Success"; 
});
var p = document.getElementById("myElement");
var a = document.createElement('a');
a.setAttribute('href',".../mypage.html");
a.setAttribute('rel',"noreferrer");
a.setAttribute('target',"_blank");
p.appendChild(a);
a.click();

In your other window:

<!DOCTYPE html>
<html>
<body>
<h1> Heading</h1>
<p> paragraph.</p>
<button type="button" onclick="btnClick()">Click Me!</button>
<script>
    function btnclick(){
        CallLocalStorageFunction("CallAlert","Hello from the other tab",function(para){ 
            console.log("para"); 
        });
}
</script>
</body>
</html>

Both sides must be on the same domain, otherwise they cant access the same localStorage. With my currrent code on github I use setInterval to cycle through the storage. There is a storage event, which is fired to all other tabs and windows, but not to the same tab. I'll rewrite the lib to use the much cleaner approach with the event, but for now this should do the trick.

Update

In the repository you can find communicator2, which is based on the 'storage' event.

Update

Here is a working example hosted. Keep in mind to allow popups.

Astasian
  • 429
  • 4
  • 15
  • Thanks , it will be great if you can give example with my context , if you need additonal info ...Thanks! – John Jerrby Oct 25 '16 at 10:22
  • Thanks :), i try it now and let you know... – John Jerrby Oct 25 '16 at 14:28
  • No Problem, I recommend version 2. If you have any issues just let me know. – Astasian Oct 25 '16 at 14:51
  • Thanks but I cannot use version 2 since you use there window and I dont have the window object since I use a.setAttribute('href',".../mypage.html"); a.setAttribute('rel',"noreferrer"); a.setAttribute('target',"_blank"); but maybe I miss someting ... – John Jerrby Oct 25 '16 at 15:03
  • It's just adding the function to the window. If you load the lib you can access the functions everywhere. It's the same if you would not make the functions in an inner function. You don't need the window object of the other window, it's the object of your current window. With window.xzy = function(){} you make the function available in your whole window, same as xzy(){}. But because the lib is inside an anonymous function I had to attach it manually to the window. – Astasian Oct 25 '16 at 15:07
  • ok i'll try it and let you know:) ,why is the !function in the begining ? – John Jerrby Oct 25 '16 at 15:10
  • !function(){}(); means, that you define a function an then execute it with the following parameters. Another example: !function(str){alert(str);}("hello");. The benefit is, that not all variables are put into the window object, so it prevents conflicts. Therefore I had manually add the functions to the window object – Astasian Oct 25 '16 at 15:29
  • Thanks, I try it out and its not working for me but maybe Im doing something wrong...can you please add the full code with my context . i've only two pages one parent which use the a.tag with blank and no_referr and the second is the child html to open with the heading and the pragrefh,it will be great if you can share you working solution, Thanks a lot!!! – John Jerrby Oct 25 '16 at 15:42
  • Sure. I need to leave for 2 hours then i reconnect and try it. Thank you sir! – John Jerrby Oct 25 '16 at 15:53
  • I added an example.Keep in mind to use a web server to serve these files. If you use none, the storage context will be antoher. I saw that you use ".../mypage.html" with 3 dots. Should be 2 only. And some browsers may block popus – Astasian Oct 25 '16 at 16:20
  • Thanks 1+ for your effort and help :) what do you mean use webserver and diffrent context ? assume I want to change for example from mypage.html which is the "child" the content of the paragraph in the main how can I do it, eventually this is what I need to do... Thanks a lot! – John Jerrby Oct 25 '16 at 19:42
  • You can do it. I provided a example on the same rep on github. I mean with Webserver that you have to run apache or iis to serve these files. If you access them via run local file system it won't work. – Astasian Oct 25 '16 at 19:53
  • Thanks, I was able to run those file with webstorm..., I didnt see the example how to change the paragraph content ? where do you do it in the code? please send me reference. – John Jerrby Oct 25 '16 at 20:01
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/126663/discussion-between-astasian-and-john-jerrby). – Astasian Oct 25 '16 at 20:47
  • Here is a working example:https://astasian.github.io/LocalStorageFunctionCall/ – Astasian Oct 25 '16 at 21:07
  • Thanks you very much! , can you please explain why you are using window in (communicator2.js) and if there is elegant way to avoid it ? use some other not global property ? – John Jerrby Oct 26 '16 at 11:27
  • The elegant way is to capsulate in a function and add the required functions to the window object. – Astasian Oct 26 '16 at 11:30
  • can you please provide some example how ? I think it's bad practise to use window... – John Jerrby Oct 26 '16 at 11:32
  • Its a bad practise to to have everything globally accessable. In communicator1 everything (even the reset function) will be put automatically into the window object. – Astasian Oct 26 '16 at 11:36
  • but in version 2 you still have the window like window.RegisterLocalStorageFunction ,how it can be avoided ? – John Jerrby Oct 26 '16 at 11:38
  • 1
    Yes but since we are having some security issue of using local storage ,im trying to check if I can use the sessionStorage which is better from security aspects ,if you know how to make it work with the session storage please let me know . Thanks a lot! – John Jerrby Oct 27 '16 at 12:22
  • Its not possible with the sessionStorage, because every tab has its own one. What are your concerns ? – Astasian Oct 27 '16 at 12:30
  • We have security expert here which claim about the usage of localStorage...we currently in discussion...1. are you sure 100% that it cannot be done with session storage ? 2. can you please say why are you using line 11& 12 placeholder ,why its needed and why you are using 8000 ms ? – John Jerrby Oct 27 '16 at 12:42
  • Hi again , I did some additonal test which is not working, the scenario is : run the parent twice (without close the previous two pages) now in the new child that open (the second) try to send some value to the parent in the text box, Its not working, any idea way ? – John Jerrby Oct 27 '16 at 19:55
  • This make the browser to stuck ...and when I open the local storage viewer in the console->application-> localstorage you see entry is inserted and deleted without doing anything....not sure how? this make the browser to freeze ... – John Jerrby Oct 27 '16 at 20:00
  • maybe will be simpler to see this also , run the index page twice , now you have 4 tabs opened , click on close this will close both window which is bad. I want that every parent will close his own window... – John Jerrby Oct 27 '16 at 20:08
  • since I need it to prod Im doing lot of testing to see if I really can use it otherwise this is just a POC like which I can use in prod and doesnt help me... – John Jerrby Oct 27 '16 at 20:09
  • I Need somehow that every parent and child window have its own scope(maybe by some indetifier...) – John Jerrby Oct 27 '16 at 20:14
  • Thank you maybe with session storage? I need to leave the office so take your time , lets cont. tomorrow :) have a nice day and thanks for your time and effort – John Jerrby Oct 27 '16 at 20:28
  • HI Again :) I know that this one is hard , but Its a big problem to me to use this line ,a.setAttribute('href', "child.html" + '#' +sessionStorage.getItem('winId')); , there is a way to avoid it somehow? in addition if you open 3 index.html one after other and you try to close the Childs from it only the last index.html is working...any idea how to solve it? – John Jerrby Oct 28 '16 at 05:34
  • It's not working yet. It was just a try with sessionStorage. After the doc it will be wiped out after a reload, so we can't use it. I'm on to it – Astasian Oct 28 '16 at 05:36
  • btw there is a way to do all this logic from the communicator somehow and minimal or at all code in the index and myPage, I know this is not trivial but maybe expert like you can give some good solution – John Jerrby Oct 28 '16 at 05:36
  • Thanks a lot expert, take your time :) , I need better solution then quicker solution .... – John Jerrby Oct 28 '16 at 05:37
  • https://en.m.wikipedia.org/wiki/Minification_(programming). But technically I have answered your question. Please accept it, I will still help you. – Astasian Oct 28 '16 at 05:41
  • What are this link not sure that I got it... – John Jerrby Oct 28 '16 at 05:43
  • Wikipedia entry for Minification – Astasian Oct 28 '16 at 05:44
  • well, I see that but how its related ? – John Jerrby Oct 28 '16 at 05:45
  • Do you have some direction ? – John Jerrby Oct 28 '16 at 05:49
  • Thought you wanted to minimize the file? Your site must be static when you want to put your code into the index etc, otherwise choose just to minify it, then it can be still cached. – Astasian Oct 28 '16 at 05:50
  • Ahh ok sure we have some build that handle it,but this is other topic...this topic I can manage :) – John Jerrby Oct 28 '16 at 05:55
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/126882/discussion-between-john-jerrby-and-astasian). – John Jerrby Oct 28 '16 at 05:58
  • HI Again, yes i'll check it now . – John Jerrby Oct 28 '16 at 07:01
  • I send you a message in the chat : http://chat.stackoverflow.com/rooms/126663/discussion-between-astasian-and-john-jerrby . Please accept the answer – Astasian Oct 31 '16 at 09:07
  • Sure done as promised ! :) Ive some additional minor questions... – John Jerrby Oct 31 '16 at 12:00
  • Sure In few min – John Jerrby Oct 31 '16 at 12:04
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/127041/discussion-between-john-jerrby-and-astasian). – John Jerrby Oct 31 '16 at 12:30
1

You have to attach a DOMNodeInserted-listener before the click event is fired, then you can access this window-object.

// assuming that all inserted alements are links or a-tags
// this code must run before the code that adds the a-element
document.addEventListener("DOMNodeInserted", function (ev) {
      var link = ev.target;
      var oldRef = link.href;
      link.onclick = function(event){
        event.preventDefault();
        var childWindow = window.open(oldRef);
        childWindow.onload = function(){
          console.log('at this point you can interact with this newly opened window-object: ',childWindow);
        };
      };
});

//...
// some other code
//...

var p = document.getElementById("myElement"); 
var a = document.createElement('a');
a.setAttribute('href',".../mypage.html");
a.setAttribute('rel',"noreferrer");
a.setAttribute('target',"_blank");
p.appendChild(a);
a.click();

Hope this helps.

Blauharley
  • 4,186
  • 6
  • 28
  • 47
1

You can use SharedWorker to commuicate between different browsing contexts.

See Can we refer to javascript variables across webpages in a browser session?

You could alternatively use storage event Can the mechanism that loads the worker in Shared Web Workers be modified?

Community
  • 1
  • 1
guest271314
  • 1
  • 15
  • 104
  • 177