If only div 1 is clicked, play sound - javascript

In my project, I have a big div, and there is another div in that div as a shape.
When you click the shape, you did right and you have 1 point. When you click only the background div, I want to play a sound.
When I do (simple example):
var $audioLifeLost = new Audio('Mis.mp3');
#divid.onclick = function (){
$audioLifeLost.play();
}
it also plays the sound when I hit the shape because I hit both div's at the same time.
Anyway how can I do it?

You need to stop the event from propagating up to the parent:
document
.querySelector('#inner')
.addEventListener('click', e => {
console.log('click inner');
e.stopPropagation(); // <-- stop event propagation
})
document
.querySelector('#outer')
.addEventListener('click', () => {
console.log('click outer');
})
#outer {
background: pink;
height: 300px;
width: 300px;
display: flex;
align-items: center;
justify-content: center;
}
#inner {
background: salmon;
width: 150px;
height: 150px;
}
<div id="outer">
<div id="inner"></div>
</div>

document.getElementById("divid").onclick = function (e) {
if (e.target == document.getElementById("divid"))
$audioLifeLost.play();
}

Related

Open a div by clicking and close by clicking outside of it

A div is initially hidden, I want to display it when clicking a button. And once it is visible, I want to hide it when clicking anywhere outside that div.
I'm trying following code, it displays the div, but the problem is in the second part (clicking outside) the box. The second part conflicts with first one so it hides it before displaying.
How can I fix that?
$('button').on('click', function(e){
e.preventDefault();
$('.box').addClass('active');
});
//hide is by clicking outside .box
$(document).on('click', function (e) {
if ($('.box').is(':visible') && !$('.box').is(e.target) && !$('.box').has(e.target).length) {
$('.box').hide();
}
});
button {
margin-bottom: 20px;
}
.box {
width: 200px;
height: 120px;
background: #fab1a0;
display: none;
}
.active {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>Click</button>
<div class="box"></div>
You can stop the propagation of your event so that when button is clicked the event doesn't bubble up to the document. Also instead of hide(), just using removeClass(...) should work for you.
Also that event propagation doesn't stop in this button listener itself but from the next event listener which in your case is on the document and that is what we require.
$('button').on('click', function(e){
e.stopPropagation();
$('.box').addClass('active');
});
//hide is by clicking outside .box
$(document).on('click', function (e) {
if ($('.box').is(':visible') && !$('.box').is(e.target) && !$('.box').has(e.target).length) {
$('.box').removeClass('active');
}
});
button {
margin-bottom: 20px;
}
.box {
width: 200px;
height: 120px;
background: #fab1a0;
display: none;
}
.active {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>Click</button>
<div class="box"></div>

When I click outside the `<html>`, why does it trigger the click event bound on `<html>`?

const html = document.querySelector('html')
const body = document.querySelector('body')
body.onclick = () => {
console.log('body clicked')
}
html.onclick = () => {
console.log('html clicked')
}
document.onclick = (e) => {
console.log('document clicked')
}
window.onclick = () => {
console.log('window clicked')
}
html {
width: 500px;
height: 500px;
border: 20px solid red;
margin-left: 100px;
margin-top: 100px;
}
body {
width: 300px;
height: 300px;
border: 20px solid green;
}
<div></div>
I have assigned a fixed width and height to the <html>(See the red box in the figure above.), When I click outside the red box, why does it trigger the click event bound on <html>?
When I click outside the red box, why does it trigger the click event
bound on ?
You've really clicked outside the red box, but it still relates to html tag. It means: the position where you're clicking on, it's still inside html tag.
You can use Dev tools to check that:
By hovering on html tag, you will see the real width/height of html tag is still full of the page.

Toggle won't stay open

I have images (.rv_button) that are acting as buttons to toggle the div's below (#reveal). I want to hover over the button to open the div but right now I can't get the div to stay open. Can someone help me with this?
jQuery(document).ready(function() {
// Hide the div
jQuery('#reveal').hide();
jQuery('.rv_button').on('mouseenter mouseleave', function(e) {
e.preventDefault();
jQuery("#reveal").fadeToggle()(slow, swing, callback);
jQuery('.rv_button').toggleClass('open');
});
});
Rather than using toggleClass(), on mousenter, remove the open class from all of the buttons and add it to e.target or $(this). And on mouseout just remove it from all the buttons.
Also, remove (slow, swing, callback) or use them as arguments in fadeToggle().
e.g.
jQuery("#reveal").fadeToggle('slow');
And to keep the div to stay open, just wrap the buttons and div in a container and listen for the mouseout event on it instead of the buttons themselves.
$(document).ready(function() {
// Hide the div
$('#reveal').hide();
$('.rv_button').on('mouseenter', function(e) {
e.preventDefault();
$('.rv_button').removeClass('open');
$(e.target).addClass('open');
$("#reveal").fadeIn();
});
$('.container').on('mouseleave', function(e) {
e.preventDefault();
$('.rv_button').removeClass('open');
$("#reveal").fadeOut();
});
});
.container {
width: 400px;
}
#reveal {
width: 400px;
height: 400px;
background-color: beige;
text-align: center;
font-size: 2em;
}
.rv_button {
padding: 1em;
background-color: brown;
width: 400px;
box-sizing: border-box;
}
.open {
background-color: orange;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="rv_button">Button 1</div>
<div class="rv_button">Button 2</div>
<div class="rv_button">Button 3</div>
<div id="reveal">Reveal</div>
</div>

Display alert if clicking outside div

I have a div class ".square", i want to show an alert if there is a mouse clicking outside of the div element, i can't find something similar according to mouse event on this website w3schools. ( i want the opposite of my actual code ) Thank you.
function myFunction() {
alert('hi')
}
.square{
width: 100px;
height: 100px;
background-color: red;
}
<div class="square" onclick="myFunction()" ></div>
Simple solution: Add a listener to the window that produces the alert and add a listener to the div that stops the click event from propagating so that it never reaches the window.
Disclaimer: calling stopPropagation is not a great thing to do as it's quite intrusive, but I'm guessing you're just trying things out, so it should be fine.
window.onclick = () => alert('hi')
.square{
width: 100px;
height: 100px;
color: red;
background-color: teal;
}
<div onclick="event.stopPropagation()" class="square">TEST</div>
Here's a good answer that describes a more proper way to achieve this.
And here's that answer adjusted to your case in a more correct solution where we look at the click event to determine if we should call alert:
const outsideClickListener = element => ({ target }) => {
if (!element.contains(target)) {
alert("hi");
}
};
const squareEl = document.getElementById("square");
document.addEventListener("click", outsideClickListener(squareEl));
#square{
width: 100px;
height: 100px;
color: red;
background-color: teal;
}
<div id="square">TEST</div>
Why should we not use stopPropagation? In a small project there's not a big problem to use it (which is why it's my top recommendation). But in a big real world project it's ill advice, because it can break behavior of other stuff. See below example. Developer A added Test 1 and expects alert('hi 1') to be ran every time the user clicks outside of Test 1. But developer B added Test 2 which calls stopPropagation that stops all events, so when the user clicks Test 2 (which is outside of Test 1) alert('hi 1') is not ran and we have a bug.
window.onclick = () => alert('hi 2')
const outsideClickListener = element => ({ target }) => {
if (!element.contains(target)) {
alert("hi 1");
}
};
const squareEl = document.getElementsByClassName("square")[0];
document.addEventListener("click", outsideClickListener(squareEl));
.square, .circle {
width: 100px;
height: 100px;
color: red;
background-color: teal;
}
.square {
background-color: teal;
}
.circle {
background-color: wheat;
}
<div class="square">TEST 1</div>
<div onclick="event.stopPropagation()" class="circle">TEST 2</div>
<div class="square">squre</div>
.square{
width:200px;
height:200px;
border:1px solid red;
}
let sq = document.querySelector('.square');
window.addEventListener('click', function(e){
if (sq.contains(e.target)){
alert('inside square box')
} else{
alert('outside square box')
}
});
Make a click event listener for the body.
If the body is clicked check if the target is the square, or if the target is a child of the square
function myFunction() {
alert('hi');
}
$(document).ready(function(){
$('body').on('click', function(e) {
if($(e.target).is('.square') || $(e.target).closest('.square').length) {
myFunction();
}
});
});
.square{
width: 100px;
height: 100px;
color: red;
background:red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<div class="square">
</div>
<body>

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>

Categories

Resources