Javascript functions in series - javascript

I am using a function first which adds a class that causes the page to fade to 0 on clicking an anchor tag. How would I add the following...
if style = opacity "0" (in other words function one has successfully completed) add the next function. The code is given below.
They both run independently from there respective triggers but not sure how to ensure that function two runs only on completion of the first.
document.getElementsByTagName("a")[1].addEventListener("click", first);
function first() {
"use strict";
document.getElementById("content").classList.add("animation")
}
function next() {
"use strict";
document.getElementById("profile").classList.add("animation");
}

document.getElementsByTagName("a")[1].addEventListener("click", function(){
document.getElementById("content").add('animation');
next();
});
function next(){
if (document.getElementById("content").contains('animation')) {
document.getElementById("profile").classList.add('animation');
} else {
return false;
}
}

I recommend you to use JQuery, it is much more easier to manipulate css attributes and stuffs. And for pure javascript, I think it was already answered here, it might not be straight answer, but it might help you out.
Use callback functions
function func(value, callback){
//do stuff
callback();
}
In your case
function first(alphavalue, second) {
// do some stuffs
if(alphavalue == 0) {
// run the call back
second();
}else { // do no stuffs }
}
Hope it helps!!

$("#content").on("webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend",
function(event) {
// Do something when the transition ends
next();
});
Check transition end event handling and this.

Related

Execute a local function only once in pure JavaScript?

This seems so easy, but I couldn't find a proper solution yet.
What the JS does: check an element's CSS style immediately and if max-width is 1000px, do something (see JS comment).
And in case the JS is executed before the CSS is applied, check again after the document has finished loading.
But "do something" should only happen once, so if it was done right away, don't do it again via the event listener.
But how to avoid that? It would be easy using a global variable or function, but I want to keep those local.
(function()
{
function checkCSS()
{
if (window.getComputedStyle(element).getPropertyValue('max-width') == '1000px')
{
// do something, but only once!
}
}
checkCSS();
window.addEventListener('load', function() {checkCSS();});
})();
You can remove the handler when you've done the "something," see comments:
(function() {
function checkCSS() {
if (window.getComputedStyle(element).getPropertyValue("max-width") === "1000px") {
// do something, but only once!
// *** Remove the listener
window.removeEventListener("load", checkCSS);
}
}
// *** Add the listener
window.addEventListener("load", checkCSS); // <== Note using the function directly
// *** Do the initial check
checkCSS();
})();
Or only add it if you didn't do "something":
(function() {
function checkCSS() {
if (window.getComputedStyle(element).getPropertyValue("max-width") === "1000px") {
// do something, but only once!
// *** We did it (you could remove the listener here, but it doesn't really matter)
return true;
} else {
// *** Didn't do it
return false;
}
}
// *** Do the initial check
if (!checkCSS()) {
// *** Didn't do it, add the listener
window.addEventListener("load", checkCSS); // <== Note using the function directly
}
})();
To trigger it before "CSS is applied" you can use different event, for example, DOMContentLoaded
window.addEventListener('DOMContentLoaded', checkCSS)

Turbolinks: How to stop running functions when you leave the page?

In my Rails 5.2.2 app I am using Turbolinks.
I have discovered that when I leave a page, the functions that were started continues.
I have organised my functions below a return statement that checks the body class. In my example below, if the body class is not foobar the functions below do not run.
// assets/javascripts/pages/foobar.js
var goLoop;
$(document).on("turbolinks:load", function() {
if (!$("body").hasClass("foobar")) {
return;
}
return goLoop();
});
goLoop = function() {
return setTimeout((function() {
console.log("Hello");
return goLoop();
}), 1000);
};
First time I visit the page, the goLoop function is triggered.
When I follow a link away from the page, the function runs. If I had not used Turbolinks, this would not have happened.
If I follow another link back to the page, the function is triggered again, so now it runs twice.
How can I avoid this, without disabling Turbolinks?
Use the turbolinks:before-cache to teardown your timeout using clearTimeout. You will need to keep a reference of the current timeout ID. So your solution might look like:
var goLoop;
var timeout;
$(document).on("turbolinks:load", function() {
if (!$("body").hasClass("foobar")) {
return;
}
return goLoop();
});
goLoop = function() {
return timeout = setTimeout((function() {
console.log("Hello");
return goLoop();
}), 1000);
};
$(document).on("turbolinks:before-render", function() {
clearTimeout(timeout);
});
You can use PageVisibilityAPI to see is current page active or not.
and for the loop issue, you should check whether it's exist or not then run timeout function.

Javascript While or If statement to run a set interval function with

I need a javascript while look that looks for the condition ":visible" on a DOM object and only runs the code when the DOM object is actually visible.
This is my code so far.
if (("#rightPanel").is(":visible") == true){
// It's visible, run fetch on interval!
setInterval(function() {
updateChatField()
}, 500);
} else {
// Do Nothing!
};
What do I need to adjust to get my desired effect? Right now I'm getting ("#rightPanel").is is not a function.
You forgot the $ sign:
if ($("#rightPanel").is(":visible") == true){
// It's visible, run fetch on interval!
setInterval(function() {
updateChatField()
}, 500);
} else {
// Do Nothing!
};
Actually, if I understood correctly, you need the interval to be constantly running so it detects when the element changes to visible. I'd suggest something like:
var $rightPanel; // cache the element
function checker() {
if ($rightPanel.is(":visible"))
updateChatField();
}
function init() {
$rightPanel = $("rightPanel"); // cache
window.setInterval(checker, 500);
}
Then to start it, just call init() after the page has loaded.

jQuery Window Load not firing when called from within function

Using jQuery the following would log that the app had loaded once the DOM and all assets had been downloaded by the browser:
$(window).load(function() {
console.log('app loaded');
});
However I don't want this check to happen until after some other things have run.
So for example:
function checkLoaded()
{
$(window).load(function() {
console.log('app loaded');
});
}
So let's say I call this function after a bunch of other functions.
The problem is, because $(window).load(function() is an event listener, when I call the checkLoaded() function the event won't ALWAYS run (because it MAY have already been fired because everything has downloaded BEFORE the checkLoaded() function has run).
Any ideas on how I can do this?
I tried this:
function checkLoaded()
{
if(loaded)
{
console.log('app loaded');
}
else
{
checkLoaded(); // keep checking until the loaded becomes true
}
}
$(window).load(function(){
loaded = true;
});
But the problem here is that the checkLoaded function COULD get called hundreds of times in a few seconds and isn't a nice way of handling this.
UPDATE: The function is called using checkLoaded(); Just so everyone knows I am calling the function!
UPDATE 2:
The plan is essentially this:
function init() {
start();
}();
function start() {
// Show Preloader... and other stuff
/// Once all logic has finished call checkLoaded
checkLoaded();
}
function checkLoaded() {
if(loaded) {
show();
}
}
function show() {
... // show app
}
So I should be able to know if the status of loaded is true, but keep checking until it becomes true as it may be true or false when I get to the checking stage.
You run it either on window load or if it's already done using such kind of code:
function onLoad(loading, loaded) {
if (document.readyState === 'complete') {
return loaded();
}
loading();
if (window.addEventListener) {
window.addEventListener('load', loaded, false);
} else if (window.attachEvent) {
window.attachEvent('onload', loaded);
}
}
onLoad(function() {
console.log('I am waiting for the page to be loaded');
}, function() {
console.log('The page is loaded');
});
var loaded=false;
$(window).load(function() {
loaded=true;
});
function checkLoaded()
{
// do something if loaded===true
}
Try this
function checkLoaded()
{
$(window).load(function() {
console.log('app loaded');
});
}
checkLoaded();
you want to make checkLoaded block and thats a bad idea:
javascript has no threads and blocking like that will just burn CPU while potentially blocking the whole script.
don't wait like you do for loaded to be to true. use the eventhandler as it is meant to be used.
maybe give checkLoaded a parameter to a function you want called:
function checkLoaded(continueWhenLoaded) {
$(window).load(function() {
continueWhenLoaded();
});
}
Have you looked into a solution involving jQuery's .promise() and .done()? Look at some of the examples in the documentation, it might be what you are looking for.

Nested change event still happens when disabled

I want the categorycb_change function NOT to be executed when permissioncb_change is in progress, but it does not work.
In the code below I set fireCategoryEvents to false when permissioncb_change is executing, however for some reason this does not prevent category_cb from executing. When I debug I can see that permissioncb_change is done first and only when it is done executing categorycb_change is fired.
(Important note: categorycb_change is triggered within updateGroupCheckboxes within the permissioncb_change function.)
I also tried this with unbinding and rebinding, but the same problem.
What am I doing wrong and or how can I fix this?
.permissioncheckbox and .rolecategory are both html input checkbox elements.
the code behind updateGroupCheckboxes is quite complicated. so I don't think it is useful to show here. (it changes the checkedstate of multiple .rolecategory checkboxes so it triggers the categorycb_change events)
var fireCategoryEvents = true;
$(function () {
$('.permissioncheckbox').change(permissioncb_change, 0);
$('.rolecategory').change(categorycb_change);
});
function permissioncb_change() {
fireCategoryEvents = false;
$(this).attr('data-changed', true);
if (firePermissionEvents) {
updateGroupCheckboxes(this);
}
fireCategoryEvents = true;
}
function categorycb_change() {
if (fireCategoryEvents) {
alert('cat changed');
}
}
I found the solution:
function permissioncb_change() {
$(this).attr('data-changed', true);
if (arguments[0].originalEvent.srcElement.className != 'rolecategory') {
updateGroupCheckboxes(this);
alert('per changed');
}
}
function categorycb_change() {
if (arguments[0].originalEvent.srcElement.className != 'permissioncheckbox') {
alert('cat changed');
}
}
This way I check what the origin of the event was before deciding to run the code.

Categories