Execute function on each item click, but also once on page load - javascript

I have a page with boxes and I want a function to run on each box click. Additionally, I want the function to run ONCE on page load.
(The idea is that the function "updates the state", and I want to update on each click, but also on page load - to initialize the state, so to speak.)
Normally, I do this like so:
$('.box').click(function() {
// do something
}).first().click();
So I attach the handler to each .box click event, and then I get the first .box element and trigger the click event on it.
This approach works, but it feels kind-of clumsy. How do you tackle this problem?

jQuery has triggerHandler()(docs), which offers a number of advantages that may be desired for your code.
$('.box').click(function() {
// do something
}).triggerHandler('click');
From the docs:
The .triggerHandler() method does not cause the default behavior of an event to occur (such as a form submission).
While .trigger() will operate on all elements matched by the jQuery object, .triggerHandler() only affects the first matched element.
Events created with .triggerHandler() do not bubble up the DOM hierarchy; if they are not handled by the target element directly, they do nothing.
Instead of returning the jQuery object (to allow chaining), .triggerHandler() returns whatever value was returned by the last handler it caused to be executed. If no handlers are triggered, it returns undefined

function hello() {
//Here goes your update function
alert('world');
}
$('.box').click(hello);
hello();

This is how I would probably do it.
(function(){
var foo = function(){
// stuff
}
$('.box').click(foo);
foo();
})();
Calls foo when it initializes and adds it to the click.

Something like this could also work :
$(document).ready(function($) {
$('.box').click(function() {
$(this).val("Value"); //Your function here
});
$('.box').each(function() {
$(this).val("Ready"); //Your function here
});
});
Demo

Related

Using addListener to an element that would be created later

I get an error '.addListener is not a function' upon trying this:
if(document.getElementById("id")){
document.getElementById("id").addListener('click', function(){alert("ok");});
}
This element 'id' comes into picture when the entire document gets loaded, and I am using it in the middle of the documents construction. So, I did this:
window.onload = function(){
if(document.getElementById("id")){
document.getElementById("id").addListener('click', function(){
alert("ok");
});
}
}
The error is gone now, but the element 'id' does nothing upon being clicked.
How to make it clickable?
It sounds like you may be assigning to window.onload more than once. If you do this, only the last callback assigned to it will run. Use addEventListener instead, so that prior assignments to onload do not conflict with later assignments to onload.
You can also listen for DOMContentLoaded instead of load, allowing the listener to be attached faster:
window.addEventListener('DOMContentLoaded', function(){
const elm = document.getElementById("id");
if(!elm){
return;
}
elm.addEventListener('click', function(){
alert("ok");
});
});
Best to never assign to an .on- property unless you're certain it will never be assigned to again (or unless you're certain it should only ever have one listener).
Because the element is added later in the dom, you can not attach a listener this way.
What you should do is to attach a listener on the document that will 'filter' the events, so elements added later on in the dom will still be able to fire your events. Try the code below:
document.addEventListener('click',function(e){
if(e.target && e.target.id== 'id'){
//do something
}
});
Now anytime anything is clicked on the dom, this listener will await for an element with id='id' to execute your code, otherwise it will not do anything. This method is called
"event delegation", look it up for more info!

Is it possible to execute an inline click event function without executing a click event?

Explaining by example:
$(".myCheckboxes").click(function () {
...
});
Inside the click event function I have code that does various things depending on what checkboxes are checked.
I however need to run this code to initialize it first, kindof like this:
$(".myCheckboxes").click(function () {
...
}).click();
It runs the code and it gets initialized, but it also clicks on all my checkboxes making them all invert their value.
Is it possible to execute the inline click event function wihtout executing a click event?
I would very much like to keep the function inline to keep the flow of the code. Also, it's not big enough to have the function outside of the event, but it's not so small as I would like to write the code twice.
triggerHandler triggers only the handler:
$(".myCheckboxes").click(function () {
...
}).each(function(i, checkbox) {
$(checkbox).triggerHandler('click');
}
Note that you need to iterate the checkboxes if you wish to trigger the handler for all of them instead of just the first one:
while .trigger() will operate on all elements matched by the jQuery
object, .triggerHandler() only affects the first matched element.
Use a named function as the handler, bind it and execute it:
$(".myCheckboxes").click(clickHandler);
clickHandler();
You may consider to call the function triggerHandler who seems to do what you need.
$(".myCheckboxes").click(function () {
...
}).triggerHandler('click');
NB: I haven't tested this solution.

Why is this click event automatically triggered in jQuery?

I'm creating a simple app using JS/jQuery as a learning exercise and am running into a problem I've encountered before and can't seem to solve. Why, in the following code, is the second click event triggered automatically rather than when I click $('.tweet li a.username')?
$(function(){
setInterval(update, 3000);
$('.showMore').on('click', function() {
moreIndex += 5;
update();
})
$('.tweet li a.username').on('click', alert('hey!'));
});
alert('hey!') is filler for a function I'm still working out. How should this be organized so that the click event triggers when the link is clicked rather than when the page loads? The $('.showMore') event works properly, even if I change the order.
it is because you are invoking the alert function there instead of passing the callback function reference.
In your case you are invoking the alert() function and pass the value returned by the alert as the click event handler.
$('.tweet li a.username').on('click', function(){
alert('hey!')
});
You need to wrap the alert in a callback function, just like the first example:
$('.tweet li a.username').on('click', function() { alert('hey!') });
The .on method is expecting a JavaScript object in that position, a function in particular, which it can execute later. What is happening in your original code is that the JavaScript engine is looking for a function, but sees some other code there instead -- so it executes the code there (activating the alert) in hopes that a useful object will be returned. (When nothing is returned, the JavaScript engine instead assumes that you want null to be executed on a click event, and happily does so.)

JQuery explanation on document.ready

I have question will the click event or any other event run in document.ready() for the first time?
I mean will it reach after loading DOM elements to the comment without clicking first time? :)
$(document).ready(
$(#foo).click(
function()
{
// "It reached here after DOM is loaded!"
}
)
)
document.ready fires when the DOM is fully loaded, so you would be correct.
The 'click' event, however, will not fire unless the bound element is clicked or the click event is explicitly called using click() or Events/trigger:
$('#foo').click();
$('#foo').trigger("click");
Have you read the manual page for document.ready? See:
http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
No, the function will not be executed.
There are a few errors:
$(document).ready() takes a function as an argument.
'#foo' should also be a string.
$(document).ready(function() {
$('#foo').click(
function()
{
// "It reached here after DOM is loaded!"
}
)
})
If you want the function to be evaluated at least once, after the dom loads. Then probably the easiest way is to name your function.
eg:
$(document).ready(function() {
$('#foo').click(
function myfunction()
{
// "It reached here after DOM is loaded!"
}
);
myfunction();
})
If you need the function to execute in the scope of $('#foo') you can do so with Function.call() method.
eg:
$(document).ready(function() {
$('#foo').click(
function myfunction()
{
// "It reached here after DOM is loaded!"
}
);
myfunction.call($('foo'));
})
That would make it behave more like as it were triggered by a DOM event. I'm sure JQuery has a specific method of triggering an event registered through it's DOM event functions. It would also be an option to use that as it would probably also emulate the Event Object passed to "myfunction".
To generalize the question, JavaScript events are handled by associating an event type (onclick, onkeyup, onfocuse, etc) with a function (or multiple functions). The function is, of course, parsed, but is not evaluated until the associated event occurs. Also, the "function," in this context, is often referred to as an event handler or event callback.

MooTools/JS: bindWithEvent

There's this piece in the codebase I'm working on:
this.element.addEvent('click', this.clickEvent.bindWithEvent(this));
I want to change it so that the click event makes sure the window is loaded first. So I tried:
var t = this;
this.element.addEvent('click', function() {
window.addEvent('load', function() {
t.clickEvent.bindWithEvent(t));
});
});
That doesn't seem to get it to work though. What am I missing?
You're adding a handler to the load event when the user clicks something, _aftertheload` event has already fired. Therefore, nothing happens.
You should probably add the click handler inside of an event handler for the load event. (swap the two addEvent lines)
in mootools you tend to use domready and not load but essentially, doing it as suggested will not work as it lacks the context here:
this.element.addEvent('click', this.clickEvent.bindWithEvent(this));
so you are working within a class here - therefore, make sure you instantiate it on the domready event instead, something like...
window.addEvent("domready", function() {
// whatever you need to do...
var foo = new myClass($("someElement"), {option: value}); // example instantiation
// if the binding is not in the .initialize, then call the right method...
// foo.bindMyEvents();
});
as long as the class instance is within domready, you're fine. if that's not an option, see which method binds the events and call that on the domready instead.

Categories

Resources