Cannot define global object in new tab when reused (window.open) - javascript

I'm trying to open a new tab and define an object in its global context (CORS safe), and then reuse the new tab (e.g. refresh) and declare the object in the global context again.
Is there a way to consistently modify the new tab's global variables when the tab is reused?
The first time I run the code below (i.e. opened as a NEW tab) it works as expected and window.something is defined in the child tab context.
// In parent/main tab.
const newTab = window.open('https://same-domain-url.com', 'knownString');
newTab.something = { dev: true };
If I call the same action again, the child tab is refreshed as expected (browser tab reused due to the target value - MDN reference) but this time window.something is not defined in the child context.
I've determined it's not a race-condition problem because I placed a console.log(window.something) within a setInterval in the child page JS (at DOMContentLoaded event).
I tested the code in Chrome 109.0.5414.87 and Firefox 107.0.1 (64-bit). Exact same behavior in both.
Edit: Posting some code as example:
Page 1 (main page # localhost:8080/page-1):
<button id="button">Open Tab</button>
(function () {
document.addEventListener("DOMContentLoaded", (_) => {
document.getElementById("button").addEventListener("click", (_) => {
let newTab = window.open(
"localhost:8080/page-2",
"page2"
);
newTab.something = { dev: true };
});
});
})();
Page 2 (child page / new tab # localhost:8080/page-2):
document.addEventListener('DOMContentLoaded', function() {
setInterval(() => {
console.log('>>>>>>', JSON.stringify(window.something));
}, 1000);
});
Click on Page 1 button and child tab is created. In child tab's Console you'll see the object correctly.
Switch back to the Page 1 tab without closing the child tab. Click on the Page 1 button again. The child tab is refreshed but this time the Console shows the object as undefined.

Related

Custom Javascript Variable Returns Different Value on History Change

I have setup a Custom JavaScript variable that works intermittently. The function is simply designed to return true or false if a text is contained on the page.
The below code works fine when the page is loaded directly from the URL bar and when executed in the developer tools console. When running the function in the console, the function indeed turns true. When the code is executed within debug mode in GTM, the value returns false when a history change event occurs.
function() {
var content = document.body.innerText;
var query = "text to search";
if (content.search(query) > -1 ) {
return true;
} else {
return false;
}
}
Any assistance/insight is very much appreciated!
To me this seems like expected behavior. Since you are talking about history changes, you are probably working with a single page application, or some other page where the DOM is changed after the initial page load.
Custom Javscript variables evaluate a function and return the result each time you reference it. How I imagine the flow of operations goes is this.
Page Loads (target text is in the page body) -> Custom JS evaluates on page view and returns true -> User presses some button -> DOM is modified to display new content (target text is removed and no longer present -> History change occurs -> Custom JS evaluates again, the text is no longer present so returns false.
If the target text is still present after the history change, then I can understand why we have some unexpected behavior. The history change trigger is based off of the push state api so what could be happening is that the pushState() function is called before the DOM is finished being modified. In this case, the text isn't present at time of the history change event even though it is shortly afterwards.
You could change the page so pushState() is only called after the DOM is done being modified, use a custom event as a trigger instead (again, pushing it after the DOM is done being modified), or use a different trigger like the element visibility trigger that will only fire after the new DOM elements you want to target appear on-screen.

Window.document not updated

I open a new tab in the browser with const w = window.open('www.example.com'); and I get the DOM with let d = w.document; Then I go to another webpage with an click-event: d.querySelector('a').click(); The new webpage opens, in the same window, and I want to grap the DOM of the just openend page by running d = w.document again. And this is the point where I get stuck.
I aspect the DOM of the currently openend window, but instead I get the DOM of the previous window back. When console.log(w) (in the .js itself not in the console), with the new webpage open, I get the window object of the current page and the window.document matches the DOM of the openend page. But as I said in reality I get the DOM of the previous page back when I run d = w.document on the new page.
The following code is the whole function I use. Sidenote: I didn't(/couldn't) use window.document.onload fom I reason I don't understand, but It seems I can't attach an function to the window onload event. Also to make things clear my code is inside of a ES6 Class so I didn't use the constas in the example.
The Problem:
When I run the getDOM method on the new openend webpage it returns the DOM of the previous page.
async foo() {
await this.getDOM()
.then(w => this.d = w.document);
const x = this.d.querySelector('button.x');
console.log(send); //null
}
getDOM () {
return new Promise(resolve => {
const interval = setInterval(() => {
if (this.w.document.readyState === 'complete') {
clearInterval(interval);
resolve(this.w);
}
}, 500);
});
}
I hope someone can help, thanks in advance!

How to refresh the parent page on closing the rad window

I have a opened a rad window using below java-script code given below. Now I want to refresh my parent page on closing the rad window. To achieve this i have linked a jquery method, OnSendInviteClose with onclose event. Now this code refreshes my parent page but some time it gives me error described as "can't execute code from a freed script". How to fix this issue or reload my parent page on close (any other way).
Thanks
var e_showaddresslist = function (sender, args) {
var url = $page.url.create("Pages/CalendarInvites.aspx?parentScreen=sendInviteWnd");
var win = $window.createPopup(url,
{
size: "750, 500", behaviors: Telerik.Web.UI.WindowBehaviors.Close | Telerik.Web.UI.WindowBehaviors.Maximize | Telerik.Web.UI.WindowBehaviors.Move | Telerik.Web.UI.WindowBehaviors.Reload | Telerik.Web.UI.WindowBehaviors.Modal, name: "sendInviteWnd", onclose: onSendInviteClose
},
function () {
//$page.get_window().set_destroyOnClose(true);
});
}
function onSendInviteClose() {
window.location.reload(true);
}
Note: All the code is place in the calendar.js file which has references in both parent and radwindow page.
Have a read of this What causes the error "Can't execute code from a freed script"
The try / catch solution may help in your case.
You can hook the OnClientColose to the RadWindow and refresh the page using document.location.reload().
function RefreshParentPage()//function in parent page
{
document.location.reload();
}
Thanks,
Saritha
Make sure the code is executed in the correct context, i.e., in the main page and not in the CalendarInvites page.
Then, if this is ok, try adding a timeout like this:
function onSendInviteClose() {
setTimeout(function() {
window.location.reload(true);
}, 0); //you can also try increasing the timeout.
}
Usually, the cannot execute code from freed script means that the content page that is being disposed is still trying to run some code but it is orphaned (e.g., other pieces of code it depends on are disposed, or its context is gone - the window object). Most often this would be the page in the iframe (i.e., inside the RadWindow), but it may also be your main page.
Attached the 'onSendInviteClose' method on close event.
var win = $window.createPopup(url,
{
size: "750, 500", behaviors: Telerik.Web.UI.WindowBehaviors.Close |Telerik.Web.UI.WindowBehaviors.Move, onclose: onSendInviteClose
}
Now create that method in the page from which the popup is opened. This function will automatically fired when popup window is closed.
function onSendInviteClose() {
//get a reference to the current RadWindow
var wndow = GetRadWindow();
wndow .Close();
// and as this method is present in parent page
// we can refresh the page controls easily.
}
function GetRadWindow() {
var oWindow = null;
if (window.radWindow) oWindow = window.radWindow;
else if (window.frameElement.radWindow) oWindow = window.frameElement.radWindow;
return oWindow;
}

Does popup exist? (javascript)

I'm trying to determine whether a popup exists in javascript. I do know its name (passed in window.open()), but I do not have a window reference. For example consider this: I have a web page A which calls window.open('url', 'popup') and I have web page B which also wants to call window.open('url', 'popup') unless such popup exists. In this case B just focuses on popup. So web page B has no reference to popup (and it cannot have, we may assume that A and B are independent). Is there a way to do that?
You should be able to do it if you play around with your window structure.
Whenever I've come across this problem I've had a main window which always exists. Then, when calling window.open, I grab the handler that that function returns and then assign it to the main window that I know will always exist.
Then, whenever calling window.open, I go off and check main window to see if it has an open window handler for the popup window.
So, assuming you have that main window that always exists (you could always use have a window that uses a frame to display your actual content so, to your users, it'll look the same), you could do something like:
var mainWindow = window;
while(mainWindow != mainWindow.parent){
mainWindow = mainWindow.parent;
}
if(mainWindow.PopupWindow === undefined || mainWindow.PopupWindow.closed){
var handler = window.open('url', 'popup');
mainWindow.PopupWindow = handler;
}
I've always had a few problems using the closed property of the window object, so you may need to map a function to the onunload event within the popup window that just clears out the PopupWindow variable on the mainWindow, and then add that check within your if statement too.

Controlling browser window through Javascript

I have a web app that launches an URL in other windows/tabs. I would like to check if the window/tab exists. If not, I want to create it, else I would like to pick it in the first position.
I use:
wf=window.open(address, web_form_target, 'toolbar=1,scrollbars=1,location=1,statusbar=1,menubar=1,resizable=1,width=640,height=450');
if(wf!=null)
wf.focus();
But it goes well only the first time (in IE, not in Firefox). If I create a new tab in the window, when I call window.open() nothing happens. If I close the window it recreates it but keeps it ionized.
Is there a way I can follow to obtain a good result?
Thanks in advance.
Here's some code I've used for ages that still works as far as I know. Notice that oWindow has global scope, and that I pass it to the second parameter of open as a string, not as the object itself. Then, I test to see if it's closed before trying to open again...if it's already opened, then I just give it focus:
var oWindow;
function openWindow(p_strURL) {
if(!oWindow || oWindow.closed) {
oWindow = window.open(p_strURL, "oWindow", "status, scrollbars, resizable, width=800, height=500");
if(!oWindow.opener) {
oWindow.opener = window;
}
}
else {
oWindow.location.href = p_strURL;
oWindow.focus();
}
}
Hope it helps you find a solution,
Kevin
web_form_target is the window name.
if (wf.name !== web_form_target) {
// create it
}

Categories

Resources