so I just started making a webpage for a change and I want to animate some buttons and so on. So what i want to do is write a function wich takes an object (in this case an ) and declares functions for the hover-event. The function works totaly fine in this (not usefull) version:
function hoverOver() {
$(document).ready(function(){
$("#FormA").hover(function(){
$("#ButtonA").animate({marginLeft:"5px", opacity:"1"}, "fast");
}, function(){
$("#ButtonA").animate({marginLeft:"0px", opacity:"0.5"}, "fast");
});
});
But in order to use the function on multiple Buttons, I want to write it like this:
function hoverOver(source) {
$(document).ready(function(){
source.parent().hover(function(){
source.animate({marginLeft:"5px", opacity:"1"}, "fast");
}, function(){
source.animate({marginLeft:"0px", opacity:"0.5"}, "fast");
});
});
}
// this is how I want to call the function with multiple Buttons
hoverOver($("#ButtonA"));
I also tought that it would work if I pass the source-variable through all the functions like this:
function hoverOver(source) {
$(document).ready(function(source){ // <-- here
source.parent().hover(function(source){ // <-- here
source.animate({marginLeft:"5px", opacity:"1"}, "fast");
}, function(source){ // <-- and here
source.animate({marginLeft:"0px", opacity:"0.5"}, "fast");
});
});
}
// this is how I want to call the function with multiple Buttons
hoverOver($("#ButtonA"));
So where is my problem? I know this way of coding JS is not the best way and specialy with JS, HTML and CSS there are million ways to do it but I realy started like 4 days ago. ;)
Thanks
If you use jQuery you might as well extend its prototype, like this:
$.fn.hoverOver = function(){
this.each(function(){
var $this = $(this);
$this.parent().hover(function(){
$this.animate({marginLeft:"5px", opacity:"1"}, "fast");
}, function(){
$this.animate({marginLeft:"0", opacity:"0.5"}, "fast");
});
});
}
And then bind it to any element like this;
$("#buttonA").hoverOver();
or this:
$(".buttonHover").hoverOver();
Related
I am working on a currently working on a dropdown menu using jQuery. I have run into an issue where the Timeout function is not working at all. The code for it is:
$(document).ready(function() {
$('.has-sub').hover(
function() {
$('ul', this).stop(true, true).slideDown(500);
},
function() {
$('ul', this).stop(true, true).slideUp(400);
},
function() {
setTimeout(function() {
$('.has-sub').addClass("tap");
}, 2000);
},
function() {
$(this).removeClass("tap");
clearTimeout();
}
);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
What I trying to do is to create a hover delay for parent of the Dropdown. You would need to hover over the parent for 2 seconds for the Dropdown menu to appear. I also want to pair that with a Slidedown and Slideup effect.
The Slidedown and Slideup functions correctly but the Timeout does not work.
You can't just call clearTimeout() (which is not part of JQuery, by the way), you must provide it with an identifier for the timer you want to cancel.
Also, setTimeout() and clearTimeout() are not part of JQuery or JavaScript for that matter. They are methods of the window object, which is supplied by the browser. They are not part of the language (JavaScript) or the library (JQuery).
Additionally, the JQuery .hover() method takes 2 arguments and you are providing 4. I have combined them below, but not knowing exactly what you are trying to do, you may need to adjust that.
$(document).ready(function() {
// This will represent the unique ID of the timer
// It must be declared in a scope that is accessible
// to any code that will use it
var timerID = null;
$('.has-sub').hover(
function() {
// Clear any previously running timers, so
// we dont' wind up with multiples. If there aren't
// any, this code will do noting.
clearTimeout(timerID);
$('ul', this).stop(true, true).slideDown(500);
// Set the ID variable to the integer ID returned
// by setTimeout()
timerID = setTimeout(function() {
$('.has-sub').addClass("tap");
}, 2000);
},
function() {
$('ul', this).stop(true, true).slideUp(400);
$(this).removeClass("tap");
// Clear the particular timer based on its ID
clearTimeout(timerID);
}
);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
I'm working on a jQuery plugin. To separate my logic I do something like this:
$element.on({
mouseenter: function(){
//do something special
}, mouseleave: function(){
//do something else special
}
});
//more stuffs
and then above this I do that again but with other function body
$element.on({
mouseenter: function(){
//do something not special
}, mouseleave: function(){
//do something else not special
}
});
How does jQuery deal with this ? Will 2nd declaration of mouse events function override the first one ? Sometimes I see both things works but sometimes not.
Will 2nd declaration of mouse events function override the first one ?
No.
How does jQuery deal with this ?
It executes your event handlers in the order in which they were attached. From the documentation (about 40% down the page):
Event handlers bound to an element are called in the same order that they were bound.
So for instance, if you have:
var div = $("#someDiv");
div.on("click", function() { console.log("one"); });
div.on("click", function() { console.log("two"); });
div.on("click", function() { console.log("three"); });
...then clicking the div will give you
one
two
three
...in the console.
Note that it doesn't matter how you found the element to attach the handlers. Let's say you have only one div on the page, it has the id "someDiv", and it's the first child of body (just to make the selectors easy). If you have:
$("#someDiv").on("click", function() { console.log("one"); });
$(document.body).children().first().on("click", function() { console.log("two"); });
$("div").on("click", function() { console.log("three"); });
and you click the div, you'll get
one
two
three
...in the console.
Quick Description:
I'm aware that using $(this) in a function won't work because it's not within the right scope. I've also seen other similar questions. I just still can't figure out how to fix my scenerio.
Goal: I'm trying to build a panoramic photo viewer with jQuery. I have it working, but I need multiple instances. So I need to target only the one I'm hovering on.
Code:
jsFiddle: http://jsfiddle.net/kthornbloom/5J3rh/
Simplified Code:
var hoverInterval;
function doStuff() {
/* The next line is the one in question */
$(this).animate({
/* stuff happening */
});
}
$(function() {
$('.pan-wrap').hover(
function() {
/* stuff happening */
hoverInterval = setInterval(doStuff, 250);
},
function() {
clearInterval(hoverInterval);
});
});
You have scope issues, this in the doStuff is window context.
Use proxy()
hoverInterval = setInterval($.proxy(doStuff,this), 250);
You can explicitly pass this into doStuff:
setInterval(function() {
doStuff(this);
}, 250);
And in doStuff you can do:
function doStuff(element) {
...
}
Or you can explicitly set the value of this for doStuff like so:
setInterval(function() {
doStuff.call(this);
}, 250);
Then you can still use $(this) inside doStuff without changing any of its arguments. For more information on call, see Function.prototype.call and its friend Function.prototype.apply.
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
first post here at this great website!
I would like to reduce the amount of code for the following, espacially as there are more parts I need to add in the future - I'm sure there must be an easy way but I'm just not seeing it. Thanks for your help!
$(document).ready(function(){
$(function(){
$('#iqdrive').click(
function(){
$('#iqdrive-cont').show();
});
});
$(function(){
$('#optiwave').click(
function(){
$('#optiwave-cont').show();
});
});
$(function(){
$('#vario').click(
function(){
$('#vario-cont').show();
});
});
$(function(){
$('#autostain').click(
function(){
$('#autostain-cont').show();
});
});
$(function(){
$('#autoload').click(
function(){
$('#autoload-cont').show();
});
});
});
Firstly, you don't need to nest document.ready functions (all the $(function() { are redundant as it is equivalent to document.ready). And to simplify your code:
$(function() {
$('#iqdrive, #optiwave, #vario, #autostain, #autoload').click(function() {
$('#' + this.id + '-cont').show();
});
});
All of the internal $(function()) calls are unnecessary, since $(function()) is an alias for $(document).ready(function()). Your example shows a lot of repetition of the same sort of task; that's very easy to consolidate.
$(document).ready(function(){
$('#iqdrive, #optiwave, #vario, #autostain, #autoload').click(function(){
$($(this).attr("id") + "-cont").show();
});
});
What that does is register for clicks on elements with any of those IDs, and on click, gets the ID of the clicked element, appends -cont, and uses that as a selector to get a set of elements to show.