Reputation: 637
I have elements like this
<div class="parent-component">
<div class="form-group">
<label for="my-input">Label</label>
<input type="text" name="my-input" id="my-input" class="form-control">
</div>
</div>
I have attached a click listener with jQuery on
method to the parent as follows
$(document).on("click", ".parent-component", function() {
// ...
})
Where ever I click inside the .parent-component
the event listener fires. However, clicking on the input - or any interactive element (links, buttons, inputs) for that matter - it get's active.
How do I prevent any element inside .parent-component
from being clicked so that I can have inputs and links inside it which are not able to be clicked?
Upvotes: 0
Views: 491
Reputation: 2233
You can do this in several ways
This is just an example on you can exclude child element(s) from parent.
$(document).ready(function(){
$(document).on('click', '.main', function(e){
alert('Parent was clicked');
}).find('.child').on('click', function(){
return false;
});
});
.main{
background: orangered;
color: white;
font-weight: bold;
padding: 10px;
height: 400px;
width: 400px;
padding: 10px;
}
.child{
background: green;
color: white;
margin: auto;
height: 40%;
width: 40%;
padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='main'>
Click me and I will fire up something
<div class='child'>
If you click on me I will not fire.....
I am the child you cannot click me
</div>
</div>
Another way
$(document).ready(function(){
$(".main").click(function(){
alert('Parent was clicked');
}).children().click(function(){
return false;
});
});
.main{
background: orangered;
color: white;
font-weight: bold;
padding: 10px;
height: 400px;
width: 400px;
}
.child{
background: green;
color: white;
margin: auto;
height: 40%;
width: 40%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='main'>
Click me and I will fire up something
<div class='child'>
If you click on me I will not fire.....
This is the child you cannot click me
</div>
</div>
Upvotes: 0
Reputation: 2542
pointer-events
, credit goes to @Tibos
$(document).on("click", ".parent-component", function(e) {
console.log('click on: ' + e.target.className);
});
.no-click {
pointer-events: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent-component">
<div class="form-group no-click">
<label for="my-input" style="pointer-events: none" >Label</label>
<input type="text" name="my-input" id="my-input" class="form-control" />
<span>This still sends clicks to parent</span>
</div>
</div>
Upvotes: 1
Reputation: 130065
You can check if the target item, which was clicked, has some class, and only then, continue.
$(document).on("click", '.someClass', function(e){
if( e.target.classList.contains('someClass') ) return false;
})
Upvotes: 0
Reputation: 24181
Another alternative, so that you can use in different places,..
Is for the controls you don't want to propagate events, you could create a class and target this, and tell them not to propagate the events..
The advantage been if you do have some controls that you do want to propagate the events you can leave the class off.
eg..
$(document).on("click", ".parent-component", function(e) {
console.log('click');
});
$(document).on('click', '.no-propagate', function (e) { e.stopPropagation(); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent-component">
<div class="form-group">
<label class="no-propagate" for="my-input">Label</label>
<input class="no-propagate" type="text" name="my-input" id="my-input" class="form-control">
<span>This still sends clicks to parent</span>
</div>
</div>
Upvotes: 2
Reputation: 34556
This is normally desirable behaviour; a click to a child element is also a click to its parent and ancestor elements, in the same way that you can't be in your bathroom without also being in your house.
If you want to guard against child/descendant clicks, however, you can do this:
$(document).on("click", ".parent-component", function(evt) {
if (!$(evt.target).is('.parent-component')) return false;
//beyond here, we can be sure the element was to the parent directly,
//not any children/descendants
})
Upvotes: 2