Javascript window location in loop on masterpage - javascript

We have a site with masterpage. There is another page policy.aspx.
User has to accept the policy in order to access the site resources.
Hence we put the foll. code on masterpage. There is a boolean variable (var boolVal).
if(!boolVal)
{
window.location="http://url/policy.aspx";
}
For new users boolVal is always false. So they get redirected to the policy.aspx page. But since this page also inherits the masterpage, it reloads continuously as it executes window.location again and again infinitely.
Can something be done besides stopping the policy.aspx page to inherit the masterpage?

It's hard to know without seeing the rest of your code, but my first instinct would be to change your code to:
if(!boolVal)
{
window.location="http://url/policy.aspx";
boolVal = true;
}

cut your js in 2 parts:
1 part with declaration.
1 part with the loop.
In policy.aspx js try to insert code between the 2 parties to change the value of the varialble boolVal

Well, if JavaScropt is to blame, I bet problem lies in boolVal.
If it's not defined typeof boolVal is 'undefined'... Which is falsy value that you negate.
if(!boolVal) // will always be true if boolVal isn't defined/inherited properly.

Related

Swift - execute Javascript on each page

I have a UIWebView to which I pass a HTML file to load.
The HTML file includes javascript that looks for the existence of a variable.
If it exists, it performs one action, if the variable doesn't exist, the script performs another action.
if(typeof customVar === 'undefined')
//Perform task1
else
// Perform task 2 using customVar
On the native, I use the function stringByEvaluatingJavaScriptFromString to set the variable before the page is loaded.
To do so, I'm setting the code in webViewDidStartLoad (I also tried to place it in shouldStartLoadWithRequest).
func webViewDidStartLoad(webView: UIWebView)
{
let cutVar = "test"
webView.stringByEvaluatingJavaScriptFromString("customVar = '\(cutVar)';")
}
This works well when I load a page for the first time, but only the first time.
After that, it seems that through the webViewDidStartLoad, we re-assign the variable in the current page, and then reload the page itself.
So that means, the page is reloaded without the variable to be set.
Is there a way to say I want to run the javascript bit for the next page to load?
Maybe something like a global variable always accessible?
Thank you.

Changing the value of a variable through user input and re-using it on a different page

First I would like to say that I searched and found plenty of answers and even tried a couple (more than...) but to no avail! The error is probably mine but it is time to turn to SO and ask.
Problem description: I have a variable that I want to change the value through the user input (click on btn). As soon as the user chooses the btn it will navigate to a different page that will use the result of the variable to perform certain actions. My issue is that if I alert on my 1st page I get the value being passed by the btn... But on the second page I only get "undefined"
I think it has to do with variable scope and the fact that (I think it works that way anyway) even a window.var will be deleted/purged in a different window.
Anyway, the code is something like this (on the 1st page/file):
var somAlvo;
$('#omissL').click(function(){
somAlvo = 'l';
window.location.href='index_ProofOfConcept_nivel1.html';
});
And on the "receiving end" I have the following code
<head>
...
<script type="text/javascript" src="testForm_javascript.js"></script>
to "import" the js file with the variable and:
var processo = somAlvo;
alert(processo);
I tried declaring window, not using var inside the function and so on...
This is a proof of Concept for a project in my local University, where I'm working as a research assistant (so, this is not homework ;) )
Thanks for any help/hints...
You are right in that when you navigate to another page, the entire JavaScript runtime is reset and all variables lost.
To preserve a value across page loads you have two options:
Include it as part of a query string when navigating to the new page.
Set a cookie.
You may also want to look into loading the new content through an AJAX call and replacing what is displayed. This way you won't reload the entire page which won't cause the JavaScript runtime to be reset.

How can I clear references to Javascript functions that no longer exist?

I am working on a project that uses AJAX to download HTML, CSS and Javascript in one singe chunk of text then appends it to an element on the page. Here is the code:
_t.stage.empty();
_t.stage.html(DATA);
This works fine.
Here is the problem:
After adding the HTML to the stage, I call this function:
if(initApp != null && typeof(initApp) == "function") initApp();// Checks for initApp(). If exists, executes.
If I load a page that has this function, then load one that does NOT have this function, the function from the first page is executed. Here is some psuedo code to understand the results.
page 1:
This is a page.
<style>...</style>
<script> function initApp(){ alert("hello"); } </script>
When this page is run, an alert box with the text 'hello' is shown.
page 2: (no initApp() function)
This is page 2.
<style>...</style>
When the page is run, an alert box with the text 'hello' is shown.
Please note: These pages are loaded with AJAX and inserted into the HTML of an already loaded page.
It is not easy to tell exactly what you're trying to do, but if what you're trying to do is make it so that some other code that calls initApp() will cause nothing to happen when it calls that, then you can simply redefine the function to a do-nothing function like this:
initApp = function() {}
The most recent definition of a function takes precedence (e.g. replaces any prior definitions).
If your newly loaded code contains an implementation of initApp() that you don't want called the second time the script is loaded, then you're out of luck. You can't stop that. You will need to change the structure of your code so that the dynamically loaded code doesn't execute stuff you don't want to be executed. There are many different ways you could do that. For example, you could have a global boolean that keeps track of whether the init code has been called yet.
var initCalled = false;
function initApp() {
if (!initCalled) {
initCalled = true;
// rest of initialization code here
}
}
initApp(); // will only actually do anything the first time it's called
// even if it is loaded more than once
It appears from the comments that you seem to think that reloading a script tag with different code will somehow make code from the previous script go away. It will not. Once a function is loaded, it stays loaded unless it is redefined to mean something else or unless some code explicitly removed a property from an object. It does not matter how the code was loaded or whether it was in the core page or an external script file.
Javascript functions that no longer exist
This is a bad premise. The functions still exist, which is obvious from the fact that the second AJAX load ended up executing it. The fact that the <script> tags are replaced and no longer in the document doesn't undefine the function. It's like asking why is your TV still broken if the burglar that broke it is no longer there.
There are two basic things you can do:
a) Clear the function explicitly yourself:
if (initApp != null && typeof(initApp) == "function") {
initApp();
delete window.initApp;
}
b) Change the function name to be unique per AJAX page (or namespace the function with the same idea), probably tied to the name of the AJAX page, so you can invoke it in a more specific manner.

Javascript: Performing action once the next page has loaded?

I am currently building a google extension and this is what I'm going for:
Do something on awesome.page1.html then automatically press Next Page. When the new page has loaded, fill in a form's textfield.
My issue is that even though I know how to fill in the textfield, I don't quite know how to tell it to fill it in once page2 has loaded. It keeps trying to do everything on page 1.
This is what I'm trying but it's not working:
function addEffect() {
document.getElementsByClassName("effect1 shine")[0].click();
document.getElementsByClassName("nextPage BigButton")[0].click();
nextStep();
}
function nextStep() {
if(document.getElementsByClassName("myformTextField imageName") != undefined) {
alert('Page 2 is up.');
}
else {
alert('Page 1 is still up.');
setTimeout("nextStep()", 250);
}
}
I'm using an alert just for testing, and I keep getting the "Page 2 is up" even though it is still on page 1. I'm checking if an element, which is only present in page 2, is up. How could I make sure page2 is up?
The major issue you're going to run into is that JavaScript variables--including functions--don't persist from one page to another. Put another way, you can't write a function on one page and have it execute on the page that replaces it.
You could pass a URL variable or set a cookie for data persistence--or store settings on your server--but a straight JavaScript approach won't work.
Of course, there is a little trick that some folks use to load the entire DOM of the next page into a variable (using a variation on an XMLHttpRequest), apply the stored settings to the object in memory, and then replace most of the document body with most of the new DOM, but that's probably far more complicated than you need, and it has to conform to same-domain requirements.
Well, your code here:
document.getElementsByClassName("myformTextField imageName")
returns an empty array when it finds nothing, which is not undefined. Therefor, your first if condition will always be true, regardless if it finds your item or not.
Instead, check the length returned by getElementsByClassName or use querySelector and check for null
if (document.getElementsByClassName("myformTextField imageName").length) { ... }
// Or..
if (document.querySelector('.myformTextField.imageName') !== null) { ... }
The easiest method I chose to go with was content script matches.
What I did was create two separate javascript files in my extension: 1.js and 2.js. When awesome.page1.html loads it will run 1.js and when page2.html loads it will run 2.js.
All I did in my manifest.json file is the following:
"content_scripts":[
{"matches": ["http://awesome.page1.com/*"], "js": ["1.js"]},
{"matches": ["http://page2.com/*"], "js": ["2.js"]}]
you should try to user jquery and the $(document).ready(handler)
this is really a best practice to ensure that the page is loaded before it tries to execute your commands
http://api.jquery.com/ready/

What causes the error "Can't execute code from a freed script"

I thought I'd found the solution a while ago (see my blog):
If you ever get the JavaScript (or should that be JScript) error "Can't execute code from a freed script" - try moving any meta tags in the head so that they're before your script tags.
...but based on one of the most recent blog comments, the fix I suggested may not work for everyone. I thought this would be a good one to open up to the StackOverflow community....
What causes the error "Can't execute code from a freed script" and what are the solutions/workarounds?
You get this error when you call a function that was created in a window or frame that no longer exists.
If you don't know in advance if the window still exists, you can do a try/catch to detect it:
try
{
f();
}
catch(e)
{
if (e.number == -2146823277)
// f is no longer available
...
}
The error is caused when the 'parent' window of script is disposed (ie: closed) but a reference to the script which is still held (such as in another window) is invoked. Even though the 'object' is still alive, the context in which it wants to execute is not.
It's somewhat dirty, but it works for my Windows Sidebar Gadget:
Here is the general idea:
The 'main' window sets up a function which will eval'uate some code, yup, it's that ugly.
Then a 'child' can call this "builder function" (which is /bound to the scope of the main window/) and get back a function which is also bound to the 'main' window. An obvious disadvantage is, of course, that the function being 'rebound' can't closure over the scope it is seemingly defined in... anyway, enough of the gibbering:
This is partially pseudo-code, but I use a variant of it on a Windows Sidebar Gadget (I keep saying this because Sidebar Gadgets run in "unrestricted zone 0", which may -- or may not -- change the scenario greatly.)
// This has to be setup from the main window, not a child/etc!
mainWindow.functionBuilder = function (func, args) {
// trim the name, if any
var funcStr = ("" + func).replace(/^function\s+[^\s(]+\s*\(/, "function (")
try {
var rebuilt
eval("rebuilt = (" + funcStr + ")")
return rebuilt(args)
} catch (e) {
alert("oops! " + e.message)
}
}
// then in the child, as an example
// as stated above, even though function (args) looks like it's
// a closure in the child scope, IT IS NOT. There you go :)
var x = {blerg: 2}
functionInMainWindowContenxt = mainWindow.functionBuilder(function (args) {
// in here args is in the bound scope -- have at the child objects! :-/
function fn (blah) {
return blah * args.blerg
}
return fn
}, x)
x.blerg = 7
functionInMainWindowContext(6) // -> 42 if I did my math right
As a variant, the main window should be able to pass the functionBuilder function to the child window -- as long as the functionBuilder function is defined in the main window context!
I feel like I used too many words. YMMV.
Here's a very specific case in which I've seen this behavior. It is reproducible for me in IE6 and IE7.
From within an iframe:
window.parent.mySpecialHandler = function() { ...work... }
Then, after reloading the iframe with new content, in the window containing the iframe:
window.mySpecialHandler();
This call fails with "Can't execute code from a freed script" because mySpecialHandler was defined in a context (the iframe's original DOM) that no longer exits. (Reloading the iframe destroyed this context.)
You can however safely set "serializeable" values (primitives, object graphs that don't reference functions directly) in the parent window. If you really need a separate window (in my case, an iframe) to specify some work to a remote window, you can pass the work as a String and "eval" it in the receiver. Be careful with this, it generally doesn't make for a clean or secure implementation.
If you are trying to access the JS object, the easiest way is to create a copy:
var objectCopy = JSON.parse(JSON.stringify(object));
Hope it'll help.
This error can occur in MSIE when a child window tries to communicate with a parent window which is no longer open.
(Not exactly the most helpful error message text in the world.)
Beginning in IE9 we began receiving this error when calling .getTime() on a Date object stored in an Array within another Object. The solution was to make sure it was a Date before calling Date methods:
Fail: rowTime = wl.rowData[a][12].getTime()
Pass: rowTime = new Date(wl.rowData[a][12]).getTime()
I ran into this problem when inside of a child frame I added a reference type to the top level window and attempted to access it after the child window reloaded
i.e.
// set the value on first load
window.top.timestamp = new Date();
// after frame reloads, try to access the value
if(window.top.timestamp) // <--- Raises exception
...
I was able to resolve the issue by using only primitive types
// set the value on first load
window.top.timestamp = Number(new Date());
This isn't really an answer, but more an example of where this precisely happens.
We have frame A and frame B (this wasn't my idea, but I have to live with it). Frame A never changes, Frame B changes constantly. We cannot apply code changes directly into frame A, so (per the vendor's instructions) we can only run JavaScript in frame B - the exact frame that keeps changing.
We have a piece of JavaScript that needs to run every 5 seconds, so the JavaScript in frame B create a new script tag and inserts into into the head section of frame B. The setInterval exists in this new scripts (the one injected), as well as the function to invoke. Even though the injected JavaScript is technically loaded by frame A (since it now contains the script tag), once frame B changes, the function is no longer accessible by the setInterval.
I got this error in IE9 within a page that eventually opens an iFrame. As long as the iFrame wasn't open, I could use localStorage. Once the iFrame was opened and closed, I wasn't able to use the localStorage anymore because of this error. To fix it, I had to add this code to in the Javascript that was inside the iFrame and also using the localStorage.
if (window.parent) {
localStorage = window.parent.localStorage;
}
got this error in DHTMLX while opening a dialogue & parent id or current window id not found
$(document).ready(function () {
if (parent.dxWindowMngr == undefined) return;
DhtmlxJS.GetCurrentWindow('wnManageConDlg').show();
});
Just make sure you are sending correct curr/parent window id while opening a dialogue
On update of iframe's src i am getting that error.
Got that error by accessing an event(click in my case) of an element in the main window like this (calling the main/outmost window directly):
top.$("#settings").on("click",function(){
$("#settings_modal").modal("show");
});
I just changed it like this and it works fine (calling the parent of the parent of the iframe window):
$('#settings', window.parent.parent.document).on("click",function(){
$("#settings_modal").modal("show");
});
My iframe containing the modal is also inside another iframe.
The explanations are very relevant in the previous answers. Just trying to provide my scenario. Hope this can help others.
we were using:
<script> window.document.writeln(table) </script>
, and calling other functions in the script on onchange events but writeln completely overrides the HTML in IE where as it is having different behavior in chrome.
we changed it to:
<script> window.document.body.innerHTML = table;</script>
Thus retained the script which fixed the issue.

Categories