jquery calling an event inside another binded event - javascript

I have an html as below :
<div class="parent">
parent
<div class="child">child</div>
</div>
Here is my Jquery binding an click event :
$(document).ready(function(){
$('.parent').on('click', function(){
alert('parent div');
});
$('.child').on('click', function(){
alert('child div');
});
});
I want, if I click on ".child" div, then event bound on "div.parent" should not be called.
Again if I click on ".parent" div and its bound event should be executed.
I have tried with following -
$('.child').on('click', function(){
alert('child div');
$(this).parents('.parent').off('click');
return false;
});
But above code has unbound the "click" event on parent div permanently,
and again its click event does not trigger.

why don't you stop propagating to prevent bubbling up the event from child to achieve this
$(document).ready(function(){
$('.parent').on('click', function(){
alert('parent div');
});
$('.child').on('click', function(ev){
ev.stopPropagation();
alert('child div');
});
});

Once you click on the child div, the event bubbles up through the DOM tree, which causes the parent div to be triggered, now to prevent this you need to stop propagation using event.stopPropagation() read more on it here
$('.child').on('click', function(event){
event.stopPropagation();
alert('child div');
return false;
});

Gautam,
Interesting problem. I was thinking subclasses. But since you have the div elements wrapped in each other, this is not feasible. Therefore, I recommend the following functions that will toggle the response until the next time it is clicked.
makeParentReady = function() {
$('.parent').on('click', function(){
myClass=this.className;
alert('parent div');
});
}
$(document).ready(function(){
makeParentReady();
$('.child').on('click', function(){
myClass=this.className;
alert('child div');
$(this).parents('.parent').off('click');
makeParentReady();
return false;
});
});

Yes. Dhiraj is right. use topPropagation() function
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script>
$(document).ready(function(){
$('.parent').on('click', function(){
alert('parent div');
$('.child').click();
});
$('.child').on('click', function(e){
e.stopPropagation()
alert('child div');
});
});
</script>
</head>
<body>
<div class="parent">
parent
<div class="child">child</div>
</div>
</body>
</html>

Related

Disabling a click event from the child of a parent div

I am trying to add a on click event to a div with a class parent. Now inside that div I have a div with class child that has its own click event.
How can I manage to disable the click event of the parent function for that child element in order to execute the function of child element itself?
I have tried using pointer-event:none; but it does not seem to be working. I have wrote a jsfiddle for better understanding.
https://jsfiddle.net/arq1epbs/
$(document).on('click', '.parent', function() {
var url = $(this).attr("data-url")
document.location.href = url
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="parent" data-url="www.google.com">
Im the parent
<div class="child">
im the child and I don't want to go to Google
</div>
</div>
Thanks for all the help in advance!
You can use stopPropagation():
$(document).on('click', '.parent', function () {
var url = $(this).attr("data-url")
document.location.href = url
});
$(document).on('click', '.child', function (e) {
e.stopPropagation();
});
As it's not working in the Stack Snippet, here a Fiddle
For reference: stopPropagation()
You can simply call event.stopPropagation() inside child click event, to prevent the event from bubbling up the DOM tree, preventing any parent handlers from being notified of the child click event like:
$(document).on('click', '.parent', function() {
//var url = $(this).attr("data-url")
//document.location.href = url
console.log('Parent Clicked');
});
$(document).on('click', '.child', function(event) {
event.stopPropagation();
console.clear();
console.log('Child Clicked');
});
.parent{background:#99c0c3;width:350px;height:120px;position:relative}
.child{background:#ffde99;width:300px;height:50%;position:absolute;left:50%;top:50%;transform:translate(-50%,-50%)}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="parent" data-url="www.google.com">
Im the parent
<div class="child">
im the child and I don't want to go to Google
</div>
</div>
Just add this line:
$(document).on('click', '.parent', function (e) {
if(e.target !== this) return false; //This line added
var url = $(this).attr("data-url")
document.location.href = url
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="parent" data-url="www.google.com">
Im the parent
<div class="child">
im the child and I don't want to go to Google
</div>
</div>
You can do this in "pure" JS
document.querySelector('div.parent').onclick = evt =>
{
if (!evt.target.matches('div.parent')) return // reject sub elements click
document.location.href = evt.target.dataset.url
}
div.parent { cursor: pointer }
div.child { cursor: default }
<div class="parent" data-url="www.google.com">
Im the parent
<div class="child">
Im the child and I don't want to go to Google
</div>
</div>

stopPropagation & preventDefault are not working, parent click is still firing

In my code, I have added onclick on parent div and want to perform other action on inner div, but clicking on inner div also triggering parent click.
how to stop that?
$(document).on('click', '.child', function(e) {
e.preventDefault();
e.stopPropagation();
console.log('child');
});
function parentfun(sender) {
console.log('parent');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent" onclick="parentfun(this)">
parent
<div class="child">child</div>
</div>
Above divs are generated on run time on some other event.
Clicking on child, also trigger parent's click. preventDefault & stopPropagation are not working.
FYI: my question is different than How do I prevent a parent's onclick event from firing when a child anchor is clicked?
What you are actually doing here is binding the click-event to the document, not the child-element. So the event has already bubbled up all the way to the document, it's too late to try to stop the bubbling with stopPropagation.
See here when I change the click-handler to the child instead:
$(".child").on('click', function(e) {
e.preventDefault();
e.stopPropagation();
console.log('child');
});
function parentfun(sender) {
console.log('parent');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent" onclick="parentfun(this)">
parent
<div class="child">child</div>
</div>
Edit
As the question changed a bit, here is what you can do (for example) if the elements are created dynamically:
$(document).on('click', '.parent, .child', function(e) {
e.stopPropagation();
if ($(this).is(".child")) {
console.log('child');
} else {
console.log('parent');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent">
parent
<div class="child">child</div>
</div>
Using plain vanilla JS it works as expected:
function logEventTarget(e) {
e.stopPropagation();
console.log(e.target.id);
}
parentDiv.addEventListener('click', logEventTarget)
childDiv.addEventListener('click', logEventTarget)
<div id="parentDiv">
parent
<div id="childDiv">child</div>
</div>
Using an inline event handler won't pass the event to the handler function:
function logEventTarget(e) {
e.stopPropagation();
console.log(e.target.id);
}
childDiv.addEventListener('click', logEventTarget)
<div id="parentDiv" onclick="logEventTarget()">
parent
<div id="childDiv">child</div>
</div>
One of the many reasons you shouldn't use inline event handlers at all. Note that e.stopPropagation() still works for the childDiv.
You can notice that when clicking the chlid element the parent triggers first (that is why parent prints first then child ) because of event capturing which precedes event bubbling. In-order to stop the event capturing phase from parent you can stop propagating that event and then only child event will trigger.
$(document).on('click', '.child', function(e) {
//e.preventDefault();
e.stopPropagation();
console.log('child');
});
$(document).on('click', '.parent', parentfun);
function parentfun(e) {
e.stopPropagation();
console.log('parent');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent">
parent
<div class="child">child</div>
</div>
You can also resolve this problem by editing little bit in Your html code
<div class="parent" id="parent-div">
<!-- Just adding parent div text inside span tag -->
<span>parent</span>
<div class="child">child</div>
</div>
now go to jquery code
$('.parent span').on('click',function(){
//only print child text u can do more
alert($('.child').text());
//Change color of child
$('.child').css('color','red');
});

jquery on event for a dynamically generated child of a dynamically generated child

I have a div that gets added to dynamically and I would like to have a mouseenter event for images that have been dynamically added in another tag. The div that is getting added to looks like this before hand:
<div class="chat_box">
</div>
and looks like this after content has been added:
<div class="chat_box">
<p class="chat">text here <img class="emote" src="emote.png"> more text</p>
</div>
I would like to have a mouseenter event for the image with the class of emote, but I cannot get it to work.
I have tried the following:
$('.chat_box').on('mouseenter', '.chat', function(){
alert();
});
and it works, but if I try to use the child selector
$('.chat_box').on('mouseenter', '.chat > .emote', function(){
alert();
});
and
$('.chat_box').on('mouseenter', '.chat > img', function(){
alert();
});
it doesn't work.
This was previously provided by .live(), but that function has been merged into .on() ... it creates an event watcher.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div class="chat_box"></div>
<button>Add</button>
<script>
$('button').click(function(){
$('<div class="chat"><img width=10 height=10 class="emote"></div>').appendTo('.chat_box');
});
$('.chat_box').on('mouseenter', 'img.emote', function(){ alert('test'); });
</script>
Just target the parent object and have it watch for the expected child.

Jquery .remove event only on parent not child

<script>
$(".alert").click(function(){
$(this).fadeOut(300, function(){
$(this).remove();
});
});
</script>
<div class="alert alert-error">
<h4>title</h4>
<textarea class="pull-right">text...</textarea>
</div>
So the above code works perfectly except that I need to make it so that a user can select the text inside the textarea. At this moment logically when they click the textarea, as its contained by .alert, it instantly gets removed with the div.
I can't remove the textarea from the div as I need it both contained by the div, and removed when other parts of the div are clicked.
So how can I specifically exclude the textarea from the click event of its containing div while still allowing the click event from the containing div to remove the textarea.
You can do this by preventing the click event from propagating (bubbling) from the textarea to the div:
$(".alert textarea").on("click", function(e) {
e.stopPropgation();
});
Example:
$(".alert").click(function(){
$(this).fadeOut(300, function(){
$(this).remove();
});
});
$(".alert textarea").on("click", function(e) {
e.stopPropagation();
});
<div class="alert alert-error">
<h4>title</h4>
<textarea class="pull-right">text...</textarea>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Alternately, in your existing handler, check to see if the event passed through the textarea:
$(".alert").click(function(e){
if (!$(e.target).closest("textarea").length) {
$(this).fadeOut(300, function(){
$(this).remove();
});
}
});
Example:
$(".alert").click(function(e){
if (!$(e.target).closest("textarea").length) {
$(this).fadeOut(300, function(){
$(this).remove();
});
}
});
<div class="alert alert-error">
<h4>title</h4>
<textarea class="pull-right">text...</textarea>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Note that that second one relies on the fact that your .alert element can never be inside another textarea, because of the nature of the elements. It won't work in the general case. This would, but it's a pain:
$(".alert").click(function(e){
var $t = $(e.target);
if (!$t.is("textarea") && !$t.parentsUntil(this, "textarea").length) {
$(this).fadeOut(300, function(){
$(this).remove();
});
}
});
you can also use the not selector to do this :
<script>
$(".alert *:not(textarea)").click(function(){
$(this).fadeOut(300, function(){
$(this).parent().remove();
});
});
</script>
<div class="alert alert-error">
<h4>title</h4>
<textarea class="pull-right">text...</textarea>
</div>
see this fiddle: https://jsfiddle.net/zLq6dztu/

Jquery how to use $(this) to get value of clicked item?

I have trouble getting value of particular item that I'd clicked
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
$(document).ready(function(){
$(this).click(function(){
alert($(this).find("button").html());
});
});
</script>
</head>
<body>
<p>test 1</p>
<p>test 2</p>
<button>Yes</button>
<button>No</button>
</body>
</html>
I'd tried $(this).find("button").html(), but it will return the value of 1st button("Yes) even if I clicked the 2nd button("No")
Same for $(this).find("p").html(), will return value of 1st
How do I use $(this) to get the value of item I clicked?
Don't suggest me to insert class or id, I'm not suppose to touch the html.
Please assist, thanks.
this in your click handler is always the document (which you've bound the handler to), so that doesn't help anything. Instead, use something like
$(document).click(function(e){
if ($(e.target).is("button"))
console.log($(e.target).text());
} else {
console.log("not clicked (directly) on a button");
}
});
or rather just
$(document).on("click", "button", function(e){
console.log($(this).text());
});
It is because $(this).click event listener is added to document object and not any specific html element.
$(document).ready(function(){
$('button,p').on('click',function(){
alert($(this).html());
});
});
plunker: https://jsfiddle.net/wx38rz5L/1743/
If you are trying to get each button's html on click, use this.
$('button').click(function () {
alert($(this).html());
});
Bind the click event on both button and get the content of the html element with innerHTML.
$(document).ready(function() {
$('button').click(function(event) {
alert(event.target.innerHTML);
});
});
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
</head>
<body>
<p>test 1</p>
<p>test 2</p>
<button>Yes</button>
<button>No</button>
</body>
</html>
You have to detect which $(this) is binded for ? Try something like this:
Setup an object
<button class="btn red btn-xs editbtn" type="button" value="${rs.id}" value="${rs.id}">
Function for this object
$(function(){
$('.editbtn').click(function(e){
common.showSpinner();
var idbbpdtd = $(this).val();
});
});
Try this.
$(document).ready(function() {
$(this).click(function(event) {
alert(event.target.innerHTML);
});
});
In jQuery event.target always refers to the element that triggered the event.

Categories