With this code I expect to see a 'yo' added to the console every second while I'm hovering over .cell-top. But I get one 'yo' and that's it.
function cellUp(linkObj) {
console.log('yo');
}
$(".cell-top").hover(function() {
setInterval(cellUp($(this)), 1000);
});
Any idea what I can do to get my expected results?
PS. I'm using linkObj to get $(this) in a function within cellDown, I didn't include the function because that's unrelated to the issue I'm having. I did include the linkObj because I figured it may be part of the issue.
Since you're using jQuery, you can use $.proxy.
$(".cell-top").hover(function() {
setInterval($.proxy(cellUp, null, $(this)), 1000);
});
var interval;
function cellUp(linkObj) {
console.log(linkObj);
}
$(".cell-top").hover(function() {
var self = this;
interval = setInterval(function(){cellUp($(self))}, 1000);
},function() {
clearInterval(interval);
});
Related
Wow.. to get real information about 'this' is not easy as google basically ignores the word.
The code opens an image from a database using the information from thumbnail.. the onlick works, and the hover code works, but I can't figure out how to get 'this' from the mouseenter to be used in the showModal function.
function showModal() {
$("body").css("overflow-y", "hidden");
$(".small").removeClass("smallHover");
$(".modal").fadeIn(200);
var altLong = $(this).attr("alt");
var altSplit = altLong.split("#");
$(".picTitle").text(altSplit[0]);
var srclong = $(this).attr("src");
var srcshort = srclong.split("_");
var srcextension = srclong.split(".");
$(".big").attr("src", srcshort[0]+'.'+srcextension[1]);
}
$(".small").click(showModal);
var timer;
$(".small").mouseenter(function() {
timer = setTimeout(function(){
$(this).showModal(); // **<--this is the line that doesnt work**
}, 2000);
}).mouseleave(function() {
clearTimeout(timer);
});
also if you could explain why you would use $(this) as a jquery object instead of just 'this' and how they differ, that would be great. Thanks in advance~!
There are two separate aspects to this.
Getting the right this in the setTimeout callback
Calling showModal with that this
#1 is addressed by this question's answers. You have several options, the simplest in this case (for now) probably being to use a variable:
$(".small").mouseenter(function() {
var _this = this; // ***
timer = setTimeout(function(){
$(_this).showModal(); // ***
}, 2000);
}).mouseleave(function() {
clearTimeout(timer);
});
...but that code still won't work, because showModal isn't a property of jQuery objects, it's a standalone function. To call it with a specific this, you'd use Function.prototype.call:
$(".small").mouseenter(function() {
var _this = this;
timer = setTimeout(function(){
showModal.call(_this); // ***
}, 2000);
}).mouseleave(function() {
clearTimeout(timer);
});
(Alternately, change showModal to accept the element as a parameter and then just pass it as an argument.)
More on this in this question's answers as well, as well as this (old) post on my anemic little blog.
this will also work if you could change your showModel function like this :
$.fn.showModal = function() {
$("body").css("overflow-y", "hidden");
$(".small").removeClass("smallHover");
$(".modal").fadeIn(200);
...
}
and inside timer method
$(this).showModal();
I'm trying to create a jQuery autocomplete for an application:
$("#search-input").on('keyup', function() {
search = $(this).val();
autocomplete_div = $(".autocomplete")
$.get('/ajax/search/', {'search': search,}, function(response){
autocomplete_div.html(response)
});
});
What would I need to add to the above code to add a 400ms delay?
Use
setTimeout(function() {
// your code here
}, 400);
setTimeout is a method provided by the browser's window object.
A more complete example that cancels a timer if already set using clearTimeout would be:
var myTimer = 0;
$("#search-input").on('keydown', function() {
search = $(this).val();
// cancel any previously-set timer
if (myTimer) {
clearTimeout(myTimer);
}
myTimer = setTimeout(function() {
autocomplete_div = $(".autocomplete")
$.get('/ajax/search/', {'search': search,}, function(response){
autocomplete_div.html(response)
});
}, 400);
});
Also note use of on instead of the deprecated live.
Your code should look like this: (for jQuery 1.7+)
$(document).on('keyup', "#search-input", function () {
clearTimeout($(this).data('timeout'));
var _self = this;
$(this).data('timeout', setTimeout(function () {
$.get('/ajax/search/', {
search: _self.value
}, function (response) {
$(".autocomplete").html(response);
});
}, 400));
});
If using older jQuery version, use live() or better delegate(). BTW, you should bind it to closest static container, not document.
You can use the setTimeout() function to delay the start of the expression, in this case, your function. Beware that this does not delay processing beyond this code. It will only delay the start of this function, while continuing to process code after the function.
$("#search-input").live('keydown', setTimeout(function() {
search = $(this).val();
autocomplete_div = $(".autocomplete")
$.get('/ajax/search/', {'search': search,}, function(response){
autocomplete_div.html(response)
})
},400));
EDITED: to correct misplaced parentheses.
Why this code doesn't work?
I wrote This code but:
(function($){
$.fn.newsSlider = function() {
setTimeout(function() {
this.each( function() {
$(this).each(function(){
$(this).append($(this).children(":first-child").clone());
$(this).children(":first-child").remove();
});
});
}, 3000);
}
}(jQuery));
With setInterval:
http://jsfiddle.net/OmidJackson/46UNg/
Without setInterval:
http://jsfiddle.net/OmidJackson/6bKWU/
Your problem is that this has different meaning (the window object) inside the setTimeout function literal. Check this answer for further info about this in different contexts.
The solution is to save a reference to this so you can use it inside the setTimeout.
See this example.
You need to store the this as it currently has a value of window
var $this = this;
setTimeout(function() {
$this.each( function() {
$(this).each(function(){
$(this).append($(this).children(":first-child").clone());
$(this).children(":first-child").remove();
});
});
}, 3000);
I have this line of code, but it doesn't work, and I'm guessing that my function is the cause of the problem here. Here's my JavaScript:
$(document).ready(function () {
var interval;
function move(ele) {
$(ele).animate({
'background-position-y': '0px'
}, 200, function () {
$(ele).animate({
'background-position-y': '3px'
}, 200, function () {
interval = setTimeout(function () {
move(ele)
}, 3);
});
});
};
$(".up").hover(function () {
move(this), function () {
clearTimeout(interval);
interval = null;
$(this).css("background-position", "80px 3px ");
};
});
Can someone explain me what I'm doing wrong here?
Even with the proper closing braces as suggested by David there is still a problem which keeps the animation going. Clearing the timer (interval) doesn't stop the callback functions passed to .animate() from executing. So interval = setTimeout(...) will still get executed and perpetuated the animation cycle.
I reworked the code a bit for a working example, though there could be some improvements (like getting rid of a global variable). http://jsfiddle.net/aKKRk/
err, it looks like your actual problem is that you're only passing one function to hover, not two. You've got ….hover(function() { move(…), function() { … } }) instead of ….hover(function() { move(…); }, function() { … }).
In the future, this kind of error will be much easier to spot if you make a habit of consistently indenting your code.
I've got following JavaScript functions but want to refactor the $(document).ready() as I've got 2 instance of it. How can I achieve this?
FlashMessenger = {
init: function() {
setTimeout(function() {
$(".flash").fadeOut("slow", function () {
$(".flash").remove();
});
}, 5000);
}
}
SelectLanguage = {
init: function() {
$('#selectLanguageId').change(function() {
$('#frmSelectLanguage').submit();
});
}
}
$(document).ready(FlashMessenger.init);
$(document).ready(SelectLanguage.init);
It’s perfectly acceptable to set multiple handlers for $(document).ready, although you may have a good reason to do otherwise that I’m not aware of. You might be interested in knowing that $(handler) can be used as shorthand for $(document).ready(handler):
$(FlashMessenger.init);
$(SelectLanguage.init);
If you really want them in one call though, try this:
$(function() {
FlashMessenger.init();
SelectLanguage.init();
});
First off, there's no reason you have to combine them.
But if you want to:
$(document).ready(function(jq){
FlashMessenger.init(jq);
SelectLanguage.init(jq);
});
Breaking it down:
Create a function to do all your init (it can be named or anonymous; the one above is anonymous).
Have it call the other init functions, passing in the jQuery instance that jQuery passes you just in case they use it.
You might choose to wrap each init call in a try/catch block as well, so that errors in one init don't prevent the next init from occuring, but that depends on your needs.
Just combine them into one call with an anonymous function:
$(document).ready(function()
{
FlashMessenger.init();
SelectLanguage.init();
});
$(document).ready(function() {
FlashMessenger.init();
SelectLanguage.init();
});
Option 1
FlashMessenger = {
init: function() {
setTimeout(function() {
$(".flash").fadeOut("slow", function () {
$(".flash").remove();
});
}, 5000);
}
}
SelectLanguage = {
init: function() {
$('#selectLanguageId').change(function() {
$('#frmSelectLanguage').submit();
});
}
}
$(function(){
FlashMessenger.init();
SelectLanguage.init();
});
Option 2
FlashMessenger = {
init: function() {
setTimeout(function() {
$(".flash").fadeOut("slow", function () {
$(".flash").remove();
});
}, 5000);
}
}
SelectLanguage = {
init: function() {
$('#selectLanguageId').change(function() {
$('#frmSelectLanguage').submit();
});
}
}
$(document).ready(function(){
FlashMessenger.init();
SelectLanguage.init();
});
Option 3
You actually don't need those 2 objects since the only hold the init methods, so here's the ultimate solution, in my opinion, unless you use those objects elsewhere.
$(function(){
$('#selectLanguageId').change(function() {
$('#frmSelectLanguage').submit();
});
setTimeout(function() {
$(".flash").fadeOut("slow", function () {
$(".flash").remove();
});
}, 5000);
})
I prefer 2 and 3 for this reason.
I think what the op is saying is, "If in the future I have a third function to be invoked at document.ready, then how do I do it without touching that piece of code?"
If you do not want multiple $(document).ready() calls, you could just create an array called startupHooks and add each method to it:
startupHooks[ startupHooks.length ] = myNewStartupHook;
and your startup script could look like
$(document).ready(function() {
for( var i=0; i<startupHooks.length; i++ ) {
startupHooks[i]();
}
}
I know that is not mighty useful, but if that appeals to you, you can do it this way.
Personally, I'd go with multiple $(document).ready() calls.
Personally I'd go for not using document.ready at all.
If you place the scripts at the end of your html-page(just before the tag) you can just write in any way you like.
Maybe this doesn't work for 0.01% of the scripts but it never failed to work for me.
Positive effect of this is that the initial HTML+CSS rendering goes faster.
You can also read about it on yahoo. http://developer.yahoo.com/performance/rules.html#js_bottom