Why/how does Chrome treat onbeforeunload differently than other browsers? - javascript

Try this in chrome versus firefox/IE:
var cancelPressed = false;
function redirect() {
//window.location = "http://www.google.com";
alert('hi!');
}
window.onbeforeunload = function() {
window.pressedTimer = setInterval("cancelPressed = true; clearInterval(window.pressedTimer);",3000);
window.onbeforeunload = function() {
if (!cancelPressed) {
window.unloadTimer = setTimeout('redirect()',500);
window.onbeforeunload = function() {clearTimeout(window.unloadTimer);};
return "Redirecting..";
} else {
return 'wups';
}
};
return 'first!';
};
In FF/IE, refresh, hit cancel on the first prompt, wait about six seconds, and then try to refresh. The 'wups' will be triggered. However, in Chrome, you can wait as long as you want and cancelPressed will never be set to true.
What do you think?

Which version of Chrome are you using? If I wait long enough, I also get the 'wups' message in Chrome. However, I noticed a subtle difference between Webkit browsers and other browsers. Consider the following code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Javascript test</title>
<script type="text/javascript" language="javascript">
window.onload = function() {
document.getElementById("test").onclick = function() {
var startdate;
var interval = window.setInterval(function() {
// Get the difference (in milliseconds) between the current
// date and the startdate.
var diff = (new Date()).getTime() - startdate.getTime();
alert(diff);
window.clearInterval(interval);
}, 5000);
alert("Hello!");
startdate = new Date();
};
};
</script>
</head>
<body>
<button id="test">Test button</button>
</body>
</html>
In chrome and safari, the second alert will always display a number slightly greater than 5000, while in other browsers, you get a number between 0 and 5000.
So what is happening? With setInterval(), the browser creates a timer that will invoke a javascript method every given interval. Javascript is single threaded, and an alert box will completely block the javascript execution. In chrome and safari, this means that the timer is also paused, while in other browsers the timer continues, but the javascript method invocation is suppressed until the alert box is closed.
What has this to do with your example? It means that in chrome and webkit you always have to wait at least 3000 milliseconds before cancelPressed is set, while in others browser, this will happen somewhere between 0 and 3000 milliseconds.

Related

window.speechSynthesis.speak(msg) not working until button click

The brief page below does not work. Specifically, "window.speechSynthesis.speak(msg)" does not work until the button has been pressed. If the button has been pressed then the "Hello" message works. If it has not then any calls to "window.speechSynthesis.speak(msg)" do not produce any audible output.
Suspecting that it has something to do with initialization of speechSynthesis - some things have been tried below to ensure that it is initialized when "Hello" is called. None have worked. Although it seems like it should have. It seems like it is getting properly initialized only if it is called from the button press.
The setup of the SpeechSynthesisUtterance itself is the same whether called from the button or the timeout. That setup works when called by the button. But nowhere else until it has been called by the button.
What is wrong here?
<!DOCTYPE html>
<html>
<head>
<title>Voice Test 3</title>
</head>
<body>
<div id="header">User Interface Terminal</div>
<input type="text" id="control_box"></input><br>
<button id="startButton" onclick="voicemessage('Button');">start</button><br>
<script>
function voicemessage(ttstext) {
var msg = new SpeechSynthesisUtterance(ttstext);
msg.volume = 1;
msg.rate = 0.7;
msg.pitch = 1.3;
window.speechSynthesis.speak(msg);
document.getElementById('control_box').value = ttstext;
}
window.speechSynthesis.onvoiceschanged = function() {
document.getElementById('control_box').value = "tts voices recognized";
window.setTimeout(function() {
voicemessage("Hello");
}, 5000);
};
window.addEventListener('load', function () {
var voices = window.speechSynthesis.getVoices();
})
</script>
</body>
</html>
This may be due to the browser itself...
Recent updates in some browsers (Firefox and Chrome) have policies to prevent audio from being accessed unless some user interaction triggers it (like a button click)...

Dynamically created anchor doesn't work after setTimeout

Hi I make a Timer with Javascript, it works fine. And when it finish the 5 seconds count the code enable a target for open a web, but when I click its dont working. I try this code outside the timer and its works perfectly. What is the error?
<?php
$windowsOpen .= "window.open('$value', '_blank');";
?>
<script type="text/javascript">
function countDown(secs,elem){
var element = document.getElementById(elem);
element.innerHTML = "Please wait for "+secs+" seconds";
if(secs < 1){
clearTimeout(timer);
element.innerHTML='<p>Click to open webs</p>';
}
secs--;
var timer = setTimeout('countDown('+secs+',"'+elem+'")',1000);
}
</script>
<div id="status"></div>
<script type="text/javascript">countDown(5,"status");</script>
Inline event handlers are essentially eval inside HTML markup - they're bad practice and result in poorly factored, hard-to-manage code. Seriously consider attaching your events with JavaScript, instead: developer.mozilla.org/en/DOM/element.addEventListener
If you absolutely need the window opener to be handled with Javascript instead of the browser's nice native behavior, then define the URL you want people to navigate to upfront, and then attach a listener to the element when it's created:
<?php
$url = 'https://www.google.com';
?>
<script type="text/javascript">
var url = '<?=$url;?>';
var timer;
function countDown(secs,elem){
var element = document.getElementById(elem);
element.innerHTML = "Please wait for "+secs+" seconds";
if(secs < 1){
element.innerHTML='<p>Click to open link</p>';
element.querySelector('a')
.addEventListener('click', () => {
window.open(url);
});
} else {
secs--;
setTimeout(countDown, 1000, secs, elem);
}
}
</script>
<div id="status"></div>
<script type="text/javascript">countDown(5,"status");</script>
You should also avoid using eval in your setTimeout - always write out functions in normal JS, rather than as strings to be parsed into functions.
But it would be much less user-unfriendly if you would let them click the link themselves, using the browser's normal behavior:
element.innerHTML='<p>Click to open link</p>';
element.querySelector('a')
.href = url;

One time page refresh after first page load

I would like to implement a JavaScript code which states this:
if the page is loaded completely, refresh the page immediately, but only once.
I'm stuck at the "only once":
window.onload = function () {window.location.reload()}
this gives a loop without the "only once". jQuery is loaded if this helps.
I'd say use hash, like this:
window.onload = function() {
if(!window.location.hash) {
window.location = window.location + '#loaded';
window.location.reload();
}
}
When I meet this problem, I search to here but most of answers are trying to modify existing url. Here is another answer which works for me using localStorage.
<script type='text/javascript'>
(function()
{
if( window.localStorage )
{
if( !localStorage.getItem('firstLoad') )
{
localStorage['firstLoad'] = true;
window.location.reload();
}
else
localStorage.removeItem('firstLoad');
}
})();
</script>
<script type="text/javascript">
$(document).ready(function(){
//Check if the current URL contains '#'
if(document.URL.indexOf("#")==-1){
// Set the URL to whatever it was plus "#".
url = document.URL+"#";
location = "#";
//Reload the page
location.reload(true);
}
});
</script>
Due to the if condition the page will reload only once.I faced this problem too and when I search ,I found this nice solution.
This works for me fine.
Check this Link it contains a java-script code that you can use to refresh your page only once
http://www.hotscripts.com/forums/javascript/4460-how-do-i-have-page-automatically-refesh-only-once.html
There are more than one way to refresh your page:
solution1:
To refresh a page once each time it opens use:
<head>
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="-1">
</head>
sollution2:
<script language=" JavaScript" >
<!--
function LoadOnce()
{
window.location.reload();
}
//-->
</script>
Then change your to say
<Body onLoad=" LoadOnce()" >
solution3:
response.setIntHeader("Refresh", 1);
But this solution will refresh the page more than one time depend on the time you specifying
I hope that will help you
<script>
function reloadIt() {
if (window.location.href.substr(-2) !== "?r") {
window.location = window.location.href + "?r";
}
}
setTimeout('reloadIt()', 1000)();
</script>
this works perfectly
Finally, I got a solution for reloading page once after two months research.
It works fine on my clientside JS project.
I wrote a function that below reloading page only once.
1) First getting browser domloading time
2) Get current timestamp
3) Browser domloading time + 10 seconds
4) If Browser domloading time + 10 seconds bigger than current now timestamp then page is able to be refreshed via "reloadPage();"
But if it's not bigger than 10 seconds that means page is just reloaded thus It will not be reloaded repeatedly.
5) Therefore if you call "reloadPage();" function in somewhere in your js file page will only be reloaded once.
Hope that helps somebody
// Reload Page Function //
function reloadPage() {
var currentDocumentTimestamp = new Date(performance.timing.domLoading).getTime();
// Current Time //
var now = Date.now();
// Total Process Lenght as Minutes //
var tenSec = 10 * 1000;
// End Time of Process //
var plusTenSec = currentDocumentTimestamp + tenSec;
if (now > plusTenSec) {
location.reload();
}
}
// You can call it in somewhere //
reloadPage();
i put this inside my head tags of the page i want a single reload on:
<?php if(!isset($_GET['mc'])) {
echo '<meta http-equiv="refresh" content= "0;URL=?mc=mobile" />';
} ?>
the value "mc" can be set to whatever you want, but both must match in the 2 lines. and the "=mobile" can be "=anythingyouwant" it just needs a value to stop the refresh.
Use window.localStorage... like this:
var refresh = window.localStorage.getItem('refresh');
console.log(refresh);
if (refresh===null){
window.location.reload();
window.localStorage.setItem('refresh', "1");
}
It works for me.
After </body> tag:
<script type="text/javascript">
if (location.href.indexOf('reload')==-1)
{
location.href=location.href+'?reload';
}
</script>
You can make one verable once = false then reload your page with if else like if once == false reload page an make once true.
You'd need to use either GET or POST information. GET would be simplest. Your JS would check the URL, if a certain param wasn't found, it wouldn't just refresh the page, but rather send the user to a "different" url, which would be the same URL but with the GET parameter in it.
For example:
http://example.com -->will refresh
http://example.com?refresh=no -->won't refresh
If you don't want the messy URL, then I'd include some PHP right at the beginning of the body that echos a hidden value that essentitally says whether the necessary POST param for not refreshing the page was included in the initial page request. Right after that, you'd include some JS to check that value and refresh the page WITH that POST information if necessary.
Try with this
var element = document.getElementById('position');
element.scrollIntoView(true);`
Please try with the code below
var windowWidth = $(window).width();
$(window).resize(function() {
if(windowWidth != $(window).width()){
location.reload();
return;
}
});
Here is another solution with setTimeout, not perfect, but it works:
It requires a parameter in the current url, so just image the current url looks like this:
www.google.com?time=1
The following code make the page reload just once:
// Reload Page Function //
// get the time parameter //
let parameter = new URLSearchParams(window.location.search);
let time = parameter.get("time");
console.log(time)//1
let timeId;
if (time == 1) {
// reload the page after 0 ms //
timeId = setTimeout(() => {
window.location.reload();//
}, 0);
// change the time parameter to 0 //
let currentUrl = new URL(window.location.href);
let param = new URLSearchParams(currentUrl.search);
param.set("time", 0);
// replace the time parameter in url to 0; now it is 0 not 1 //
window.history.replaceState({}, "", `${currentUrl.pathname}?${param}`);
// cancel the setTimeout function after 0 ms //
let currentTime = Date.now();
if (Date.now() - currentTime > 0) {
clearTimeout(timeId);
}
}
The accepted answer uses the least amount of code and is easy to understand. I just provided another solution to this.
Hope this helps others.
React Hook worked for me.
import { useEffect, useState } from 'react';
const [load, setLoad] = useState(false);
window.onload = function pageLoad() {
if (load) {
window.location.reload(true);
setLoad(false);
}
};
nothing work for me perfectly except this, -added to my JavaScript file-:
function LoadOnce() {
if (localStorage.getItem('executed') == 'false') {
window.location.reload()
localStorage.setItem('executed', true)
}
}
setTimeout(function () {
LoadOnce()
}, 100)
and in the previous page I wrote:
localStorage.setItem('executed', false)
I got the Answer from here and modified it.This is the perfect solution for me.
var refresh = window.localStorage.getItem('refresh');
console.log(refresh);
setTimeout(function() {
if (refresh===null){
window.location.reload();
window.localStorage.setItem('refresh', "1");
}
}, 1500); // 1500 milliseconds = 1.5 seconds
setTimeout(function() {
localStorage.removeItem('refresh')
}, 1700); // 1700 milliseconds = 1.7 seconds
var foo = true;
if (foo){
window.location.reload(true);
foo = false;
}
use this
<body onload = "if (location.search.length < 1){window.location.reload()}">
Use rel="external"
like below is the example
<li>Home</li>

Clarifying clearTimeout behavior in IE

I have the following code:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
</head>
<body>
<div id="logger"></div>
<script>
function log(txt) {
document.getElementById('logger').innerHTML += txt + '<br>';
}
var int = 10;
var a= setTimeout(function(){
a = null;
log("A fired!");
clearTimeout(b);
b = null;
}, int);
var b = setTimeout(function(){
b = null;
log("B fired!");
clearTimeout(a);
a = null;
}, int);
</script>
</body>
</html>
Both timeout callbacks should prevent another another one from firing. In Opera, FF and Chrome only first one (that prints ″A fired″) is executed. But when I run the same code in IE6 and IE8, both callbacks are executed. Is that some error in my scriupt or is that one of those bugs that these browsers are full of? Do clearTimeout()/clearInterval() guarantee that callback won't be called after their invocation?
I think what is happening is that:
JavaScript has an event queue.
IE processes the timeouts, and queues two events.
The first timeout event is processed, and clearTimeout is called for B. However the event for B is already queued, so it still gets fired.
the second timeout event is processed, and clearTimeout is called for A.
I suspect that in IE, the event gets queued and calling clearTimeout does not remove the event from the event queue.
It is also possible there is just funkyness in how IE pushes simultaneous timeouts onto the queue... Diagnosing the underlying cause could be acheived by using two different timeouts, using 100% CPU processing loops for x time, and by queuing/slotting in other events (maybe can inject events into queue using window.postMessage() and catch them with window.onMessage()).
I have modified your existing code to demonstrate the problem better. It queues the log items rather than doing them immediately, because calling display() can cause layout or rendering to occur, which can easily introduce other funky interference.
Edit: You can test this using http://jsbin.com/ucukez/2 - if the browser has the fault then you get "in A timeout fired" and "in B timeout fired".
Edit: This was fixed in IE9 - I couldn't reproduce in IE9/IE10/IE11.
The HTML is:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>setTimeout queued test</title>
<script>
function display(txt) {
document.getElementById('logger').innerHTML += txt + '<br>';
}
var log = {
items: [],
push: function(text) {
this.items.push(text);
},
display: function() {
var items = this.items;
this.items = [];
for (var i = 0; i < items.length; i++) {
display(items[i]);
}
}
};
function startTest() {
var ms = 10;
display("startTest()");
log.push('before A setTimeout');
var a = setTimeout(function(){
log.push('in A timeout fired');
display("A fired!");
log.push('in A clear timer B');
clearTimeout(b);
log.push('in A cleared timer B');
}, ms);
log.push('after A setTimeout');
log.push('before B setTimeout');
var b = setTimeout(function(){
log.push('in B timeout fired');
display("B fired!");
log.push('in B clear timer A');
clearTimeout(a);
log.push('in B cleared timer A');
}, ms);
log.push('after B setTimeout');
setTimeout(function(){
display("");
display("Displaying logged items:");
log.display();
},1000);
}
</script>
</head>
<body onload="startTest()">
<div id="logger"></div>
</body>
</html>
You're setting the timeouts to occur at exactly the same time, and since they are both forked processes you get inconsistent results
Your best bet is to first test to see if the timeout is still valid like this:
var int = 10;
var a= setTimeout(function(){
if (!a) return;
a = null;
log("A fired!");
clearTimeout(b);
b = null;
}, int);
var b = setTimeout(function(){
if (!b) return;
b = null;
log("B fired!");
clearTimeout(a);
a = null;
}, int);

How to wait for a Java applet to finish loading on Safari?

This doesn't work in Safari:
<html>
<body>
<applet id="MyApplet" code="MyAppletClass" archive="MyApplet.jar">
<script type="text/javascript">
alert(document.getElementById('MyApplet').myMethod);
</script>
</body>
</html>
myMethod is a public method declared in MyAppletClass.
When I first load the page in Safari, it shows the alert before the applet has finished loading (so the message box displays undefined) . If I refresh the page, the applet has already been loaded and the alert displays function myMethod() { [native code] }, as you'd expect.
Of course, this means that the applet methods are not available until it has loaded, but Safari isn't blocking the JavaScript from running. The same problem happens with <body onLoad>.
What I need is something like <body onAppletLoad="doSomething()">. How do I work around this issue?
PS: I'm not sure if it's relevant, but the JAR is signed.
I use a timer that resets and keeps checking a number of times before it gives up.
<script language="text/javascript" defer>
function performAppletCode(count) {
var applet = document.getElementById('MyApplet');
if (!applet.myMethod && count > 0) {
setTimeout( function() { performAppletCode( --count ); }, 2000 );
}
else if (applet.myMethod) {
// use the applet for something
}
else {
alert( 'applet failed to load' );
}
}
performAppletCode( 10 );
</script>
Note that this assumes that the applet will run in Safari. I've had some instances where an applet required Java 6 that simply hangs Safari even with code similar to the above. I chose to do browser detection on the server and redirect the user to an error page when the browser doesn't support the applet.
Here is a generic function I wrote to do just this:
/* Attempt to load the applet up to "X" times with a delay. If it succeeds, then execute the callback function. */
function WaitForAppletLoad(applet_id, attempts, delay, onSuccessCallback, onFailCallback) {
//Test
var to = typeof (document.getElementById(applet_id));
if (to == "function") {
onSuccessCallback(); //Go do it.
return true;
} else {
if (attempts == 0) {
onFailCallback();
return false;
} else {
//Put it back in the hopper.
setTimeout(function () {
WaitForAppletLoad(applet_id, --attempts, delay, onSuccessCallback, onFailCallback);
}, delay);
}
}
}
Call it like this:
WaitForAppletLoad("fileapplet", 10, 2000, function () {
document.getElementById("fileapplet").getDirectoriesObject("c:/");
}, function () {
alert("Sorry, unable to load the local file browser.");
});
I had a similar problem some time ago and adding MAYSCRIPT to the applet tag solved my problem.
Take a peek at this page:
http://www.htmlcodetutorial.com/applets/_APPLET_MAYSCRIPT.html
Hope it helps!

Categories

Resources