Ignore parent onclick when child onclick is clicked, using Javascript only - javascript

An good example of what im trying to do is, think of instragram. When you are click on a photo, it opens a window with that photo plus the grey background. If you click anywhere in the grey background the picture is closed, however if you click on the picture the picture remains in the window.
This is what I am trying to achieve with this:
<div class="overlay_display_production_list_background" id="overlay_display_production_list_background_id" onclick="this.style.display = 'none'">
<table class="table_production_availability" id="table_production_availability_id" onclick="this.parentElement.style.display = 'block'">
</table>
</div>
However this doesnt work. how do I get this working, I only want Purely java-script.
Thanks

Avoid intrinsic event attributes (like onclick). Bind your event handlers with JavaScript. Take advantage of the event object to prevent further propagation of the event up the DOM (so it never reaches the parent and thus doesn't trigger the event handler bound to it).
document.querySelector("div").addEventListener("click", parent);
document.querySelector("div div").addEventListener("click", child);
function parent(event) {
console.log("Parent clicked");
}
function child(event) {
event.stopPropagation();
console.log("Child clicked");
}
div {
padding: 2em;
background: red;
}
div div {
background: blue;
}
<div>
<div>
</div>
</div>

You perhaps can take an inner div which is absolute that has the background and certain height and width which is equal to main parent div and that has all the style, so on click of that div you may close parent div and on image you need not to do anything.
<div Parent><div Childdiv>
</div>
<img>
</div>
So childdiv should have display none functionality.
With JavaScript, you should be able to close parent div on a click of child div.

Related

How to make the whole div clickable?

I have a div with contents in it:
<div class="block">
<img src='...'>
<span>...</span>
</div>
I set up a JavaScript Event Listener when someone clicks on the div:
document.body.addEventListener("click", function(e) {
if (e.target.tagName === 'DIV' && e.target.classList.contains("block")){
(code)
}
}
It works when I click on the area of ​​the div that has no content. But it doesn't works, when I click to the image or to the text.
How can I get this at the whole div working?
The event.target is the element you clicked on. If you do not directly click on the div then your code will not match your tests because you are clicking on a child element.
So when you are using event delegation and you want to know if an element or one of its children is clicked on, you need to walk up the tree to see if it is that element. You can do that with closest
document.body.addEventListener("click", function(e) {
if (e.target.closest('div.block')) {
console.log('clicked', Date.now());
}
});
<h2>Example</h2>
<div class="block">
<img src='http://placekitten.com/g/200/300'>
<span>foo bar kitten</span>
</div>
Try to give an id to div and add your event listener to that.
<div id="myDiv" class="content">
// your content goes here
</div>
And in javascript
const myDiv = document.getElementById("myDiv");
myDiv.addEventListener("click", (event) => {
// your function goes here
})
There are many ways you can do it. But In my opinion the best way is to make anything clickable in JS is use onClick() function. You can simply use onClick=functionName()
function changeBackground(){
let block = document.getElementsByClassName('block');
block[0].style.backgroundColor = "green";
}
.block{
height: 50px;
border : 1px solid;
}
<div class="block" onClick="changeBackground()">
<div>
welcome to SO. You can add the event listener on the div itself and then perform whatever code you like. The reason it doesn't work in your case is because you are adding the event listener to the whole body and thus as the event handler is called, it doesn't recognize the elements you are clicking on even if they are inside the div.
Try this instead:
document.querySelector('div#block').addEventListener("click", function(e) {
// code...
});

Onclick event not works after "show" class added to parent div

I have two screens on the page. Every screen has 5 tables, there is only one table that can be seen. I want to change the visible table with these buttons. There are 2 buttons (previous, next) for each screen.
Here is my Javascript code to buttons:
document.querySelector('.screen.show .screen-table-buttons .next').onclick = function(){
...
}
This code works when the page is loaded the first time, but when added the show class to other screens, and I want to use it, it's not working. I want to use these buttons when the screen parent has a show class.
I changed the show class, added it to other screens, reloaded the page, and then other buttons worked on the other screen, but the first buttons didn't work.
So, I just want to use all buttons when the div parent has the show class. If the parent does not have the show class, don't work, If has it, just do it.
As mentioned in the comments this is a good case for event delegation - a single listener is attached to the document (or relevant ancestor) and functions are called based on target attributes.
Here it is attached to the document and it first checks if the clicked target has an ancestor with class screen.show using closest() if it does we check the classList of the target using classList.contains() to trigger the relevant function call.
function next_fn() {
console.log('next');
}
function previous_fn() {
console.log('previous');
}
document.addEventListener('click', (event) => {
if (event.target.closest('.screen.show')){
if (event.target.classList.contains('next')) {
next_fn();
}
if (event.target.classList.contains('previous')) {
previous_fn();
}
}
});
<div class='screen'>
<h6>Screen no-show (buttons won't trigger)</h6>
<button type='button' class='next'>Next</button>
<button type='button' class='previous'>Previous</button>
</div>
<div class='screen show'>
<h6>Screen show (only these buttons work)</h6>
<button type='button' class='next'>Next</button>
<button type='button' class='previous'>Previous</button>
</div>
<div class='not-screen'>
<h6>Not-screen (buttons won't trigger)</h6>
<button type='button' class='next'>Next</button>
<button type='button' class='previous'>Previous</button>
</div>
As Teemu said in the comment, the way you're binding the click event means that you're binding the click event to the button that is already visible (i.e. the one that has the show class at the moment the line you've put in the question is hit) - it isn't designed to cater for elements that may or may not exist at some point in the page lifecycle.
You'll either need to rebind the click event each time you switch the show class, or you can bind the event regardless of the show class.
In order to rebind the event each time, you'd be better off pulling the function out into its own area - something like this:
document.querySelector('.screen.show .screen-table-buttons .next').onclick = NextClicked
function NextClicked() {
... do the normal click event stuff, and move the show class to the other screen
document.querySelector('.screen.show .screen-table-buttons .next').onclick = NextClicked
}
Alternatively, you could bind the click event once and do a check to see whether the one clicked is the right one - something along these lines:
document.querySelector('.screen .screen-table-buttons .next').onclick = function(e){
if (e.target.parentElement.parentElement.hasClass('show')){
...
}
}

jquery show/hide not working for dynamically created div

I have a checkbox which will allow the users to show/hide certain features. So I have 2 divs with separate IDs and one div is added directly to my code and the second div is dynamically added through a plugin with the CSS display:none.
$(function() {
$("#chkstatus").click(function() {
if ($(this).is(":checked")) {
$("#dv").show();
$("#Add").hide(); //dynamic div
} else {
$("#dv").hide();
$("#Add").show(); //dynamic div
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="dv" class="forgo">
<h1>Benefits</h1>
<p></p>
</div>
<!-- The below code is not visible in the page source but visible in inspect element -->
<div id="Add" class="form-group" style="display:none">
<input class="btn-block button" type="button" style="" value="Upload File">
</div>
The problem is that the show/hide is working perfectly to the #dv but nothing happens to #Add. It always stays hidden.
Can someone let me know how can make the show/hide work for the dynamically added div?
Instead of binding the event listener to the dynamically created div you should add an eventlistener on the parent (say <div id='cont'></div> ) which is ofcourse static in nature .
Say the event we are listening to is click, now whenever you click the parent you have the reference to the specific div (even if there a lot of dynamic divs like this) as a target attribute of the event. which you can find by digging the output in console log.
Why and How ??
This is because of event delegation and event bubbling i.e. the event bubbles up to the parent div and keep on bubbling up to the body in DOM tree.
So for this case, as the event is click( checkbox ) which is on some different element (no parent child relation with dynamically added div) so we can use trigger to fire our own custom event on the parent div.
$(document).ready(function () {
$("#cont").on('myEvent1',function(){
$(this).find('#dv').show();
$(this).find('#Add').hide();
});
$("#cont").on('myEvent2',function(){
console.log($(this)); // This will o/p the #cont div containing both the static and dynamic div in it.
$(this).find('#dv').hide();
$(this).find('#Add').show();
});
$("#chk").change(function () {
if ($(this).is(":checked")) {
console.log($(this)); // This will o/p the checkbox element
$("#cont").trigger('myEvent1');
}
else {
$("#cont").trigger('myEvent2');
}
});
});
You can try to mold it for your exact purpose and can also use toggle to reduce the LOC.

JQuery: How to fire click event on hidden element?

I want to create a flashing effect. When user click the flashing element, it will be disappeared. However, it seems not every "user's click" can fire the "click event". Sometimes, when I clicked the flashing element, it didn't disappear. I thought the reason is a hidden element can not be clicked. Just like this article says CSS: Is a hidden object clickable?. So, is there other methods to make the flashing element disappeared immediately when user clicks the element?
var flashToggle = setInterval(function() {
$("div").toggle();
}, 200)
$("div").on("click", function(e) {
clearInterval(flashToggle);
$(this).hide();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>Flashing element</div>
Put the flashing element inside another element, and put the handler on that parent element. Also, you might change the visibility property of the flashing element, not the display of the flashing element, so that it doesn't change the layout of your page every time it appears or disappears.
const child = $('#child');
let visible = true;
var flashToggle = setInterval(function() {
visible = !visible;
child.css('visibility',
visible
? 'visible'
: 'hidden'
);
}, 500)
$("#container").on("click", function(e) {
clearInterval(flashToggle);
$(this).hide();
})
div {
background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<div id="child">Flashing element</div>
</div>
Yes, hidden/toggle will hide elements by setting the css display. When hidden, elements can not receive clicks. You can try the following:
Use .css('visibility','hidden|visible') instead. This is recommended as it does not have the side effect of changing container size and causing jiggling of other elements.
Wrap your flashing element inside a container element, register the click on the container element instead.
$(this).hide(); ---> $("div").hide();
I think this might be what you're looking for: $("my-element").click()
Try to use opacity : 0|1 instead of display: none / visibility: hidden.
On click event on opacity: 0 worked for me.
It worked for me.

Jquery - Prevent click event from being triggered through an overlying layer

.PopBgd is 100% of the screens size with another div .PopUp contained within .PopBgd and appearing on top of it.
Clicking on .PopBgd gives the desired effect of Hiding. However clicking anywhere in PopUp also runs the fadeOut part of the script below.
QUESTION
How to prevent the fadeOut part of the script from triggering though overlying divs?
$('.BtnPop').click(function(e) {
e.preventDefault();
$($(this).data('popup')).fadeIn();
$('.PopClose, .PopBgd').click(function() {
$('.PopBgd').fadeOut();});
});
ANSWER
<button type="button" class="BtnPop" data-popup=".Pop1">CLICK</button>
<div class="Pop1 PopBgd">
<div class="PopUp">
<a class="PopClose">×</a>
<div>Content</div>
</div>
</div>
$('.BtnPop').click(function(e) {
e.preventDefault();
$($(this).data('popup')).fadeIn();
});
$('.PopClose, .PopBgd').click(function() {
$('.PopBgd').fadeOut();});
$('.PopUp').click(function(e) {
e.stopPropagation();
});
NEW QUESTION
How to use StopPropogation when the target div's name is unknown?
What I have tried above does not work.
I resolved my additional problem by simply adding a second class name that was static to the desired div to allow stopPropogation to work as normal.
$('.Pop').click(function(e) {
e.stopPropagation();
});
.stopPropagation() "Prevents the event from bubbling up the DOM tree, preventing any parent handlers from being notified of the event."

Categories

Resources