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)
Related
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.
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.
This is my code:
var myFunction(){
document.addEventListener("deviceready", self.onDeviceReady, false); // scoped event listener
function onDeviceReady() {
// ...
}
}
As far as I see when the event (deviceready) is triggered, the local (to myFunction) callback is run.
However the event listeners is global so another function with the same with global scope may be called as well, once the event is triggered.
How to make not only the callback, but the listener itself locally scoped to a function (I know how to do it for a DOM element but that's different)?
Elements themselves are scoped globally. As soon as you attach something to them, they are scoped that way. Consider the following ::
function myfunc(){
document.getElementById('someId').something = 'test';
}
This will now be accessed everywhere.
I see what you want to get at so you could try several things. Here is something you could try. This will check to see if an event already exists for an element and not let you add another.
var Marvel = {
on : function(element, action, callback){
Marvel.listeners = Marvel.listeners || {};
Marvel.listeners[action] = Marvel.listeners[action] || [];
for(var index in Marvel.listeners[action]){
if(Marvel.listeners[action][index].element == element){
return console.error("A '"+action+"' event is already established for:", element, Marvel.listeners[action][index]), false
}
}
element.addEventListener(action,callback);
Marvel.listeners[action].push({ element: element, callback: callback });
},
off: function(element, action){
if(!Marvel.listeners || !Marvel.listeners[action])
return console.error("off: No '"+action+"' listener has been created. Listeners: ", Marvel.listeners || 'none'), false;
for(var index in Marvel.listeners[action]){
if(Marvel.listeners[action][index].element == element){
element.removeEventListener(action, Marvel.listeners[action][index].callback);
Marvel.listeners[action].splice(index, 1);
return true
}
}
return console.error("A '"+action+"' event has not yet been established for:", element, Marvel.listeners[action]), false;
}
}
Usage:
Marvel.on(document, click, function(e){
console.log(e.target);
});
Marvel.off(document, click);
This sets an event listener to be stored in a separate object and checks to see if it already exists when adding new ones, and additionally allows the capability to have an off function to turn them off.
You can find the full explanation for this on my site in my profile in the Javascript Tracking Events section.
Your code should be like this :
function myFunction() {
document.addEventListener("deviceready", function () {
//...
}, false); // scoped event listener
}
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.
I need to be able to achieve the following (one way or another):
function ShowContent() {}
document.onShowContent = function ()
{
// anything I want to happen....
}
What I'm trying to do is to add a kind of listener to me Advertisement code on the page that will auto refresh the ad slot when a specific function is called. Instead of having that function "ShowContent()" directly refresh the ad code, I want the ad code to refresh if it detects that "ShowContent()" has been called.
Thanks.
Modern javascript libraries make this easy. You can do it "by hand" of course, but here's a quick example with jQuery
First, the listener
$(document).bind( 'ShowContent', function()
{
// anything you want
});
Then the trigger
$(document).trigger( 'ShowContent' );
You could even go this route if you want
function ShowContent()
{
$(document).trigger( 'ShowContent' );
}
Here is a quick sample i threw together
var ev = (function(){
var events = {};
return {
on: function(name, handler){
var listeners = (name in events) ? events[name] : (events[name] = []);
listeners.push(handler);
},
raise: function(name){
var listeners = events[name];
if (listeners) {
var i = listeners.length;
while (i--) {
listeners[i]();
}
}
}
};
})();
// add a listener
ev.on("foo", function(){
alert("bar");
});
If you cannot manually alter the method in question to trigger the event, then you can 'wrap' it.
function methodIHaveNoControlOver(){
....
}
// intercept the call
var originalFn = methodIHaveNoControlOver;
// here we replace the FunctionDeclaration with a FunctionExpression containing a reference to the original FunctionDeclaration
methodIHaveNoControlOver = function(){
originalFn();
ev.raise("foo");
};
But note that this will not work if methodIHaveNoControlOver uses this to reference anything; so that will require more work.