If I run this code, why doesn't the page ever finish loading? It will always show connecting on my browser tab.
It is a simple javascript which will prompt an alert box and change the entire document to the word testing.
Javascript - testQuery.js
(function (window, undefined) {
var testQuery = function(obj) {
if (!(this instanceof testQuery)) {
return new testQuery(obj);
}
}
testQuery.alertMessage = function () {
alert("alert");
document.write("testing");
};
window.testQuery = testQuery;
}) (window);
HTML - testQuery.html
<html>
<head>
<script src="testQuery.js"></script>
<script>
function onClick() {
testQuery.alertMessage();
}
</script>
</head>
Because you didn't close the document.
document.close()
Related
I am trying to detect the window close event that I opened using window.open() in javascript. But for some reason, it doesn't seem to work.
Here is my code:
<html>
<head>
<script>
var clicktest = function() {
var newwindow = window.open("https://www.google.com",'myPopupwindow', "height=640,width=960,toolbar=no,menubar=no,scrollbars=no,location=no,status=no");
newwindow.addEventListener("beforeunload", function (e) {
console.log('hey');
});
}
</script>
</head>
<body>
<button onclick="clicktest()">hey</button>
</body>
</html>
I also tried using
newwindow.onbeforeunload = function () {
console.log('hey');
}
instead of window.addeventlistener(), but both didn't work and I did try using window instead of newwindow, still, it didn't work.
For cross-origin documents, the only solution is to poll the .closed property of the popup Window object.
But that is a very ugly thing to do, so please have a second though about why you need that.
To limit the ugliness, you can power your polling using battery friendly requestAnimationFrame:
const popup = window.open('https://google.com');
waitForClose(popup, e=>console.log('closed'));
function waitForClose(win, cb) {
function poll() {
if(win.closed) {
cb();
}
else {
requestAnimationFrame(poll);
}
}
poll();
}
As a fiddle since StackSnippet's iframes don't allow popups.
There are three accessible pages, http://localhost/parent.html, http://localhost/child1.html and http://localhost/child2.php.
Only parent.html is editable for me, whereas the others are not.
child2.php is accessible only through a POST request from child1.html.
What I want to do is to automate extracting data from every child page.
I'm on parent.html now and will access the other two pages from here using a child window.
However, the code which waits for loading the second page doesn't work.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>parent.html</title>
<script>
function waitForLoading(targetWindow) {
return new Promise((resolve, reject) => {
targetWindow.addEventListener("load", resolve);
});
}
document.addEventListener("DOMContentLoaded", async () => {
const childWindow = open("child1.html", "_blank");
await waitForLoading(childWindow);
// do something with DOM
childWindow.document.querySelector("form[action='child2.php']").submit();
await waitForLoading(childWindow); // getting stuck here
// do something with DOM // so, this line is unreachable
});
</script>
</head>
<body>
<h1>parent.html</h1>
</body>
</html>
My questions are:
Why does the code get stuck?
How do I wait for a child window to load the second page?
If it is impossible, do you know any workarounds to achieve the goal?
Thanks.
Why does the code get stuck?
Even if a child window loads another page, it seems not to run load or DOMContentLoaded for the second time or later.
How do I wait for a child window to load the second page?
Loop and watch the loading state of the page.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>parent.html</title>
<script>
function waitFirstPage(targetWindow) {
return new Promise((resolve, reject) => {
targetWindow.addEventListener("load", resolve);
});
}
function movePage(targetWindow, action) {
const originalDocument = targetWindow.document;
action();
return new Promise((resolve, reject) => {
(function loop() {
if (targetWindow.document !== null
&& targetWindow.document !== originalDocument
&& targetWindow.document.readyState === "complete") {
resolve();
}
setTimeout(loop, 100);
})();
});
}
document.addEventListener("DOMContentLoaded", async () => {
const childWindow = open("child1.html", "_blank");
await waitFirstPage(childWindow);
// do something with DOM
await movePage(childWindow, () => {
childWindow.document.querySelector("form[action='child2.html']").submit();
});
// do something with DOM
});
</script>
</head>
<body>
<h1>parent.html</h1>
</body>
</html>
If it is impossible, do you know any workarounds to achieve the goal?
No need for workarounds since it is possible.
I'm working on some code where if a user clicks on a particular button, that person is NOT presented with an exit popup upon exiting the page. The way I'm doing it is by setting a flag whenever the user clicks on the button. However, my code isn't working as expected: The popup loads whether or not the button is clicked. I don't understand why.
Edit: Help!
<!doctype html>
<html>
<head>
<title>Test!</title>
<script>
var bool = false;
var config = new Object();
config.surveyID = 3155031;
config.takeSurveyURL = 'http://www.supporterfeedback.org/a/TakeSurvey';
config.windowPositionLeft = 200;
config.windowPositionTop = 300;
config.home = 'http://www.surveyanalytics.com/';
config.isRightToLeft = false;
config.showFooter = true;
// document.getElementById("btn").onclick = function()
// {
// bool = true;
// };
function flag() {
bool = true;
}
if (!bool) {
window.onbeforeunload = function () {
QP_popupMain();
};
}
</script>
<script language="javascript"
src="http://www.surveyanalytics.com//javascript/exitSurveyInvitation.js"
type="text/javascript"></script>
<noscript>
Start Survey
</noscript>
</head>
<body>
<a href="http://google.com"><img id="btn" onclick="flag()"
src="http://kelowna.directrouter.com/~jeasprco/wp-content/uploads/2012/05/PanicButton2.png"/></a>
<p>Hello, this is a test!</p>
</body>
</html>
I think window.onbeforeunload = function () is operating as soon as the page loads, so what is inside if(!bool) is executing on the button press.
Try changing these two lines:
// var bool = false;
var bool;
// if (!bool) {
if (bool == false) {
You're testing the flag once, when you assign the .beforeunload handler when the page is loaded. Calling flag() doesn't re-execute that code. You need to test it when the function is called.
window.onbeforeunload = function() {
if (!bool) {
return "You haven't clicked the button, do you really want to leave?"
}
}
I have the below code is working as long as I load the employee section and its scripts as part of the index.html
index.html Working Demo
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<link rel="stylesheet" href="style.css" />
<script data-require="jquery" data-semver="2.1.3" src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
<script src="script.js"></script>
</head>
<body>
<h1>Employee Details loaded as usual and sript is executing able to see alert</h1>
</body>
</html>
Script.js
var empModule = (function (empModule) {
var Years = null;
$(document).ready(function () {
var empdata = { Name: 'Billa' }
var myVM = new empModule.viewModel(empdata);
});
empModule.viewModel = function (data) {
var that = this;
that.Name = data.Name;
alert(that.Name);
};
return {
empModule: empModule
}
} (empModule || {}));
Error Scenario:
We decide to move employee related section based on some condition. Hence we are loading this section and section related script(emp.js) via Ajax. But now it is throwing the error empModule.viewModel is not a constructor. Why is it so?
If I move the document.ready section at the bottom like the below order, it is working
Emp.js(moved from script.js to emp.js and load via ajax(
var empModule = (function (empModule) {
var Years = null;
// Code not working when we load this script file using Ajax.
// But works if we move this document.ready at bottom
//$(document).ready(function () {
// var empdata = { Name: 'Billa' }
// var myVM = new empModule.viewModel(empdata);
//});
empModule.viewModel = function (data) {
var that = this;
that.Name = data.Name;
alert(that.Name);
};
//Working only if I keep the ready section here
$(document).ready(function () {
var empdata = { Name: 'Billa' }
var myVM = new empModule.viewModel(empdata);
});
return {
empModule: empModule
}
} (empModule || {}));
The function empModule will get executed automatically as it is self
executing function. When it is executing it needs to prepare a
empModule.viewModel object, but failed to do that when viewModel
definition is located after document.ready (caller). This happens only
when I load this script via Ajax, but works if I pre load it in a page
This is because in the first example the script.js is part of the document and therefore the document.ready waits for that .js file to be loaded before trying to call empModule.viewModel().
In the second example, your script is loaded asyncronously, but the page is not taking this into account. So the page loads (without the script.js) and then you load the script.
At this point, the document is ready (as the ajax loaded script isn't part of the document) so the empModule.viewModel() call fires straight away, before the rest of the script (which is the bit that defines the function) and you get your error.
Just like #dougajmcdonald said is your issue, but your solution is, instead of loadding by AJAX, just insert the script tag in your document:
// Instead of $.ajax(... /myScript.js) use:
function loadMyScript(){
var script = document.createElement("script");
script.type = "text/javascript";
script.src = 'myScript.js';
script.onload = function() {
empModule.doSomething(); // or callback
};
}
I'm trying to use a simple string stored in the localStorage functionality built into phonegap as a simple setting to deicide witch set of data to fetch from a server. In the index.html I've been able to save a string from a <select> menu and display it in the header. Using this javascript code:
<script type="text/javascript" charset="utf-8">
window.onload = function() {
document.getElementById("BtnStore").addEventListener("click", storeData, false);
$("#headertitle").append(loadData()).headertitle("refresh");
}
function storeData() {
var e = document.getElementById("klass");
var klass = e.options[e.selectedIndex].value;
localStorage.setItem("klass", klass);
window.location.href = "index.html";
}
function loadData() {
var getKlass = localStorage.getItem("klass");
return getKlass;
}
</script>
This appends the stored value in an <h1> element.
But when I from a different html page try to reference the same key from the localstore, nothing is being displayed. Here is that code:
<script type="text/javascript" charset="utf-8">
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
$("#hejsan").append(loadData()).hejsan("refresh");
};
function loadData() {
var getKlass = localStorage.getItem("klass");
return getKlass;
}
</script>
This is also just as a test, appending the string to a <p> element. For some reason nothing is happening, someone knows why?
Thanks
I figured out how to make it work, here is the code i used:
First page:
<script type="text/javascript" charset="utf-8">
window.onload = function() {
document.getElementById("BtnStore").addEventListener("click", storeData, false);
$("#headertitle").html(loadData()).headertitle;
}
function storeData() {
//localStorage.clear();
var e = document.getElementById("klass");
var klass = e.options[e.selectedIndex].value;
localStorage.setItem("klass", klass);
window.location.href = "index.html";
}
function loadData() {
var getKlass = localStorage.getItem("klass");
return getKlass;
}
</script>
Second page:
$(document).ready(function() {
function loadData() {
var getKlass = localStorage.getItem("klass");
$("#hejsan").html(getKlass).hejsan;
}
loadData();
}
If anyone else gets stuck! :)