css+js: div click (and elements inside it) - javascript

I'm trying to build a (semi-transparent) overlay that covers all on a web page.
Similar to this: http://www.jankoatwarpspeed.com/use-jquery-to-turn-off-the-lights-while-watching-videos
<div id="overlaySplash" onclick="clickHandler(this)">
<div id="insideBox">
[ label elements here with onclick="dosomething()" ]
</div>
</div>
css
#overlaySplash {
position: absolute;
top: 0;
left: 0;
bottom:0;
right:0;
background: rgb(50, 50, 50);
background: rgba(0, 0, 0, .50);
z-index: 50;
}
#insidebox {
position: absolute;
z-index: 100;
left: 15%;
right: 15%;
bottom: 5%;
line-height: 50px;
text-align: left;
}
The problem is that I'm not using jquery and the overlay div will have some clicable contents on int. I have this function below but when I click on elements inside the main overlay div JS will return e.id as being the overlay div itself, not the clicked element. This way I can't tell where the user really clicked.
function clickHandler(e){ //hide the div overlaySplash
e = e || event;
alert(e.id);
}
THE BOTTOM LINE:
user clicked an label inside the div: dosomething();
user clicked the background (the DIV itself): closeOverlaySplash();

I don't think you need to completely stop propagation as it may serve some purpose later on. It might be easiest to create a separate js & css files that encompass this functionality for ease of use.
The issue you have is basically the event is bubbling up to the parent when it isn't currently needed. You can easily check the event.target.id to see if the parent was clicked or not. With this you can make sure the overlay was clicked vs the content.
eg:
if (event.target.id == "overlay") {
//hide the overlay
}
JSFiddler

Like this:
HTML
<div id="overlaySplash" onclick="clickHandler(event);">
<div id="insideBox" onclick="clickHandlerInner(event);">Inner</div>
</div>
JS
function clickHandler(event) {
alert("no");
}
function clickHandlerInner(event) {
if (!event) var event = window.event;
event.cancelBubble = true; //IE
if (event.stopPropagation) event.stopPropagation()
alert("yes")
}
jsFiddle

Related

Click outside of Div to close it. SVG & D3, Angular

I want to click anywhere outside of my div to hide it.
I have an svg background which on top of that has a graph with nodes.
I click on a node(circle) on my SVG and if this particular 'extra' node is clicked then I have a box appear, I show the box with:
d3.select('#rightBox')
.attr('hidden', null);
d3.select('#leftBox')
.attr('hidden', null);
d3.select('#headerDiv')
.attr('hidden', null)
d3.select('#headerText')
.attr('hidden', null)
This is because the div is hidden on load. Im not using the css display property because it wasn't working!
The problem is when i try angular (click) = "functionThatHidesTheDiv" on the body and hide the elements, of course because the circle nodes are part of the body then the box never gets opened?
I use angular too. once the element is not hidden, how can i click anywhere on the svg excluding the div itself to hide it?
you need to check if the 'target' of your click event is the div, or is inside of it.
Maybe something like that ?
const svg = document.querySelector('.svg');
const circle = document.querySelector('.circle');
svg.addEventListener('click', (e) => {
if (!(e.target === circle) && !circle.contains(e.target)) {
console.log('Click outside');
} else {
console.log('Click inside');
}
});
.svg {
display: flex;
justify-content:center;
align-items: center;
width: 400px;
height: 400px;
background-color: tomato;
}
.circle {
width: 50px;
height: 50px;
border-radius: 50%;
background-color: tan;
}
<section>
<div class="svg">
<div class="circle"></div>
</div>
</section>

Closing div when clicking outside of div not working on iPhone. Works fine on Mac/PC and Android

Here is the div(s). Depending on what button is clicked, one of them will appear on the screen.
var box;
var value;
var wrapper = $('.wrapper');
$('body').on('click', '#login, #register', function() {
if ($(this).attr('class')) {
value = $(this).attr('class')
} else {
value = $(this).attr('id')
}
switch (value) {
case 'login':
box = $('.loginBox');
break;
case 'register':
box = $('.registerBox');
break;
}
box.closest(wrapper).toggleClass('open');
$('input:text', box).first().focus();
});
// this successfully closes the div when I click outside of it (on Mac/PC & Android, however it does not close the div on iOS)
$('body').on('click', '.wrapper', function() {
box.closest(wrapper).toggleClass('open');
});
$('body').on('click', '.wrapper div', function(e) {
e.stopPropagation();
});
.wrapper {
position: fixed;
top: 0;
bottom: 0;
right: 0;
left: 0;
background: rgba(0, 0, 0, 0.1);
display: none;
z-index: 300;
}
.open {
display: block;
}
.blackBox {
position: absolute;
left: 50%;
top: 41%;
height: 340px;
width: 500px;
z-index: 997;
margin: 0 auto;
transform: translate(-50%, -50%);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="blackBox">
<div class="loginBox">
...
</div>
</div>
</div>
<div class="wrapper">
<div class="blackBox">
<div class="registerBox">
...
</div>
</div>
</div>
The 2nd function, (the toggle when clicking outside the div) successfully closes the div when I click outside of it (on Mac/PC & Android, however it does not close the div on iOS)
Is there another method I can perform for iOS?:
$('body').on('click', '.wrapper', function(){
if (/iPhone|iPod|BlackBerry/i.test(navigator.userAgent)) {
// another method
}
box.closest(wrapper).toggleClass('open');
});
iStuff will only acknowledge a click event if the element is clickable. One of the conditions to make it clickable is to give it
cursor:pointer;
If that's not an option, you could use tap:
$(containerSelector).on('click tap', targetSelector, function(event) {
// have you finished that webpage already?
})
Yet another option is to use touchstart. But I personally think that's a mistake. touchstart is triggered whenever a touch event is started, whether it's a swipe, a multi-touch zoom or whatever other fancy gestures your device might recognize.
Most times, when you want to swipe, pan, zoom, you don't want click functionality to trigger. tap is the most click-like event in the world of touch gestures.
In the particular case of a dropdown, you don't want it closing on gestures aimed at better positioning it on the screen or zooming in on the area in which it opened.

How to close a side bar when i pressed anywhere

What I want to do is to dismiss the sidebar when I press anywhere on the screen.
How can it be done? How can I make it so that when I hover over my image, my text would appear instead of it being visible the whole time?
function openNav() {
document.getElementById("mySidenav").style.width = "300px";
document.getElementById("toggle").style.position = "static";
}
function closeNav() {
document.getElementById("mySidenav").style.width = "0";
document.getElementById("toggle").style.marginRight = "0";
document.getElementById("toggle").style.position = "relative";
}
#toggle {
position: relative;
left: 400px;
font-size: 1.2em;
visibility: visible;
}
#toggle:hover {
color: white;
transition: 0.5s;
}
.sidenav {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
right: 0;
background-color: transparent;
overflow-x: hidden;
transition: 0.5s;
padding-top: 50px;
}
.sidenav a {
text-decoration: none;
font-size: 25px;
color: #818181;
display: block;
transition: 0.3s;
}
.sidenav a:hover,
.offcanvas a:focus {
color: #f1f1f1;
}
.sidenav .closebtn {
position: absolute;
top: 0;
right: 25px;
font-size: 36px;
margin-left: 50px;
}
<div>
<ul id="topBar">
<li id="ixora">Ixora</li>
<li class="lists">2014</li>
<li class="lists">2015</li>
<li id="toggle" onclick="openNav() ">☰</li>
</ul>
</div>
<div id="mySidenav" class="sidenav">
×
<span class="textImage">Outing</span>
<img src="outing.jpg">
<span class="textImage">Prom Night</span>
<img src="prom.jpg">
<span class="textImage">PortDickson Trip</span>
<img src="pd.jpg">
<span class="textImage">Merdeka</span>
<img src="merdeka%20(2).jpg">
</div>
I honestly think you should be using jQuery here as it's fantastic for DOM manipulation. If for some reason you have to use vanilla js then it's going to be a little trickier.
Adding jQuery to your project is easy and well explained on the jQuery site. Here;s a comparison of selecting an element in js/jquery:
Vanilla JS:
document.getElementById("mySidenav")
jQuery:
$('#mySidenav')
To get things to happen when events happen (i.e. button press, or clicking away from a menu) you set up event handlers.
It's hard to picture from your code as there seems to be CSS missing for #topBar so I can't see your site very well (here's your code running in jsfiddle).
But lets say you have a button with ID of #openToggle. You would set up your sideNav in css with the correct width, height, etc, and leave it as display: none. Then we create an event handler to do something when you click that button:
//event handlers go at the bottom of your js file or script tag
$('#openMenu').on('click', openMenu);
That example is basically saying when the element with ID 'openMenu' is 'clicked' the run the 'openMenu' function - simple! :)
The openMenu function would look something like (basic example):
function openMenu() {
var $menu = $('#sideNav');
$menu.show();
};
A better way would be to have a toggle function that toggles the menu based on whether it's already open or closed:
function toggleMenu() {
var $menu = $('#sideNav');
if (($menu).is(':visible')) { //if it's visible
$menu.hide(); //hide the menu
} else { //else it's hidden
$menu.show(); //so show it
}
};
// event handler for menu toggle button
$('#menuToggle').on('click', toggleMenu);
With regards to closing the menu when you click away from it, you could bind an event handler to the body of the page and use jQuery's .one() function (runs only once) which will detect if the body is clicked and then run the menuToggle funtion - you'd end up with 2 handlers for this:
// event handler for menu toggle button
$('#menuToggle').on('click', toggleMenu);
$('body').one('click', toggleMenu);
Alternatively you could have the menu close when your mouse pointer leaves the menu?:
//event handlers
$('#menuToggle').on('click', toggleMenu);
$('#sideNav').mouseleave(toggleMenu);
The mouseleave handler is basically saying, once the mouse pointer leaves the element with ID of 'sideNav' then run the toggleMenu function.
I'm a newb too so my examples may not be great, but I hope I helped at least a little. Hopefully some real javascript devs will be along shortly to add to this or give better examples.
Cheers,
Dave
JQuery
$( document ).onclick(function() {
$("#mySidenav").hide();
}
Reference documentation:
JQuery .on
JQuery .hide
With javascript, you can do the following:
document.onclick = function(e){
if(e.target.id == "mySidenav"){
return false;
}
closeNav();
}
I see that you already have functions to open and close your sidebar,
clicking "anywhere" is the same as "clicking on the body", But I guess that you don't want your sidebar to close when you're clicking on it.
So, here's what you can do :
var myNav = document.getElementById("mySidenav");
myNav.onclick = function(e) {
e.stopPropagation();
}
document.body.onclick = function(e) {
closeNav();
}
So, when you click on your sidebar, you won't click on the body because the event propagation is stopped, and when you click elsewhere, it will close your sidebar.
Hope it helps,
best regards

How to enable javascript mouse events on overlapping html elements?

This probably cannot be done, but I have a fixed-position div on top of inline html in the page body. The inline html has clickable elements, and the fixed div has a hover event.
The fixed element is an empty div, so it is invisible.
Currently, the fixed element is blocking click events on the item under it.
Is it possible?
This solution is too complicated
https://stackoverflow.com/a/9616491/209942
Possible solution?
https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events
Thx
The fixed element should not be prevent the clicks from the item under it unless you are stopping the event propagation.
See this fiddle: https://jsfiddle.net/pv0mygz5/
-- it demonstrates that without event.stopPropagation the event should be intercepted by the listener on the span element.
$('#click-me').on('click', function (e) {
console.log('click triggered');
});
$('.box').on('mouseover', function (e) {
//don't stop event from bubbling
console.log('hover triggered');
});
Could you also include a code snippet that demonstrates your problem?
although IE10 doesn't support it you can use
pointer-events: none;
http://jsfiddle.net/leaverou/XxkSC/light/
In this fiddle you can see a drop down being covered with other elements, the other elements has pointer-events: none so you can click on the arrow down button and the click actually goes to the select element itself.
BR,
Saar
You can also try using z-index. Depending on your layout it may not be a solution, but if your front div is invisible, then it shouldn't create unwanted effect. Like this for example:
document.querySelector('#under').addEventListener('click', function(e) {
e.target.style.color = "blue";
});
document.querySelector('#notunder').addEventListener('click', function(e) {
e.target.style.color = "blue";
});
#fix {
width: 60px;
height: 200px;
position: fixed;
z-index: -1;
top: 0px;
border: 1px solid black;
}
#under {
display: inline;
}
#fixnozindex {
width: 100px;
height: 200px;
position: fixed;
left: 75px;
top: 0px;
border: 1px solid black;
}
#notunder {
display: inline;
}
<div id="fix"></div>
<div id="under">Clickable</div>
<div id="fixnozindex"></div>
<div id="notunder">Not clickable</div>

Firefox like inspecting element

I am building my website with inspecting elements option to inspect each elements separately like firebug. I like to built the styles like newer version of Firefox which will blur all the elements except the selected element. Any idea on how to do this? The example of the needed output is given below.
EDIT : Please note that, here the element i need to select may have lower DOM hierarchy than the other elements. For eg. i may need to gray out the body container and if i select some internal elements which should not have the grey effect.
Something like this:
http://jsfiddle.net/lollero/T7PyK/
Clicking any element will show overlay and isolate the element.
Clicking overlay will undo that.
JS:
$('*').on("click", function( e ) {
e.stopPropagation();
var self = $(this),
overlay = $('#overlay');
if ( !self.hasClass('active') ) {
if ( self.is(':not(#overlay)') ) {
self.addClass('active');
}
overlay.fadeTo(400, 0.7);
}
if ( self.hasClass('active') ) {
overlay.on("click", function() {
overlay.fadeOut(400, function() {
self.removeClass('active');
});
});
}
});
​
CSS:
#overlay {
display: none;
background: #000;
position: fixed;
z-index: 100;
top: 0px;
right: 0px;
bottom: 0px;
left: 0px;
}
.active {
position: relative !important;
z-index: 101 !important;
background: #fff;
box-shadow: 0px 0px 50px #111;
}
​
HTML:
<div id="overlay"></div>
Put a div with a background color of black, 100% width/height, absolute positioning and left/top of 0, and an opacity of somewhere between 0 and 1 (eg. 0.5). That gives you the "gray out the page effect".
Then, put the text that you don't want grayed out in a separate div that's higher in the DOM hierarchy (or at the same level but with a higher z-index), so that it won't get covered up by your graying-out div.
You can use jQuery overlay effect along with some CSS..
hit this link: http://tympanus.net/codrops/2009/12/03/css-and-jquery-tutorial-overlay-with-slide-out-box/

Categories

Resources