differences between onload, onunload, onbeforeunload - javascript

I might be creepy but I am testing something and I kind of don't understand the purpose of there three events...
so here is my testcode:
<div id="timeBU"></div>
<div id="timeL"></div>
<div id="timeUL"></div>
<div id="text"></div>
<script type="text/javascript">
function loading(message, timeId) {
var secs=0;
var interval = setInterval(function() {
document.getElementById(timeId).innerHTML = secs;
secs++;
},1);
document.getElementById("text").innerHTML += "<br>"+message+"<br>";
}
// first way
window.addEventListener("beforeunload", loading("beforeunload", "timeBU"));
window.addEventListener("load", loading("load", "timeL"));
window.addEventListener("unload", loading("unload", "timeUL"));
// second way
// window.onunload = loading("beforeunload", "timeBU");
// window.onload = loading("load", "timeL");
// window.onbeforeunload = loading("unload", "timeUL");
</script>
it desn't matters I use first way or second way, but anyways I posted both...
What I am saying, that output depend on the order of //first way code or //second way code, which listener is added first, that function's message is displayed first... you can try swapping places... but time is all the same (you can increase interval or alert something for better view), that makes me think that all three events behave same...
Note: I've tested this only for chrome
my extra question is:How can I differ whether user just opened my site or reloaded?
if you have some kind of advices about my extra question, I would be grateful...

Because you're calling loading() function, you're not using as a callback:
window.addEventListener("beforeunload", loading("beforeunload", "timeBU"))
That line calls loading() (so your message is printed) and passes its return value (nothing) to addEventListener() as callback. Nothing will be performed when event will be fired.
It's not how I'd suggest to do it but try instead this:
window.addEventListener("beforeunload", function () {
loading("beforeunload", "timeBU")
});

This code worked for me. (tested in firefox & chrome).
The only difference now is that loading(message, timeId) now returns a function which gets called as a callback. Events always require you to pass a Callback (which refers to a function) which gets called as soon as the event is called.
<div id="timeBU"></div>
<div id="timeL"></div>
<div id="timeUL"></div>
<div id="text"></div>
<script type="text/javascript">
function loading(message, timeId) {
return function(){
var secs=0;
var interval = setInterval(function() {
document.getElementById(timeId).innerHTML = secs;
secs++;
},1);
document.getElementById("text").innerHTML += "<br>"+message+"<br>";
}
}
window.addEventListener("beforeunload", loading("beforeunload", "timeBU"));
window.addEventListener("load", loading("load", "timeL"));
window.addEventListener("unload", loading("unload", "timeUL"));
</script>

Related

How do I trigger a javascript function if body is clicked after certain seconds?

I need to trigger a window.open function on the click of body, but only if the click is after few seconds.
EXAMPLE:- if the second click is done immediately, it shouldn't open the window. but after 5 seconds, if the click is made, the window should open.
My code isn't working.
<script>
setInterval(myadFunction,5000);
function myadFunction()
{
$("body").click(function () {
window.open("https://www.google.com");
});
}
</script>
This is a wordpress website., and I entered this code before <body> tag.
Why isn't it working?
You can use a flag to simulate what you want. In this case "canClick" flag will do the job for you.Reset it back to true after your desired timeout.
var canClick = true;
$("body").click(function () {
if (canClick) {
window.open("https://www.google.com");
canClick = false;
setTimeout(() => {
canClick = true
}, 5000);
}
});
Let me know if you face any issue with this snippet.
You could try something like:
<button onclick="timeFunction()">Submit</button>
<script>
function timeFunction() {
setTimeout(function(){ window.open("https://www.google.com"); }, 5000);
}
</script>
It consists of this:
setTimeout(functionname, milliseconds, arg1, arg2, arg3...)
The following are the parameters −
functionname − The function name for the function to be executed.
milliseconds − The number of milliseconds.
arg1, arg2, arg3: These are the arguments passed to the function.
First of all. You should make sure that you are placing the code in the right place. Since it's Wordpress. That bugger really get on my nerves. Try putting it in the active theme.
var click_allowed = 0; //global var (you use const if supported)
setTimeout(function(){ click_allowed = 1; },5000);
jQuery('body').click(function(){
if(click_allowed) window.open("https://www.google.com");
});
jQuery has been used instead of $ for the selectors due to wordpress native jquery limitation.
you can use settimeout(function, millisecond)

Waiting with $(document).ready, $(element).ready, and windows.load all trigger before content is ready

Would you please help me delay execution of my function until the content has loaded? I've streamlined my code to the essentials, bear with my typos:
function Phase1()
{
$(".Hidden").load("hidden.html");
$(window).load(Phase2());
/* I've also tried $(document).ready(Phase2()); */
/* and $(."Hidden").load("hidden.html",Phase2()); */
/* and window.onload... */
}
function Phase2()
{
var Loop;
var Source_Array = document.getElementsByClassName("Random");
for (Loop=0;Loop<Source_Array.length,Loop++)
{ alert(Source_Array[Loop].innerHTML; };
}
The Random class contains several items. On the first pass the alerts are never called (length is 0), on the 2nd iteration it's had time to load everything.
I see no errors in the console when executing.
I have a small and neat solution for your problem, all you need to do is,
Call a setInterval for very short span to check the element is present in DOM or not, if its not your interval will go on, once the element is present, trigger your functions and clear that interval.
code will look like this..
var storeTimeInterval = setInterval(function() {
if (jQuery('.yourClass').length > 0) {
//do your stuff here..... and then clear the interval in next line
clearInterval(storeTimeInterval);
}
}, 100);
The page will load the elements from top to bottom.
If you want your JS code to execute after all elements have loaded, you may try any of the following:
Move your script to the bottom of the page.
<html>
<head></head>
<body>
<!-- Your HTML elements here -->
<script>
// Declaring your functions
function Phase1()
{
$(".Hidden").load("hidden.html");
}
function Phase2()
{
var Loop;
var Source_Array = document.getElementsByClassName("Random");
for (Loop=0;Loop<Source_Array.length,Loop++)
{ alert(Source_Array[Loop].innerHTML; };
}
// Executing your functions in that order.
Phase1();
Phase2();
</script>
</body>
</html>
Bind your functions to document ready using Vanilla JS.
document.addEventListener("DOMContentLoaded", function() {
Phase1();
Phase2();
});
Bind your functions to document using jQuery.
$(document).ready(function() {
Phase1();
Phase2();
});

Ajax call on textarea change, but not on every change

I'm making a kind of note system for my users in Laravel application.
I want this textarea that the user writes their notes on to be saved after the user is done typing, instead of running the ajax call on every change done because that would be a lot of requests.
What is the best way to achieve this?
Should I use some sort of timer here to determine if the user is done writing?
Currently I'm just using the following:
notesTextarea.on('change', function(e) {
$.ajax({ ... });
});
While the other proposed solutions (on blur or on keydown if it's the enter key), would work, I think they're not what you're looking for.
What if the user neither clicks outside the textarea, nor uses enter? I would use a technique called debounce instead. You can read about it for example here: https://davidwalsh.name/javascript-debounce-function or see an example here: https://www.geeksforgeeks.org/debouncing-in-javascript/
The short version is, it only calls a function after an event has stopped firing for a given length of time.
Add the debounce function to your code by either using an NPM package (ex. https://www.npmjs.com/package/debounce) or directly adding the necessary code:
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
Source: https://davidwalsh.name/javascript-debounce-function which has taken it from Underscore.js
Then have a function doing your ajax calls like:
var makeAjaxCall = function(e) {
$.ajax({ ... });
};
Now you can simply add a listener like:
var minTimeoutBetweenCallsInMilliSeconds = 500;
notesTextarea.on('change', debounce(makeAjaxCall, minTimeoutBetweenCallsInMilliSeconds));
Now the makeAjaxCall function would be called only 500ms after the last change event occurred, a.k.a. the user stopped typing.
You can use the onlbur event instead. It happens when the element lost the focus, that could means you are no longer changing its content:
$("#notesTextarea").on('blur', function(e) {
// $.ajax({ ... });
console.log("has finished, content to be saved:" + $(this).val());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>
Notes: <textarea id="notesTextarea"></textarea>
</p>
<p>
Other something: <input type="text">
</p>
One way, you can make the call on pressing the enter key on keydown event:
notesTextarea.on('keydown', function(e) {
if(e.keyCode == 13){
$.ajax({ ... });
}
});
You can also think of blur which will occur when the element loses focus
notesTextarea.on('blur', function(e) {
$.ajax({ ... });
});
If you want to automate this saving you can call to ajax, after N number of characters typed by user each time.
Otherwise, you can call to ajax function on CTRL+S key combination
document.addEventListener('keydown', function(event) {
if (event.ctrlKey && event.key == 's') {
event.preventDefault(); //prevent default file save box open by browser
alert('ajax call goes here!');
}
});
Similar to #Mamun's answer.
Call Ajax on keypress event:
$("textarea").on('keypress', function() {
//$.ajax({ ... });
console.log('request sent!');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>
<textarea id="textarea"></textarea>
</p>

javascript alert firing on document ready even though it's in click event

I've got a simple question, the code below keeps firing the alert when the page loads, but the alert is in a click event so I don't know why. Any ideas?
<script>
$(document).ready(
function () {
var blah = document.getElementById('btnChangeScreenSize');
var blah2 = $('#btnChangeScreenSize');
$('#btnChangeScreenSize').click(alert(1));
}
);
</script>
Thanks,
write it like this:
$(document).ready(
function () {
var blah = document.getElementById('btnChangeScreenSize');
var blah2 = $('#btnChangeScreenSize');
$('#btnChangeScreenSize').click(function() { alert(1) });
}
);
The thing is, when you write: $('#btnChangeScreenSize').click(alert(1)) the function alert() is being called and returns undefined. Then you're setting undefined as a callback function, which doesn't make sense
You have this code:
$('#btnChangeScreenSize').click(alert(1));
That attempts to set alert(1) as the click handler (see the docs), but alert(1) is evaluated immediately. Instead, you need a callback function, like this:
$('#btnChangeScreenSize').click(
function () {
alert(1)
}
);

how to delay call to JS function - animated gif not working in IE

I'm struggling to get an animated gif to run in IE. Works in all other browsers, but in IE it just freezes. I've researched this and looks like a delay using setTimeout might work. Not too sure how I add this to the following function:
<script type="text/javascript">
$(function(){
$('#photo_form').on("submit", function () {
$('#loading').show();
});
});
</script>
The gif is inside a div called 'loading' which is hidden. Would I add the timeout to onClick of the button or within the function itself?
Why does IE make things so difficult!?
Any help with solving this problem would be very helpful.
You mean something like this?
$(function() {
$('#photo_form').on("submit", function () {
setTimeout(function () {
$('#loading').show();
}, 100);
});
});
Try this curde, untested psedo-code:
var startTime;
var thread;
$(function(){
$('#photo_form').on("submit", function () {
$('#loading').show();
startTime = time();
thread = setInterval("showLoadingGif", 1);
});
function showLoadingGif() {
var timeToWait = 5; //change interval as needed
if(timeToWait + startTime <= currentTime) {
//show the gif
clearInterval(thread);
}
}
It's been a long time since I've worked with javascript, so this almost certainly needs adjustment; but the principle is the same: keep calling that function, and let that function decide when to stop being called.
setTimeout() will cause your page to freeze while you wait. setInterval will run your code asyncronously.

Categories

Resources