Hiding div with Javascript - javascript

I'm trying to hide a div when the user clicks anywhere outside of the div with id "main".
I am using vanilla Javascript and would prefer not to use jQuery.
The code I have works well but whenever the user clicks inside sub-child div or any text, it also hides the div, which is not the behavior that I want.
window.addEventListener('mouseup', function(event){
var box = document.getElementById('main');
if (event.target != box && event.target.parentNode != box){
box.style.display = 'none';
}
});
<div id="main" style="display: block; background-color: grey;">
<div id="one1">
<div id="one2" style="background-color: red;"><p>when click here should not hide<br><br>when click here should not hide<br>when click here should not hide<br>when click here should not hide</p></div>
</div>
<div id="one3"><p>when click here should not hide</p></div>
</div>
<p>when click here should hide</p>
<div id="xyz" style="background-color: green;"><p>when click here should hide</p></div>
<p>when click here should hide</p>

Hi, hopefully I've understood your question correctly.
When you click on the green and transparent lines you want to hide everything? Or just the div 'main'?
Currently your javascript is adding an event listener 'mouseup'. The event listener's function has an if statement checking to see if you target the 'main' div. The elements that you want to activate the function when clicked, are not in the main div. Your DOM tree is not organised correctly!
I've taken the liberty to adjust your code slightly to what I think you wanted to achieve... Here is a jdFiddle.
jsFiddle
You can also combine the event listener and getElementById with this line of code:
document.getElementById('clickToHide').addEventListener('mouseup', function(event){
This may be an easier method for you to make sure you are pointing to the correct div. Let me know if I got the wrong end of the stick.

You can add a separate listener on the Main div to stop propagation of that event:
window.addEventListener('click', function(event){
var box = document.getElementById('main');
box.style.display = 'none';
});
var box = document.getElementById('main');
box.addEventListener('click', function(event) {
event.stopPropagation();
});
Fiddle: https://jsfiddle.net/jaredk/bu5cjh9v/
This is from an answer here, but that one uses jQuery.

Related

How to block click event for the parent element in jQuery?

I'm developing a web page using jQuery. In this web page, there is a div tag that contains a p and a button tag.
The HTML code is like this:
<div class="container">
<div id="attribute" style="border:solid;border-width:2px;border-color:#ccc">
<p id="cell-content" style="display:inline">Id</p>
<button id="remark-view" class="btn btn-primary">Detail</button>
</div>
</div>
and the corresponding JavaScript code is like this:
$(document).ready(function(){
$("#attribute").on('click', function(){
console.log("click on the div attribute");
});
$("#attribute").on('dblclick', function(){
console.log("double click on the div attribute");
});
$("#remark-view").on('click', function(){
console.log("click on the button remark-view");
});
});
As the code shows, a outer div has a p and button child element, and the outer div element listens on the single click and double click event while the inner button element listens on the single click event.
When I run the code in my browser and click on the button, the console shows that both click functions of the outer div and inner button element are called, which is against my purpose: only the click function of inner button should be called at this situation. Thus, is there any way to block the click event for the father element(in this case, outer div element).In other words, is there any way to stop passing the click event to the father element after the child element has handled it?
Thank you in advance!
stopPropagation function will stop the event from bubbling up the DOM.
$("#remark-view").on('click', function(event){
console.log("click on the button remark-view");
event.stopPropagation()
});
From the jQuery documentation
Prevents the event from bubbling up the DOM tree, preventing any
parent handlers from being notified of the event.
This is something I use in one of my sites to do something similar to your problem. What the below code does is it prevents the middle div from closing if the button click is on that div.
//Function for the pop up with the background dimmer
$(document).mouseup(function(x) {
var container = $("#divContent"),
dimmer = $('#bgDimmer');
if (container.is(":visible")) {
if (!container.is(x.target) //check if the target of the click isn't the container...
&& container.has(x.target).length === 0) {
container.hide();
dimmer.hide();
}
}
});
Let try to relate to your code.
//Function for the pop up with the background dimmer
$(document).mouseup(function(x) {
var attribute = $('#attribute');
if (attribute.is(":visible")) {
if (!attribute.is(x.target) //check if the target of the click isn't the container...
&& attribute.has(x.target).length === 0) {
console.log("click on the button remark-view");
}
}
});

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

Disable contextmenu for a specific container and its children

I need to disable contextmenu only inside a specific div #wrapperand its children, and not the whole page. This is what I'm doing:
document.addEventListener('contextmenu', function (event) {
console.log(event.target.id);
if (event.target.id === 'wrapper') {
event.preventDefault();
}
});
.. but it doesn't seem to work.
You're approaching this the wrong way: you're adding the listener to the document, which may be ok, but it's easier to add it to the element itself, and you are checking event.target.id, which is the ID of the current clicked element (e.g. a children of your wrapper), not the wrapper.
To make this work you can easily do something like this instead:
var myWrapper = document.getElementById('wrapper');
myWrapper.addEventListener('contextmenu', function(e) {
e.preventDefault();
}, true);
This is a solution that work fine
<div id="wrapper" oncontextmenu="return false">
#wrapper
<div class="childds">
</div>
The code you have in your question works perfectly. One possibility of why the context menu still showed up is that you in fact clicked on a child of #wrapper, instead of clicking on the element itself:
HTML
<div id="wrapper">
#wrapper
<div class="inner">
#wrapper .inner
</div>
</div>
Working example demonstrating this issue on JSFiddle.
You can overcome this by attaching the event handler to the desired element directly instead. This way, right-click events on child-elements will bubble up to #wrapper, and thus fire the event as expected:
JavaScript
document.getElementById('wrapper').addEventListener('contextmenu', function (event) {
event.preventDefault();
});
Working example on JSfiddle.

Void JS Click in Pop-up area of "lightbox"

I'm making a super simple "lightbox" that pops up with a dialog box, and a dimmed background.
My problem is, I want the overlay to disappear when the user clicks on the dimmed background, but not if they click in the dialog box area.
My approach so far has been this:
I added a class with "display:none;" to the the wrapper so it would disappear if clicked. Of course, if you click in the #dialogBox this makes the overlay disappear as well. Is there any way to tell it to return the click false in the dialogBox area? Or a better way to approach this?
<div id="overlay" onclick="$(this).addClass('displayNone');">
<div id="dialogBox">
<p>Lorem ipsum</p>
</div>
</div><!-- /#overlay -->
Thank you!
Remove the inline onclick attribute/handler, and bind the event in JavaScript:
$("#overlay").on("click", function (e) {
if (!$(e.target).closest("#dialogBox").length) {
$(this).addClass('displayNone');
}
});
DEMO: http://jsfiddle.net/A7rNE/
This will check if the click came from anywhere within the #dialogBox element - if it didn't (note the ! in the if statement), it runs the .addClass() part.
References:
.on(): http://api.jquery.com/on/
.closest(): http://api.jquery.com/closest/
This should prevent the click event from bubbling up to whatever element handles closing the lightbox:
$('#dialogBox').click(function(e) {
e.stopPropagation();
})

Div slide up when click in items inside it

I have a div that slides down (opens) when I click a certain input select. Inside this div, I have some other input selects and my objective is to slide up the div when I click on the rest of the page.
My problem:
The div slides up when I select some item in the input selects inside it, and I don't want this to happen.
Is there some way to slide up the div only when I click outside it?
Why are the selects inside the div making it to slide up as well?
This is my javascript to slide up the div:
$(document).mouseup(function (e) {
var container = $('.myDiv');
if (container.has(e.target).length === 0) {
$(container).removeClass('close');
$(container).addClass('open');
$(container).next().slideUp(200);
}
});
The div slides up when I select some item in the input selects inside
it, and I don't want this to happen.
Is there some way to slide up the div only when I click outside it?
Why are the selects inside the div making it to slide up as well?
Use event.stopPropagation() on the child element(s) to prevent the slide event being triggered by them.
event.stopPropagation - Prevents the event from bubbling up the DOM
tree, preventing any parent handlers from being notified of the event.
Here's a simple jsFiddle and the basic example below.
jQuery:
$('div').click(function(){
$('#slideMeUp').slideUp();
});
$('select').click(function(e){
e.stopPropagation();
});
HTML:
<div>Clicking here will trigger it!
<select>
<option>This won't trigger the click event anymore!</option>
</select>
Clicking here will also trigger it!
</div>
<div id="slideMeUp">Only clicking the outer div will slide me up!</div>
you can check you e.target.id with your container id
$(document).mouseup(function (e) {
var container = $('.myDiv');
if(e.target.id==$(this).attr('id'))
{
if (container.has(e.target).length === 0) {
$(container).removeClass('close');
$(container).addClass('open');
$(container).next().slideUp(200);
}
}
});
If it's specific items that are causing problems, perhaps something like this?
On click tell it to to slideUp your div as long as the clicked item is "not" in the list.
('body').click(function(event) {
if (!$(event.target).is('#id_of_item .class_to_ignore')) {
var container = $('.myDiv');
$(container).removeClass('close');
$(container).addClass('open');
$(container).next().slideUp(200);
}
});
I'd suggest binding mousedown rather than mouseup. There are inconsistencies in behaviour between browsers, this may have something to do with your issue.
You should also add some logic to check the clicked element isn't the div itself, clicking just outside of an input, but still inside of the div would currently cause the slideUp to occur.
if (!container.has(e.target).length && !container.is(e.target)) {
...
}
Other than that, it should work fine.
Have a fiddle

Categories