I have this function executed in a script
$(document).ready(documentReady);
function documentReady(){
console.log("Ready");
$(".loadMore").on("click",loadMoreClicked(this.id));
}
function loadMoreClicked(elementID){
//do something with elementID
}
However, everytime the document loads up, it executes instantly the loadMoreClicked function - thus giving an error.
It seems that if I just want to assign a function to the click event without it being executed directly, I have to remove any argument.
Why does it happen, and how can I avoid it?
Just remove the parentheses and the argument, this will be available in the callback
$(".loadMore").on("click", loadMoreClicked);
function loadMoreClicked(){
var elementID = this.id;
}
You need to use an anonymous function to make the callback call
$(".loadMore").on("click",function(){ loadMoreClicked(this.id) });
Without this, the function is called immediately on document load causing the direct execution behavior you are observing. It will also assign the return value of the function (undefined in this case) to the click handler which is also undesirable.
$(document).ready(function(){
$('.loadMore').click(function(event) {
var self = $(this);
var element = self.attr('id');
});
});
Another option is to set an anonymous function as handler like this
function documentReady(){
console.log("Ready");
$(".loadMore").on("click",function(){
var element = this.id;
});
}
Its a good practice to delegate .off() before .on() to prevent multiple click event listener added to prevent memory leak. ie.
$(".loadMore").off("click").on("click",loadMoreClicked(this.id));
next, an event.preventDefault() would prevent any default action and intercepted by your function.
$(".loadMore").off("click").on("click", function(e) {
e.preventDefault();
loadMoreClicked(this.id);
});
Hope this helps.
Related
This is another Javascript closure question. I run the following code as soon as the document loads:
var handlers = (function () {
var clickHandler = function() { alert ('click!'); }
return {
clickHandler : clickHandler
}
}());
$('#element').addEventListener('click', handlers.clickHandler);
Then at some later point I want to replace the functionality of the handler and thus do something like:
handlers.clickHandler = function() { alert ('changed handler!'); }
From my understand of Javascript closures the event listener should keep a reference of the clickHandler function, and thus the functionality should change accordingly. Yet, this is not what happens. The event listener triggers the initial function. I have managed to achieve the result I want using eval but this feels like a hack. Is there a legitimate way to do what I want?
$('#element').on('click', /*the solution: */ () => handlers.clickHandler());
You need to resolve the identifier on execution of the handler, not on registration. That can be done by wrapping the call into a function, like i did above ( with an arrow function).
Problem:
I have some selects with options in my HTML code and I have set an on change event handler, to figure out, when a selection will be changed.
The following code shows the jQuery code to get the on change:
$(document).on('change', '.anyHtmlSelect', updateState);
I have an existing Javascript function, that should be used as callback function.
The Javascript function looks like:
function updateState(element)
{
var currentId = element.attr("id");
}
Question:
How can I get the changed select as element?
I have tried the following:
$(document).on('change', '.anyHtmlSelect', updateState($(this));
but it doesn't work.
The first argument that is automatically passed to an event handler is a reference to the event itself, not the element that caused the event. To access the DOM element that triggered the event, use this:
Simply change:
function updateState(element)
{
var currentId = element.attr("id");
}
to:
function updateState(event) {
var currentId = this.attr("id");
}
After some research I have found a solution I would share with you.
In my solution, I created an anonymous function, which calls the updateState function with $(this) as parameter.
$(document).on('change', '.anyHtmlSelect', function () {
updateState($(this));
});
Is there a better solution?
I'm trying to enable some touch controls through a callback function but I'm having trouble accessing the event as well as $(this) in my callback function. Right now the code looks as follows:
$('.img-responsive').each(touchControls);
function touchControls(event) {
event.preventDefault();
var mc = new Hammer(this);
mc.on("doubletap", function() {
console.log($(this));
});
}
Where '.img-responsive' is a class of images on my page.
When it tries to call event.preventDefault, I get an error that event.preventDefault is not a function. I thought the event was automatically passed to the variable called? I know when I did a named callback function with .on, event.preventDefault() worked perfectly fine. I assume it's different when I do it with .each, how do I properly access it?
Now, if I remove the event.preventDefault() line, when it logs $(this), I get a function. I was expecting to get individual elements so I could set touch controls for them, but that clearly didn't work. I tried to bind 'this' by:
$('.img-responsive').each(touchControls).bind(this);
But when I logged $(this), it was still a function and not the element I was expecting.
I'm basically just confused as to how to access $(this) and event within the defined callback function.
.each is not an event handler so its callback function does not accept an event object. The method signature of the each callback function looks like this:
.each( function )
function
Type: Function( Integer index, Element element )
A function to execute for each matched element.
So you won't have an event object to reference but, more importantly, there will be no default event behavior to prevent.
Conversely, on does in fact setup event handlers. Its callback function does take an event as its parameter. You can handle your event management within your event handler code, inside the callback function for .on.
this will refer to your current element as you iterate. But inside your inner callback function there will be a different context (so a different this). Simply store a reference to the element in the outer scope:
function touchControls() {
var $this = $(this);
var mc = new Hammer(this);
mc.on("doubletap", function(e) {
e.preventDefault();
console.log($this);
});
}
You have the event being passed in the wrong function.. You need to pass it into the event listener. The first argument of an each loop is the current index of the iteration.
$('.img-responsive').each(touchControls);
function touchControls(eachIndex) {
var mc = new Hammer(this);
mc.on("doubletap", function(event) {
// move preventDefault here and pass the event
event.preventDefault();
console.log($(this));
});
}
function Hammer(el){
return $(el)
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="img-responsive">img</div>
<div class="img-responsive">img</div>
I have this function:
function showPost(event){
event.preventDefault();
$(this).parent('article').animate({width:'100%'}, 'slow');
}
I am attempting to use it like so:
$('.article-header').click(function(event){showPost(event);});
When I use it in the above manner, the event property is passed just fine, however $(this) doesn't work within the function. If I attempt to include this as a parameter in the .click method, it returns an error claiming this is undefined. I have even gone so far as to set var ths = $(this); to no avail.
Please, what is the proper way to make this function happen?
Just use the function directly:
$('.article-header').click(showPost);
You're loosing this because you're calling the function "naked", with no object receiver. You could do this too (but don't because there's no point here):
$('.article-header').click(function(event) { showPost.call(this, event); });
I was trying the following:
f.addEventListener('submit',(function(frm){
var func = (function(e){somefunction(e,frm);})(e);
})(f),false);
But this is failing. I want to pass the form (f) as a static reference and the dynamic event object to the named function 'somefunction'.
What I have above isnt working, what is the right syntax for passing both?
The issue is that each of the functions is being called right away, with undefined actually being passed to addEventListener().
You'll want to instead return one of the functions without its calling parenthesis so the event can call it later:
f.addEventListener('submit', (function (frm) {
return function (e) {
someFunction(e, frm);
};
})(f), false);
Though, with event bindings, you may not necessarily need the closure, as the <form> will be the context (this) of the function passed:
f.addEventListener('submit', someFunction, false);
function someFunction(e) {
var frm = this;
// ...
}
not saure exactly what you are trying to do but, to looks like you are trying to manually pass in the form via the event handler. Instead save a reference and just refer to it in the handler such as
f.addEventListener('submit',function(){
var func = function(e){
somefunction(e,f);
};
},false);
you shouldn't need the self executing functions unless I am missing your intent here