jquerys' e.stopPropagation() cannot get required functionality - javascript

photoContainer below has children. This works okay, but if I click on any of its children the code execute, hides blackLayer and removes photoContainer. How can I prevent this from happening and yet execute when I click anywhere but on photoContainer children ?
Thanks.
$('div#photoContainer').live('click', function (e) {
e.stopPropagation();
var blackLayer = $('div#blackLayer');
if (blackLayer.length) {
blackLayer.fadeOut();
}
$(this).remove();
});

I believe the problem is that you are stopping the propagation of the event on the parent element, you want to stop the propagation of the event on the children of the #photoContainer element so it does not propagate up to the #phoeoContainer element:
$('#photoContainer').live('click', function (e) {
var blackLayer = $('div#blackLayer');
if (blackLayer.length) {
blackLayer.fadeOut();
}
$(this).remove();
});
$('#photoContainer > div').live('click', function (event) {
event.stopPropagation();
});
This will stop the propagation of the click event when it is triggered on a child div of the #photoContainer element.
Here is a demo: http://jsfiddle.net/J9dBS/2/ (notice that if you click on the "child" element that no alert is shown)
I would like to note that .live() is deprecidated as of jQuery 1.7. If you are using jQuery 1.7 or later then it's suggested to use .on() like this:
$(<root-element>).on(<event>, <selector>, <event-handler>)
Or if you are using jQuery 1.4.2 to jQuery 1.6.4 then it's suggested that you use .delegate():
$(<root-element>).delegate(<selector>, <event>, <event-handler>);

Related

jQuery has stopped recognizing click events

I have a function that is called every time a user goes through a new step to bind the click event to each new item that is added to the page, and it was working fine but now it's stopped and I cannot figure out why
Below is the function (or click here for full js):
function bindClickEvents() {
console.log('bindClickEvents');
$(".wall-dropdown .item").unbind('click').on('click', function() {
console.log('Item clicked');
if ($(this).hasClass('range')) {
$(".item.range").removeClass('active');
selectedRange = $(this).data('id');
$(this).addClass('active');
selectedStyle = null;
selectedColour = null;
}
if ($(this).hasClass('style')) {
$(".item.style").removeClass('active');
selectedStyle = $(this).data('id');
$(this).addClass('active');
selectedColour = null;
}
if ($(this).hasClass('colour')) {
$(".item.colour").removeClass('active');
selectedColour = $(this).data('id');
$(this).addClass('active');
}
runFilter();
});
}
Use off with on (not unbind)
$(".wall-dropdown .item").off('click').on('click', function() {
However I suggest you simply switch to delegated event handlers (attached to a non changing ancestor element):
e.g
$(document).on("click", ".wall-dropdown .item", function()
It works by listening for the specified event to bubble-up to the connected element, then it applies the jQuery selector. Then it applies the function to the matching items that caused the event.
This way the match of .wall-dropdown .item is only done at event time so the items can exists later than event registration time.
document is the best default of no other element is closer/convenient. Do not use body for delegated events as it has a bug (to do with styling) that can stop mouse events firing. Basically, if styling causes a computed body height of 0, it stops receiving bubbled mouse events. Also as document always exists, you do not need to wrap document-based delegated handlers inside a DOM ready :)
Why don't you bind event to body like
$('body').on('click','.wall-dropdown .item',function(){...some code...})
to prevent reinitialization of event?
this code automaticaly works with each new element .wall-dropdown .item

Second jQuery button click isn't firing

I am trying to do something ostensibly simple in jsfiddle and it is not working. Essentially I have an h1 html tag with class "me" and a button with class "poo". The first click works and my css color changes, however the second click does not work?
$(".poo").click(function(e){
e.preventDefault();
$(".me").css("color","green");
var haha = $("<button>Click Me!!!</button>");
$(this).after(haha);
$(haha).addClass("changer");
$(this).hide();
});
$(".changer").click(function(e){
e.preventDefault();
$(".me").css("color","black");
$(this).hide();
});
Bind the second click to the parent element:
$(document).on('click', '.changer', function() {
//function here
});
The changer click handler is bound before the element exists. Try using the $.on method instead.
http://api.jquery.com/on/
$('body').on('click', '.changer', function() {...})
This works because the event handler is bound to the document body, which already exists on the page. When there is a click anywhere in the body, jQuery will check if the clicked element matches the selector .changer and execute the callback if so.
Alternatively, you could just bind the $('.changer').click event within the first callback.
Update fiddle: http://jsfiddle.net/0yodg7gb/7/
$(".poo").click(function(e){
e.preventDefault();
$(".me").css("color","green");
var haha = $("<button>Click Me!!!</button>").addClass('changer');
$(this).after(haha);
$(haha).addClass("changer");
$(this).hide();
bindClick();
});
function bindClick(){
$(".changer").bind('click',function(e){
e.preventDefault();
$(".me").css("color","black");
$(this).hide();
});
}

JS mouseenter triggered twice

The problem is about event mouseenter which is triggered twice.
The code is here : http://jsfiddle.net/xyrhacom/
HTML :
<div id="elt1" class="elt" val="text1">
text1
<div id="elt2" class="elt" val="text2">
text2
<div>
</div>
JS :
$(document).ready(function() {
$(".elt").mouseenter(function() {
console.log($(this).attr('val'));
});
})
I understand the problem is the event is linked to the class attribute so it is triggered for each class, but I need to find a way to consider just the event triggered for the child.
In the example, when mouseover text2, it displays in the console 'text2 text1' but I want to find a way to only display 'text2' (keeping the same HTML code)
use stopPropagation(); Prevents the event from bubbling up the DOM tree,
$(document).ready(function() {
$(".elt").mouseenter(function(e) {
e.stopPropagation();
console.log($(this).attr('val'));
});
})
Updated demo
Both #elt1 and #elt2 have your selector class (.elt )
use event.stopPropagation() to stop event from bubbling up in the DOM tree
$(document).ready(function() {
$(".elt").mouseenter(function(event) {
event.stopPropagation();
console.log($(this).attr('val'));
});
})
If you only want to let the first child trigger the event, you can use a selector like:
$(".elt > .elt")
The issue here is that elt2 is inside elt1, and the mouseenter event is bubbling up the DOM chain. You need to stop the bubbling by using event.stopPropagation() to prevent your function from firing multiple times:
$(document).ready(function() {
$(".elt").mouseenter(function(e) {
e.stopPropagation();
console.log($(this).attr('val'));
});
})
I've made a fiddle here: http://jsfiddle.net/autoboxer/9e243sgL/
Cheers,
autoboxer

if clicked arround element with jQuery

i just wanna ask if there's something like "if clicked arround" in jQuery, i mean, if clicked any element in the page except for one element, or if there a way to make that easily.
You can try this:
$(document).on("click", function(event) {
if($(event.target).parents().index(yourElement) == -1) {
// your code here
}
});
Yes you can use .not()
event.stoppropagation
Description: Prevents the event from bubbling up the DOM tree, preventing any parent handlers from being notified of the event.
$('#divID').not('#ElID').click(function(){
//* code here */
});
Or
:not()
$('#divID:not("#ElID")').click(function(){
//* code here */
});
Start Reading jQuery API Documentation and Learning
Updated After OP's comment.
Fiddle Demo
event.target and .is()
$('#divID').click(function (event) {
if (!$(event.target).is('#ElID')) {
alert('Work');
}
});
Fiddle Demo
Works on click anywhere except element with id ElID
$('html').click(function (event) {
if (!$(event.target).is('#ElID')) {
alert('Work');
}
});

click outside DIV

<body>
<div id="aaa">
<div id="bbb">
</div>
</div>
</body>
$(#?????).click(function(){
$('#bbb').hide();
})
http://jsfiddle.net/GkRY2/
What i must use if i want hide #bbb if user click outside box #bbb? But if i click on div #bbb then box is still visible - only outside.
$('body').click(function(e){
if( e.target.id == 'bbb' )
{ return true; }
else
{ $('#bbb').hide(); }
});
A note of explanation: There are a few ways to do this, either way we need to listen for a click on a parent element, weather it be a direct parent like #aaa or a distant parent like the body or the document. This way we can capture clicks that occur outside of #bbb.
Now that we have that we need the .hide to NOT occur if the user did click inside of #bbb. We can do this two ways
Stop propagation if the user clicks on #bbb. This will make the click event not 'bubble' up to the parent. That way the click event never reaches the parent and so #bbb will not hide. I personally don't like this method because stop propagation will so ALL click events from bubbling, and you may have click events that you would like to bubble to a local parent and not a distant parent. Or you may have listeners delegated from a distant parent, which will stop working if click propagation is stopped.
Check for the #bbb element in the parent listener. This is the method shown above. Basically this listens on a distant parent, and when a click occurs it checks to see if that click is on #bbb specifically. If it IS NOT on #bbb .hide is fired, otherwise it returns true, so other things that may be tied into the click event will continue working. I prefer this method for that reason alone, but secondarily its a-little bit more readable and understandable.
Finally the manner in which you check to see if the click originated at #bbb you have many options. Any will work, the pattern is the real meat of this thing.
http://jsfiddle.net/tpBq4/ //Modded from #Raminson who's answer is very similar.
New suggestion, leverage event bubbling without jQuery.
var isOutSide = true
bbb = documment.getElementById('bbb');
document.body.addEventListener('click', function(){
if(!isOutSide){
bbb.style.display = 'none';
}
isOutSide = true;
});
bbb.addEventListener('click', function(){
isOutSide = false;
});
Catch the click event as it bubbles-up to the document element. When it hits the document element, hide the element. Then in a click event handler for the element, stop the propagation of the event so it doesn't reach the document element:
$(function () {
$(document).on('click', function () {
$('#bbb').hide();
});
$('#bbb').on('click', function (event) {
event.stopPropagation();
});
});
Here is a demo: http://jsfiddle.net/KVXNL/
Docs for event.stopPropagation(): http://api.jquery.com/event.stopPropagation/
I made a plugin that does this. It preserves the value for this where as these other solutions' this value will refer to document.
https://github.com/tylercrompton/clickOut
Use:
$('#bbb').clickOut(function () {
$(this).hide();
});
You can use target property of the event object, try the following:
$(document).click(function(e) {
if (e.target.id != 'bbb') {
$('#bbb').hide();
}
})
DEMO
This will work
$("#aaa").click(function(){
$('#bbb').hide();
});
$("#bbb").click(function(event){
event.stopPropagation();
})​
Becouse bbb is inside the aaa the event will "bubbel up to aaa". So you have to stop the bubbling by using the event.stopPropagation when bbb is clicked
http://jsfiddle.net/GkRY2/5/
OK
* this is none jquery. you can easly modify it to work with IE
first create helper method to facilitate codding don't get confused with JQuery $()
function $g(element) {
return document.getElementById(element);
}
create our listener class
function globalClickEventListener(obj){
this.fire = function(event){
obj.onOutSideClick(event);
}
}
let's say we need to capture every click on document body
so we need to create listeners array and initialize our work. This method will be called on load
function initialize(){
// $g('body') will return reference to our document body. parameter 'body' is the id of our document body
$g('body').globalClickEventListeners = new Array();
$g('body').addGlobalClickEventListener = function (listener)
{
$g('body').globalClickEventListeners.push(listener);
}
// capture onclick event on document body and inform all listeners
$g('body').onclick = function(event) {
for(var i =0;i < $g('body').globalClickEventListeners.length; i++){
$g('body').globalClickEventListeners[i].fire(event);
}
}
}
after initialization we create event listener and pass reference of the object that needs to know every clcik on our document
function goListening(){
var icanSeeEveryClick = $g('myid');
var lsnr = new globalClickEventListener(icanSeeEveryClick);
// add our listener to listeners array
$g('body').addGlobalClickEventListener(lsnr);
// add event handling method to div
icanSeeEveryClick.onOutSideClick = function (event){
alert('Element with id : ' + event.target.id + ' has been clicked');
}
}
* Take into account the document body height and width
* Remove event listeners when you don't need them
$(document).click(function(event) {
if(!$(event.target).closest('#elementId').length) {
if($('#elementId').is(":visible")) {
$('#elementId').hide('fast');
}
}
})
Change the "#elementId" with your div.

Categories

Resources