Stop propagation not working, avoid children click trigger other function - javascript

I write simple overlay for my page, kind of lightbox, but is going to do other stuff, anyway, My bigger problem in this tests... is I want when you click the overlay mask, the overlay close... But if you click in the children div, like the content div inside the overlay the overlay must remain open.. (which is not, that's the problem)
http://jsfiddle.net/7Cr2V/
How can I say in Javascript, if I click a child div of "overlayfull" please do not close or hide the overlayfull ... here is my code.. and above is the js fiddle if you want to check it cause my English is very bad.
$('div.vidreveal a').click(
function(event) {
event.stopPropagation();
$('div.videoquon').fadeToggle(300);
$('div.overlayfull').fadeToggle(300);
}
);
$('div.my-video-close').click(
function(event) {
event.stopPropagation();
$('div.videoquon').fadeToggle(300);
$('div.overlayfull').fadeToggle(300);
}
);
$('div.overlayfull').click(
function(event) {
event.stopPropagation();
$('div.videoquon').fadeToggle(300);
$('div.overlayfull').fadeToggle(300);
}
);

One solution is to add a click handler to the children, in which you stop propagation:
$('div.overlayfull').children().click(function(event){
event.stopPropagation();
});

stop propagation only works for parent elements it doesnt not stop the active element itself. you can encompass the text with a class and return false if clicked on that
<div id='my-video'></div>
<div class="message">CLIC HERE MUST NOT CLOSE THE OVERLAY</div>
</div>
if (event.target.className === 'message')
return false;
http://jsfiddle.net/59trN/

I think this is the simplest way to do it if I understand the question correctly. I just check within your handler to see if the div getting clicked on is the one you don't want to close the modal, and return from the function before the fadeout is triggered:
$('div.overlayfull').click(
function(event) {
if ($(event.target).hasClass('videoquon')){
return;
}
event.stopPropagation();
$('div.videoquon').fadeToggle(300);
$('div.overlayfull').fadeToggle(300);
}
);
Check out the fiddle http://jsfiddle.net/aRDKS/

Either have an event for the divs inside overloay div and stoppropagation on that. Inorder to stop the Propagation of event occurring on the children of a parent which has that particular event's handler, either check for the target from where the event generated in the paent handler or add a handler for the children and apply event.stopPropagation() to avoid the event bubbling up to the parent.
$('div.overlayfull div').click(function (e) {
e.stopPropagation()
});
or check for the target's id from which the event was generated:
function (event) {
if (event.target.id == 'overlayfull') { // Check here if the event originated from the intended div itself
$('div.videoquon').fadeToggle(300);
$(this).fadeToggle(300);
}
});
Fiddle

Related

Jquery toggle div, allow clicking outside of div to close, also allow everything inside the div clickable

I have a toggle event on a div, and I've seen many questions regarding mine but nothing seems to work for what I'm trying to do, it either makes my div disappear in a few seconds, or it just doesn't work. Here's my jsfiddle.
I have a div that needs to toggle when another <div> is clicked. The toggled div has inputs in it that need to be filled out, and a submit button inside it as well. So I need clicks inside the div to be allowed, but only inside my div. So I want the div to show unless the user clicks outside of this div.
I'm using this query which toggles fine:
$('#MyDiv').click(function (event) {
$("#ToggledDiv").slideToggle();
});
And then this coding to hide it when clicked outside of the div which doesn't work:
$(window).click(function () {
$("ToggledDiv").hide();
});
I've tried solutions with e.preventDefault(); but that doesn't work, or $(document).click, even mousedown but it just doesn't flow how I want, it'll hide it within a few seconds, or it will prevent the toggle from even working so I'm lost.
The reason behind this behavior is Event Bubbling and Capturing of HTML DOM API. You can use event.stopPropagation() OR event.cancelBubble = true to prevents the event from bubbling up to the DOM tree, preventing any parent handlers from being notified of the event.
Another good article: events order
$('#MyDiv').click(function(event) {
$("#ToggledDiv").show();
disabledEventPropagation(event);
//console.log('2nd event');
});
$('#ToggledDiv').click(function(event) {
disabledEventPropagation(event);
//console.log('3rd event');
});
$(document).click(function() {
$("#ToggledDiv").hide();
//console.log('1st event');
});
function disabledEventPropagation(event) {
if (event.stopPropagation) {
event.stopPropagation();
} else if (window.event) {
window.event.cancelBubble = true;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="MyDiv" style="background-color:yellow">
click me to open
</div>
<div id="ToggledDiv" style="display: none;background-color:yellow">
<input type="text" />
<input type="submit" />
</div>
Take a look at the event when you click inside the #targetDiv. There are two properties you can use to evaluate what action to perform: event.target and event.currentTarget. In this case:
$('#ToggledDiv').on('click', function(event) {
console.log(event.target, event.currentTarget);
});
This is a good way to see if what clicked is actual target or a child element in the target.
To add to Chris' answer, you can see here that I check that the e.target is not inside the form using vanilla Node.contains, and also not the button...
https://jsfiddle.net/jmLdp45s/3/
var $button = $('button');
var $form = $('form');
$button.click(function() {
$form.slideToggle();
});
$(window).click(function(event) {
if (
!$form.get(0).contains( event.target ) // target is not inside form
&& event.target !== $button.get(0) // target is not button
) $form.hide();
});

Fire event only when clicking on an element, and not on its children

If I bind a click handler to the body element, when I click anything on the page the event is triggered. I can check the event.target on every click:
$("body").on("click", function(event) {
if (event.target.tagName == "BODY") {
...
}
});
but that seem a bit overkill. Is there a way to trigger the event only when clicking the blank area of the body itself?
You can use the eventPhase property of event. A value of 2 means that the event is currently triggering the target element:
$("body").on("click", function(event) {
//Cancel if not at target
if (event.eventPhase != 2) return;
//Other Code Here
});
Fiddle Here: http://jsfiddle.net/o0yptmmp/
You should put an
event.stopPropagation()
on all children you want to not bubble up.
jQuery Docs: http://api.jquery.com/event.stoppropagation/.
You can do it if you check on every click if the element clicked has a body parent. If the condition is false, you are clicking the body:
$("body").on("click", function(event) {
if ($(this).parents('body').length == 0) {
//Do something
}
});
In my opinion it's not a good practice, but it depends on your code and project.

jQuery Child Event Handling

I have a container element. The element may or may not have anchor tags in it. I want to listen for click events within that element. I want to handle each click only once, but I want to do something different if an anchor tag is clicked.
Issues that I've run into:
Listening at the container element level doesn't capture the anchor tag clicks: $('#ID').on('click', myFunction);
Listening to every child in the container ends up firing multiple events: $('#ID').find(*).on('click', myFunction);
How do I accomplish this?
This should work:
$('#ID').on('click', function(e) {
if ($(e.target).closest("a").length) {
anchorWasClicked();
} else {
somethingElseWasClicked();
}
});
You can check the target of the click. And as you seem to be trying to enable the click just once for every element within the container, you should then use .one():
$(function() {
$("#container").children().one("click", function(e) {
e.preventDefault(); // For testing purposes.
if ($(e.target).parents().is("a") || $(e.target).is("a")) {
// Anchor.
}
else {
// Others...
}
});
});
Demo
That's an improvement to the example I've posted in the comments previously.

Exclude a checkbox from .click() of a div

I'm tryin to make a div 'active' by clicking on it using jquery. But inside the div, there is a checkbox. I want the div to become active whenever i click anywher inside the div except the checkbox. I have done that, but the checkbox is now not responsding to click events (ie it's not getting checked/unchecked when i click on it).
http://jsfiddle.net/U7VmV/3/
$(document).ready(function(){
$('.c-video').click(function(){
$('.c-video').removeClass('active');
$(this).addClass('active');
});
}).children().find('label').click(function(e){
return false;
});
Use event.stoppropagation()
Prevents the event from bubbling up the DOM tree, preventing any parent handlers from being notified of the event.
}).find('label').click(function (e) {
e.stopPropagation();
});
Fiddle Demo
You have to prevent the propagation of the event, when you return false it prevents the event propagation but it will also prevents the default action of the click event that is checking/unchecking the checkbox.
So instead or returning false call stopPropagation() in the event object
$(document).ready(function(){
$('.c-video').click(function(){
$('.c-video').removeClass('active');
$(this).addClass('active');
});
}).children().find('label').click(function(e){
e.stopPropagation()
});
Demo: Fiddle
Another way to do it is to check clicked event target:
var $cVideo = $('.c-video').on('click', function(e) {
if (e.target.tagName != 'INPUT' && e.target.tagName != 'LABEL') {
$cVideo.removeClass('active');
$(this).addClass('active');
}
});
http://jsfiddle.net/U7VmV/4/

jquery not function miss element

I use a tool-tip to display error message on the page, I need it to be closed when I click elsewhere within the view. I use the below codes to control this action:
$(':not(.qtip)').click(function(){
$('.qtip').hide();
});
The ".qtip" is used for marking the tool-tip area. The tool-tip itself creates a new one when it comes out, what happened here is when I click on the tool-tip, it disappears.
But when I use a smaller scale of the selector instead of the whole body, it works fine, which is a little weird, for example:
$("#id").not('.qtip').click(function (){
$('.qtip').hide();
});
It would be advisable to just target document for handling the click outside of your tooltip; the selector for :not(.qtip) potentially returns a very big result set.
$(document).on('click', function() {
$('.qtip').hide();
}
On the tooltip itself you would need to prevent the click event from bubbling to document level, if you're not doing so yet:
$('.qtip').on('click', false);
Use event bubbling to your advantage
$(document).on("mouseup", function (e) {
var target = e.target || e.srcElement;
var container = $(".qtip");
if (container.not(target) && container.has(target).length === 0)
{
container.hide();
}
});
I suggest you to do two things:
$(document).click(function() {
$('.qtip').hide();
});
$('.qtip').click(function(e){
e.stopPropagation();
});
click of document to hide the .qtip
stop the event bubbling on click of .qtip, here click won't traverse up to the parent.
Try
$(document).on("click", function(e) {
var qtip = $(e.target).closest('.qtip');
if(!qtip.length)
$('.qtip').hide();
});

Categories