If I make an AJAX request and want to call all functions that were set up by $(document).ready(). How can I do it? Thank you
$(document).ready();
If that doesn't work, try this:
function startup() {
// All your functions in here.
}
$(document).ready(startup);
And after your AJAX request is finished:
startup();
The easiest way is to use a shared function:
$(document).ready(function() {
setup();
});
$.post('/', {}, function() {
setup();
}, 'json');
But if you're using it to re-assign listeners, you would probably be able to get away with assigning them before they're created, like this:
$(document).ready(function() {
$(document).delegate('.my-button', 'click', function() { });
});
Using this code, all .my-button clicks will be handled by your custom function, regardless of whether the button existed in your DOM upon DOMReady.
Note that:
$(document).ready(function() { ... }); can be minimized to $(function() { ... });
If you're using jQuery 1.7+, prefer .on over .delegate: $(document).on('click', .my-button', function() { });
Prefer narrower context over broader, i.e. $('#close-parent').delegate over $(document).delegate
Instead of triggering document.ready by hand (which would be bad practice IMHO), make a function that's called setup which sets up all listeners etc. and invoke this function when you need to re-apply things etc.
Related
I have put together a small script as part of a larger quiz project and am struggling to understand why the this keyword is being set in the function before it is called. Here is my code:
$(document).ready(function ($) {
function nextCard() {
console.log('yes');
$(this).closest('.card').hide();
$(this).parent().next().show();
}
$("#start").on('click', function (e) {
e.preventDefault();
//First card to appear
nextCard();
});
$("#next").on('click', function (e) {
e.preventDefault();
nextCard();
});
});
Why would 'this' not be set to element #start for instance?
Within nextCard(), this will refer to the window as that's the default scope. Hence your DOM traversal methods most likely are not working as you expect them to.
Assuming you want this within the function to refer to the clicked #start or #next element, you could provide the reference of nextCard() to the event handler methods, like this:
$(function($) {
function nextCard(e) {
e.preventDefault();
console.log('yes');
$(this).closest('.card').hide();
$(this).parent().next().show();
}
$("#start, #next").on('click', nextCard);
});
Why would 'this' not be set to element #start for instance?
Why would it be? It's not that it can sense what you want it to do.
Use Function#call to define what object this should point to during the call. If you don't explicitly define it, this will default to the global object (Window in browsers).
$(document).ready(function ($) {
function nextCard() {
console.log('yes');
$(this).closest('.card').hide();
$(this).parent().next().show();
}
$("#start").on('click', function (e) {
e.preventDefault();
//First card to appear
nextCard.call(this);
});
$("#next").on('click', function (e) {
e.preventDefault();
nextCard.call(this);
});
});
Using someFunction.call(this); will effectively "transfer the current meaning" of this to the called function, or more technically, call someFunction in the context of whatever object this is referencing at the moment.
jQuery does something like the above automatically - it sets this for you to the proper DOM element when it calls event handlers. You can make use of the automatic this handling like #Rory McCrossan's answer shows – or you handle this yourself.
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.
$("#").on("click",function () {
$("#").load('', function () {
$(".").on("click",function(event) {
event.preventDefault();
var data = $(this);
$.ajax({
.........etc
Can we use $.ajax function inside .load in jquery or is there any better way to handle this ?
I'm guessing you are trying to do that because you can't bind the click function on an element that hasn't been created yet. What you should probably be using is event delegation:
$("#id").on("click",function () {
$("#id2").load('');
});
$('#id2').on('click','.class', function() {
//do stuff
});
This will find any click that happens inside of #id2, which already exists, and if it originated from .class, which may or may not exist at the time of binding, will execute the "do stuff" code.
I'm working on some code which uses jQuery Countdown plugin. The plugin allows for a callback function to be passed which will be executed when the countdown hits zero:
{
until: new Date(remaining),
onExpiry: runSomeAction
}
runSomeAction uses $(this) to pick up the timer which hit zero. I'd like to wrap runSomeAction but the only way I know how to do this is to add a paramenter to it, like this:
{
until: new Date(remaining),
onExpiry: function() {
// my logic here...
runSomeAction($(this));
}
}
But now I have to change all $(this) references in runSomeAction to the parameter name.
Is there a way to wrap runSomeAction so that it can continue using $(this) and I don't have to change it?
You can use the call or apply javascript functions to change the this context for a given function. Something like this should work for you:
onExpiry: function() {
// my logic here...
runSomeAction.call($(this));
}
Now within the runSomeAction function, this will equal $(this) from the point the function was called.
I am not exactly clear what you are after. More code would have cleared up my answer.
You should be able to use jQuery's .proxy( function, context ) method.
Depending on what this scope you are after, it would either be
onExpiry: $.proxy(runSomeAction,this)
or
onExpiry: function() { runSomeAction.call(this); }
You could change it to $(this) in the proxy if you want the jQuery object.
I'm trying to get better with JavaScript and learn how to utilize my code in functions and keep everything clean. I'm trying to run a function on page-load...
var setColors = function(){
this.init = function(){
$.getJSON('js/colors.json', function(colors) {
$.each(colors, function(i, colors) {
$('<li>', {
text: colors['color'],
'name' : colors['color'],
'data-hex' : colors['hex'],
'data-var' : colors['var']
}).appendTo('#picker');
})
});
}
}
(This is not a color-picker, just a list of colors)
I want setColors() to be executed as soon as the page starts. I read that an anonymous function runs automatically, but this one isn't, I also tried...
$(function(){
setColors();
});
Below the setColors() function and that isn't working ether (The page is just blank). What am I doing wrong and how do I get my function to run on page load? I'm trying to learn so an explanation would be great.
Anonymous functions are not run immediately, you're thinking of Immediately Invoked Function Expressions which happen to often use an anonymous function.
To fix your code:
a) get rid of the this.init function wrapper within the "object" - you're not using it and this.foo only makes sense if you're using new to instantiate an object:
function setColors() {
return $.getJSON(...);
}
Note that returning the $.getJSON() result allows you to register additional deferred object handlers, register error handlers, etc.
b) call the above function in a document.ready handler (which you must do, since the AJAX callback modifies the DOM).
$(setColors);
NB: the latter is a legal way of calling this handler - jQuery will automatically register any function that you pass this way as a document.ready handler. It's similar to writing:
$(function() { setColors() })
but without the extra (useless) function wrapper.
To have that run once the DOM is initialized, you can put it in a ready listener (jQuery):
$(document).on('ready', function() {
setColors();
});
If you want the function to run automatically as soon as it is encountered in the js, after the } that ends the function, add ();
Something like:
function setColors() {
// Code
}();
setColors doesn't return the next function, or call it at the end. YOu could change it to look like:
var setColors = function(){
this.init = function(){
$.getJSON('js/colors.json', function(colors) {
$.each(colors, function(i, colors) {
$('<li>', {
text: colors['color'],
'name' : colors['color'],
'data-hex' : colors['hex'],
'data-var' : colors['var']
}).appendTo('#picker');
})
});
}
init(); // <--- change
}
Which would do the trick for you. You don't even need to "return it" either since the init function itself doesn't return anything, so you could just call it.