My hover events are triggered, if I removed the hovered events, click still does not get triggered. What could be the problem?
items = '<li></li>';//some html content
list.html(items);
list.show().children().
hover(function () {
alert('hover');
}, function () {
alert('gone');
}).
click(function () {
alert('clicked'); //this is never reached when I click a list item.
});
Related
I have simple slider which I open/close on click event.
$('#tab1-slideout span').click(function () {
manageToggleStateTab1();
});
function manageToggleStateTab1() {
if (tab1ToggleState == 'collapsed') {
$('#tab1-content').slideToggle('slow');
$('#tab1-slideout span').addClass('active');
tab1ToggleState = 'expanded';
});
and on page load I set this tab1ToggleState with initial value
var tab1ToggleState = 'collapsed';
this works great but I want to expand this further in order to allow toggling state on click event anywhere outside #tab1-content container div.
I tried to wire click event anywhere on page except the one with toggle content
$(document).not($('#tab1-content')).click(function () {
manageToggleStateTab1();
});
but this not gives me desired result, div immediately slide down after it slide up.
you can use this function
// hide some divs when click on window
function actionwindowclick(e , el , action){
if (!$(el).is(e.target) // if the target of the click isn't the container...
&& $(el).has(e.target).length === 0) // ... nor a descendant of the container
{
action();
}
}
in click event
$(document).click(function (e) {
actionwindowclick(e , '#tab1-content' , function(){
// do action here
});
});
simply this function says if the element is not a target do the action
Working Demo
and while you use $(document).click(... you will need event.stopPropagation()
so for example
$('#tab1-slideout span').click(function (event) {
event.stopPropagation();
manageToggleStateTab1();
});
Working Example
I was trying to execute some alerts with some onclick events and conditions with jquery statement. But it seems that event handlers don't work properly, probably due the fact that is missing something in my event handling logic. I have just 1 button, with id #bottone1, and I have some menu buttons with id #b1 and #b2.
The first event works fine, it adds correctly the class "cliccatoInvoca1_OnReady". When i click on #bottone1 it starts the the first alert "cliccatoInvoca1_OnReady". Also the onClick event $("#b1") works properly, it removes the class "cliccatoInvoca1_OnReady" and replaces with the class "cliccatoInvoca1".
This point i encounter the first problem
When i click on #bottone1 it comes like first alert "cliccatoInvoca1_OnReady", and then "cliccatoInvoca1". Then when i click on #b2 and afer that i click on #bottone1 it executes 3 alerts, "cliccatoInvoca1_OnReady", "cliccatoInvoca1" and finally "cliccatoInvoca3".
So, the main problem is that it doesn't work if condition for execute only 1 alert at time. So when i click on #bottone1 it executes all the alerts in sequence.
This is my document.ready function
$(document).ready(function () {
$("#select-1").multiselect();
invoca1();
$("#bottone1").addClass("cliccatoInvoca1_OnReady btn btn-default");
if ($("#bottone1").hasClass("cliccatoInvoca1_OnReady")) {
$("#bottone1").click(function () {
alert("cliccatoInvoca1_OnReady");
keys = [];
$('input[name="multiselect_select-1"]:checked').each(function () {
keys.push(this.value);
});
});
}
$("#b1").click(function () {
invoca1();
$("#bottone1").removeClass("cliccatoInvoca1_OnReady noClass").addClass("cliccatoInvoca1");
if ($("#bottone1").hasClass("cliccatoInvoca1")) {
$("#bottone1").click(function () {
alert("cliccatoInvoca1");
keys = [];
$('input[name="multiselect_select-1"]:checked').each(function () {
keys.push(this.value);
});
});
}
});
$("#b2").click(function () {
invoca3();
$("#bottone1").removeClass("cliccatoInvoca1").addClass("cliccatoInvoca3");
if ($("#bottone1").hasClass("cliccatoInvoca3")) {
$("#bottone1").click(function () {
alert("cliccatoInvoca3");
keys = [];
$('input[name="multiselect_select-1"]:checked').each(function () {
keys.push(this.value);
});
});
}
});
});
Change to use delegated event handlers, attached to a non-changing ancestor element, each with a matching selector:
e.g. like this:
$(document).on('click', "#bottone1.cliccatoInvoca1_OnReady", function() {
alert("cliccatoInvoca1_OnReady");
keys = [];
$('input[name="multiselect_select-1"]:checked').each(function () {
keys.push(this.value);
});
});
The above is now all you need for one click handler, repeat the pattern for the other classes it can have. You never need the hasClass checks.
Your other code just becomes simple like this:
$("#b1").click(function () {
invoca1();
$("#bottone1").removeClass("cliccatoInvoca1_OnReady noClass").addClass("cliccatoInvoca1");
});
Delegated handlers:
Delegated event handlers work by listening for the event (in this case click) to bubble up to the ancestor element.
You normally choose the closest non-changing ancestor element, but document is the default if nothing else is closer/convenient. Do not use 'body' as it has a bug related to styling that can cause mouse events not to bubble to it.
Then it applies the jQuery selector to only the elements in the bubble-chain.
It then applies the function, only to the matching elements that caused the event.
The result is the elements only need to match at event time and not event registration time.
This pattern will simplify your code significantly.
The entire example will become something like this:
$(document).ready(function () {
$("#select-1").multiselect();
invoca1();
$("#bottone1").addClass("cliccatoInvoca1_OnReady btn btn-default");
$("#b1").click(function () {
invoca1();
$("#bottone1").removeClass("cliccatoInvoca1_OnReady noClass").addClass("cliccatoInvoca1");
});
$("#b2").click(function () {
invoca3();
$("#bottone1").removeClass("cliccatoInvoca1").addClass("cliccatoInvoca3");
});
$(document).on('click', "#bottone1.cliccatoInvoca1", function () {
alert("cliccatoInvoca1");
keys = [];
$('input[name="multiselect_select-1"]:checked').each(function () {
keys.push(this.value);
});
});
$(document).on('click', "#bottone1.cliccatoInvoca3", function () {
alert("cliccatoInvoca3");
keys = [];
$('input[name="multiselect_select-1"]:checked').each(function () {
keys.push(this.value);
});
});
});
Notes:
I am ignoring the fact that your event handlers contain identical code and assume the real code has different operations.
i have the following situation:
i have an animated graph, at the end of the animation i want to add a click handler to a "dead" link, which then hides the actual slide and shows the next. i bind it with .one, cause i dont want to fire it again after loading.
so it works, it shows the next slide, but the event is not unbinding.
even if i unbind it manually it fires the event.
can someone give me a clue?
thx
jesta
$("li#slide3").off().on("click", $(this), function() {
$("#slide3 .device").animate({opacity:1}, 1000, function() {
$("#slide3 .device").animate({opacity:0}, 1000, function() {
console.log($("li#slide3 img.graph_adds").data("height"));
$("li#slide3 img.graph_adds").animate({height:$("li#slide3 img.graph_adds").data("height")}, 1500, function() {
$("#book_container").one("click", "a#book", function(ev) {
ev.stopImmediatePropagation();
ev.preventDefault();
if (!animBook) { initialiseAnimatedImages(); }
$("li.active_slide").fadeOut(500, function() {
$("li#slide4").addClass("active_slide").fadeIn(1000);
resetSlides();
}).removeClass("active_slide");
});
});
});
});
});
so, i think i found the solution. the animation was the problem. cause there were multiple devices and graphs with my code-structure each device was firing the function code, so device1 fired, then the two graphs fired two time, then device2 fired them again and so on.
with the .promise().done() structure all is just fired once, the animation works and all events are just fired once. now it should work too that i bind the elements in the .on()-statements, cause now they should bind only once then...but...nevah change a running system ^^
$("li#slide3").on("click", $("div.slide3"), function(ev) {
$("#slide3 .device").animate({opacity:1}, 1000).promise().done(function() {
$("#slide3 .device").animate({opacity:0}, 1000).promise().done(function() {
console.log("slide3-height: "+$("li#slide3 img.graph_adds3").data("height"));
$("li#slide3 img.graph_adds3").animate({height:$("li#slide3 img.graph_adds3").data("height")}, 1500).promise().done(function() {
console.log("slide3 click");
if(!$("a#book").hasClass("slide_4") ) {
$("a#book").addClass("slide_3"); }
});
});
}).promise().done(function() { console.log("div.slide3 anim don") });
});
Here is JQuery command that removes all bindings from the element:
$("#book_container").unbind(); //to flush previously bound actions
I got a double event to manage. The two events are both "click" and they're handled with jquery. The html is the following:
<div class="siteMap" style="width:23%;">
<h5>Divisione Anticontraffazione</h5>
<span class="menufooter">
<span class="link1">Introduzione</span><br>
<span class="link2">Filosofia</span><br>
<span class="link3">Negozio online</span></span><br>
</div>
Then i have my click events which fires inside the menufooter span and inside every single link span. The code is like this:
$(document).ready(function() {
$('span.menufooter').click(function() {
//my code here
});
$("span.link1").click(function() {
//my code here
});
});
I need an event capturing action, the click on the span menufooter has to fire the event before the click on the span link1 fires. At this point, none of the two events is firing. Any hint?
How about only fire event on .menufooter
$(document).ready(function() {
$('span.menufooter').click(function(e) {
//my code here 1
// Capture Event Propagation
if ( $("span .link1").find(e.target).length>0 ){
//my code here 2
};
});
});
http://jsfiddle.net/9QLtG/
You could prevent the click from bubbling, and then trigger the click on the parent element so whatever is in that handler executes first (unless it's async)
$(document).ready(function () {
$('.menufooter').click(function () {
// fires before ....
});
$("span.link1").click(function (e) {
e.stopPropagation();
$('.menufooter').trigger('click');
// .... this fires, as it's triggered above
});
});
FIDDLE
I would have 1 click listener that listens to the wrapper. You can check the event's target to see if they actually clicked on a link and run code accordingly.
For example:
$(document).ready(function() {
$('.container').click(function(e) {
// Perform action when they clicked in the main wrapper,
// regardless of whether or not it was a link.
console.log("I clicked in the wrapper...");
if ($(e.target).hasClass('link')) {
// Perform action if they clicked on a link.
console.log("...but more specifically, on a link.");
}
});
});
Here's a fiddle that demonstrates this: http://jsfiddle.net/WaYFr/
Try this event.stopPropagation();
$("span.link1").click(function(event) {
event.stopPropagation();
...
});
I have elements on my page (id=itemid) that when hovered over cause another element (id=panel) to become visible (via fadeIn). Basically a hover event on itemid causes panel to fadeIn and mouseOut leads to fadeOut.
I want to make a button so that when clicked the panel element does not fadeIn or out but stays visible. When that button is clicked, the mouseIn and mouseOut events should work again.
Any ideas?
Thank you!
$(document).ready(function(){
$('.itemid').hover(
function () {
$('.panel').fadeIn(300);
},
function () {
$('.panel').fadeOut(200);
}
);
});
Set a flag for whether to do the fading or not:
$(document).ready(function(){
var fadeEnabled = true;
$('.itemid').hover(
function () {
if (fadeEnabled) {
$('.panel').fadeIn(300);
}
},
function () {
if (fadeEnabled) {
$('.panel').fadeOut(200);
}
}
);
$("#myButton").click(function() {
fadeEnabled = !fadeEnabled;
});
});
Then, just toggle that flag with your button and it will enable or disable the fade behavior.
On click of the button, use $(selector).unbind('mousein') on your object/item to deregister the events., and the reregister on another click of the button. Keep toggling on each click of the button.