.hide on any click action not relating to child elements - javascript

<div id="example" style="background:yellow;height:200px;width:200px;">
<button>Some text</button>
</div>​
I want #example to .hide when it's clicked, but I don't want it to .hide when it's child elements get clicked.

Add a handler to the <div> and then check if it's the target.
In this example, the event.target is the element that was actually clicked, but this is the element attached with the handler.
$('#example').on('click', function(event) {
if (event.target === this) {
alert('div, not button');
$(this).hide();
}
});

Related

Show/Hide toggle button is not working as expected

I am fairly new to jQuery and I tried to create a show/hide toggle button without using jQuery's toggle function and I can't figure out what's wrong with the following code.
The Hide button hides the paragraph successfully. The hide part is working. It adds a class "show" and removes class "hide" and changes button's text. I used Dev Tools to see this and this part is working but clicking on the button again is not working i.e the show part.
$(document).ready(function() {
$(".hide").click(function() {
$(".content").hide();
$(this).addClass("show");
$(this).removeClass("hide");
$(this).text("Show");
});
$(".show").click(function() {
$(".content").show();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
<p class="content">If you click on the "Hide" button, I will disappear.</p>
<button class="hide">Hide</button>
You can use toggle() to easily switch the visible state of an element using a single button. Then you can provide a function to text() to set the text on the button based on its current value. Try this:
$(document).ready(function() {
$(".toggle").click(function() {
$(".content").toggle();
$(this).text(function(i, t) {
return t == 'Show' ? 'Hide' : 'Show';
})
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
<p class="content">If you click on the "Hide" button, I will disappear.</p>
<button class="toggle">Hide</button>
If you wanted to do this without toggle(), then you could use toggleClass() to switch the state of the hide class, like this:
$(document).ready(function() {
$(".toggle").click(function() {
$(".content").toggleClass('hide');
$(this).text(function(i, t) {
return t == 'Show' ? 'Hide' : 'Show';
})
});
});
.hide {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
<p class="content">If you click on the "Hide" button, I will disappear.</p>
<button class="toggle">Hide</button>
You do not want to change the class - if you do you need to delegate so the event is registered to a static container like document
$(document).on("click",".hide",function() {
I suggest to toggle instead:
$(document).ready(function() {
$(".but").on("click",function() {
$(".content").toggle();
$(this).text($(this).text()=="Show"?"Hide":"Show");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
<p class="content">If you click on the "Hide" button, I will disappear.</p>
<button class="but">Hide</button>
Without toggle
$(document).ready(function() {
$(document).on("click",".hide",function() {
$(".content").hide();
$(this).text("Show")
.removeClass("hide")
.addClass("show");
});
$(document).on("click",".show",function() {
$(".content").show();
$(this).text("Hide")
.removeClass("show")
.addClass("hide");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
<p class="content">If you click on the "Hide" button, I will disappear.</p>
<button class="hide">Hide</button>
The click event only works when the element you add it to is built when the DOM is first created. As soon as you change the class name of the button from 'show' to 'hide' this "removes it from the DOM" in an event based sense.
To get the button click event to trigger after you change the class name on the button you must assign the click event using the on() function and the function must be placed on the parent container of the element that will trigger the event. In the example below I have added the on() method to the document object, so all elements within the document that have a class of .hide or .show will inherit these click events. This will also apply to any new elements you create on the fly.
<p class="content">If you click on the "Hide" button, I will disappear.</p>
<button class="hide">Hide</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
<script>
$(document).on('click', ".show", function(){
$(".content").show();
$(this).addClass("hide");
$(this).removeClass("show");
$(this).text("Hide");
});
$(document).on('click', ".hide", function(){
$(".content").hide();
$(this).addClass("show");
$(this).removeClass("hide");
$(this).text("Show");
});
</script>
You should also use the toggleClass() method #mplungjan suggests.
Here's the jQuery docs for the on() function https://api.jquery.com/on/
$("#show-hide").toggle(function() {
$(".content").hide();
$(this).text("Show");
}, function() {
$(".content").show();
$(this).text("Hide");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
<p class="content">If you click on the "Hide" button, I will disappear.</p>
<button id="show-hide">Hide</button>

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');
});

Hide all elements except one, And show all elements again

<body>
<div id="e1">Element X1</div>
<div id="e2">Element 2X</div>
<div id="e3">Element X3</div>
Hide
</body>
How can i hide the entire body And only show #e2 when i click on #hide, But if i clicked anywhere else out of #e2 again, the hide effect will stop and return to normal.
Something like this? NB: make sure to give your hide link a unique ID.
Showing/hiding works well with jQuery show and hide methods, but since you wanted the elements to stay in their place, it is more suitable to use the visibility style attribute:
$('#hide').click(function () {
// hide all in body except #e2, and #e2's parents.
$('body *').not($('#e2').parents().addBack()).css({visibility: 'hidden'});
return false; // cancel bubbling and default hyperlink effect.
});
$('#e2').click(function () { // click on #e2
return false; // cancel bubbling -- ignore click.
})
$(document).click(function (e) { // click on document
$('body *').css({visibility: 'visible'}); // show all in body.
});
div { border: 1px solid}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="e1">Element X1</div>
<div id="e2">Element 2X</div>
<div id="e3">Element X3</div>
Hide
Be aware that these div elements stretch across horizontally, so a click to the right of the text "Element 2X" will still be on #e2.
Something like this:
// Get reference to the hyperlink
var hideElem = document.getElementById("e4");
// Set up click event handler for link
hideElem.addEventListener("click", function(e){
var elems = document.querySelectorAll("body *:not(#e2)");
Array.prototype.slice.call(elems).forEach(function(value){
value.classList.add("hide");
});
e.stopPropagation();
});
// Set up click event handler for document
document.addEventListener("click", function(){
var elems = document.querySelectorAll("body *");
Array.prototype.slice.call(elems).forEach(function(value){
value.classList.remove("hide");
});
});
.hide { display:none; }
<div id="e1">Element X1</div>
<div id="e2">Element 2X</div>
<div id="e3">Element X3</div>
Hide
$('body').click(function(evt){
if(!$(evt.target).is('#e2')) {
//If not e2 is clicked then restore the state back of page by removing a specific class
}
});
You will need help of css class .hide {display:none;} and add and remove this class when e2 is clicked and remove this class when body is clicked but not e2 as provided above

How to bind click event to element hasn't specific child using jquery?

I have several elements on a page like bottom code.
<div>
click
some content
</div>
They can be clicked and jQuery picks that click. However one of the elements has a a link that is clicked should not be picked as a click of the parent element.
$('div:not(#notme)').on('click', function(e) {
// do something
});
Doesn't seem to work for some reason...
Use :has selector to selecting div element has specific child. In :has use :not.
$("div:has(a:not(#notme))").on("click", function(e) {
console.log("clicked");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
click
some content
</div>
<div>
<a href="#" >click2</a>
some content 2
</div>
You may try:
$('div').on('click', function(e) {
if($(e.target).attr("id") !== "notme") {
// do something
}
});
$('#notme').on('click', function(e) {
e.stopPropagation();
});

How to select the clicked child element within a parent element in Jquery?

I have a parent div within which elements are added dynamically. I want to find out the class of the element which was clicked, if none of the child element was clicked but parent was clicked then I would like to get the class of parent element.
$(document).ready(function() {
$('.parent').on('click', function(event) {
// event.stopPropagation();
alert($(this).attr('class'));
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class='parent'>Parent//clicking here should alert parent
<ol>
<li class='type1'>NEW</li>//clicking on this should alert type 1
</ol>
</div>
try this:
$(document).ready(function() {
$('.parent').on('click', function(event) {
// event.stopPropagation();
alert($(event.target).attr('class'));
});
});
this will get the target tag of the clicked position.
see the DEMO

Categories