I have div (.upload-drop-zone, yellow zone at screenshot) with another div (.dropzone-width, blue zone) inside.
<div class="upload-drop-zone dz-clickable" id="drop-zone-600">
<div class="dropzone-width">600 PX</div>
</div>
There is a javascript onclick event attached to .upload-drop-zone (when I click on it, it shows file chooser dialog). Event attached by third-party plugin, so I have no access to function which be called.
The problem is that if I make click on .dropzone-width, click event did not pass to .upload-drop-zone so nothing happens instead of showing file chooser dialog. What can I do to fix it?
P.S.: Sorry for bad english.
Try this, I had a same issue before. No javscript required...
.dropzone-width { pointer-events: none; }
You can listen for a click in the inner div and fire the click on the outer div.
$("#drop-zone-600").click(function (e) {
alert("hey");
});
$("#dzw").click(function (e) {
$("#drop-zone-600").onclick();
});
.upload-drop-zone {
width: 200px;
height: 200px;
border: 1px solid red;
background: darkred;
}
.dropzone-width {
width: 100px;
height: 100px;
border: 1px solid green;
background: lightgreen;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="upload-drop-zone dz-clickable" id="drop-zone-600">
<div id ="dzw" class="dropzone-width">600 PX</div>
</div>
Despite the fact that the alert function is inside the click event listener of the #drop-zone-600 div, you can see the alert by clicking any of the divs.
One possibility is to synthetically fire the click event. See How can I trigger a JavaScript event click
fireEvent( document.getElementById('drop-zone-600'), 'click' );
Try this via jquery:
$(".dropzone-width").on("click", function(){
$("#drop-zone-600").trigger("click");
});
Related
My question in the title probably looks vague. And I sketched an example for the question:
container.onclick = () => {
alert(0);
};
content.onclick = () => {
alert("how can I prevent here appearance alert(0) from parent element event?");
//how can I prevent parent event by content clicked?
};
#container{
height: 100px;
background-color: gray;
}
#content{
height: 50px;
width: 150px;
background-color: green;
}
<div id="container">
<div id="content"></div>
</div>k
This is a simple example. In a real project, I can't combine these two events into one, because the first one is programmatically assigned somewhere in the bowels of my framework and it shouldn't be removed from the EventListener after clicking on content
In General, is it possible to somehow interrupt the execution of the call chain event by clicking in the DOM layers? I tried to do this:
content.onclick = () => {
alert("how can I prevent here appearance alert(0) from parent element event?");
e.preventDefault();
return false;
//how can I prevent parent event by content clicked?
};
But this, of course, was not successful
You should pass the event by dependency injection to the specific method (content.onclick) and then stop the propagation of it.
container.onclick = () => {
alert(0);
};
content.onclick = (e) => {
e.stopPropagation();
alert("Voilà, this prevent that appears alert(0) from parent element event.");
};
#container{
height: 100px;
background-color: gray;
}
#content{
height: 50px;
width: 150px;
background-color: green;
}
<div id="container">
<div id="content"></div>
</div>
For this, you can use stop propogation of js like this
<div id="container">
<div id="content" onclick="event.stopPropagation();">
</div>
</div>
So when you click on content it will not trigger container event only.
Languages involved: HTML, CSS, JS
Context: I'm relatively new to web development. I have two elements overlapping each other. One is a slider, one is a div. The slider is on top of the div.
Code snippets:
<div id="myDiv">
<input id="mySlider" type="range" min=1 max=100 step=1>
</div>
and
initListeners() {
document.getElementById("myDiv").addEventListener("click", divFunction);
document.getElementById("mySlider").addEventListener("input", sliderFunction);
}
I need to make it that when you click the slider, it doesn't click the div. How would I go about doing that? I've tried z-index, but that doesn't seem to change anything.
Thanks in advance!
As I'm sure you've figured out by now, events in JavaScript by default bubble up from a child to a parent. You need to stop that from happening at the child level, also known as preventing propagation.
Using the stopPropagation function, you can handle this as follows:
function sliderFunction(e) {
e.stopPropagation();
}
Simple. That event will no longer reach the parent.
EDIT
While stop propagation is the correct method to use, event listeners must also match in type. Therefore, both the slider and the parent DIV must have click event listeners (instead of input and click). stopPropagation stops propagation of a specific type of event.
function divFunction() {
console.log('DIV clicked!');
}
function sliderFunction(event) {
event.stopPropagation();
console.log('Slider clicked!');
}
function initListeners() {
document.getElementById('myDiv').addEventListener('click', divFunction);
document.getElementById('mySlider').addEventListener('click', sliderFunction);
}
initListeners();
/* unnecessary visual aides */
body *:not(label) {
padding: 2rem;
outline: 1px solid red;
position: relative;
}
label {
display: inline-block;
position: absolute;
background: #222;
color: #fff;
top: 0; left: 0;
}
<div id="myDiv">
<label>#myDiv</label>
<div id="tools">
<label>#tools</label>
<input type="range" id="mySlider">
</div>
</div>
You can also check the target once you fire that click event. I've used this approach before:
JSFiddle: http://jsfiddle.net/L4ck7ygo/1/
function divFunction(e) {
if (e.target !== this) {
return;
} else {
console.log('hit');
}
}
When the fiddle first loads, click the slider and you'll see the console log out some text. To see it work, remove the line that is being pointed to and rerun the fiddle. Now when you click the slider, you won't see anything logged in the console, but if you click on the div and not the slider, it will log to the console.
function initListeners() {
document.getElementById("myDiv").addEventListener("click", divFunction);
document.getElementById("mySlider").addEventListener("input", sliderFunction);
}
initListeners();
function divFunction(e) {
console.log('Firing...') // <-- This will log on any click
if (e.target !== this) {
return;
} else {
console.log('hit'); // <-- This will NOT log except for div click
}
}
function sliderFunction() {
console.log('Doing stuffs...');
}
<div id="myDiv">
<input id="mySlider" type="range" min=1 max=100 step=1>
</div>
UPDATE: Stupidity on my part. I had the ordering wrong for the elements which caused propagation to not act as intended.
I am having a div inside a div. And I want to call a function on the click of outer div and another function on the click of inner div. Is it possible to do so?
<div onclick="function1()">
<div onclick=function2()></div>
</div>
Yes, this is very much possible. And the code you have will get the job done.
NOTE: You need to add event.stopPropagation() in case you want to prevent the bubbling of the event from the inner function.
Try this out:
function function1() {
console.log("From outer div");
}
function function2(event) {
console.log("From inner div");
event.stopPropagation();
}
#outer-div {
width: 100px;
height: 100px;
background: yellow;
}
#inner-div {
width: 50px;
height: 50px;
background: red;
position: relative;
top: 25px;
left: 25px;
}
<div id="outer-div" onclick="function1()">
<div id="inner-div" onclick="function2(event)"></div>
</div>
Yes, it is; one way to do it is the way you've done it in your question, except:
You need quotes around the inner onclick attribute value, just as you have around the outer onclick attribute value.
You probably want to pass event into at least the inner one:
<div onclick="function2(event)"></div>
and then have it call stopPropagation on that:
function function2(event) {
event.stopPropagation();
}
so that the click event isn't propagated to the parent (doesn't bubble any further). If the click bubbles, function1 will be called as well.
Example:
function function1() {
console.log("function1 called");
}
function function2(event) {
event.stopPropagation();
console.log("function2 called");
}
<div onclick="function1()">
<div onclick="function2(event)">this div fires function2</div>
clicking here will fire function1
</div>
You might also consider modern event handling rather than onxyz-attribute-style event handlers; search for examples of addEventListener for details; my answer here also has a useful workaround for obsolete browsers.
I'm attaching mousedown, mouseup and click handlers to an element. On mousedown I add a class to the element, on mouseup I remove the class, and on click I do some work. (This is a simplification of the context. In my project the click event is handled by a 3rd party component.)
The problem I'm having is that the click event is never emitted in Safari and Firefox, but it works just fine in Chrome. (I don't know what IE does. I don't have access to it, and don't care about it.)
The code is as follows:
HTML:
<div id="clickme">
<div class="normal"></div>
<div class="highlight"></div>
</div>
<input type="text" id="textinput"/>
CSS:
#clickme:not(.active) > .highlight {
display: none;
}
#clickme.active > .normal {
display: none;
}
.normal, .highlight {
width: 100px;
height: 100px;
}
.normal {
background: blue;
}
.highlight {
background: red;
}
JS:
var clickme = $('#clickme');
var textinput = $('#textinput');
clickme.on('mousedown', function(e) {
clickme.addClass('active');
// ^-- comment this out and the click event starts working
});
clickme.on('mouseup', function(e) {
clickme.removeClass('active');
// ^-- comment this out and the click event starts working after the second click
});
clickme.on('click', function(e) {
e.preventDefault();
textinput.val(Date.now());
});
JSFiddle: https://jsfiddle.net/xLskk3po/14/
JSFiddle without JQuery: https://jsfiddle.net/xLskk3po/15/ It shows that it's not a JQuery problem.
I stumbled upon this SO question: When a mousedown and mouseup event don't equal a click and it looks like my issue is similar to that. So I did something silly: I put a transparent, absolutely positioned element on top.
HTML:
<div id="clickme">
<div class="normal"></div>
<div class="highlight"></div>
<div class="abs"></div> <!-- this is the absolute element, covering #clickme -->
</div>
<input type="text" id="textinput"/>
That fixed it.
I'm making website that have notification 'button'. When user click this button, notification div will appear at the bottom of the button.
I want to make its behaviour like notifacation in facebook. the notification will disappear when user click anywhere outside the notification div element.
So far, i've succeed to make the notification div to fade in and fade out when the notification button clicked. i'm using jquery to do this.
but, i don't know how to make it fade out when user click anywhere outside the notification div.
Can anyone help me?
Here is my code that i've made:
<div id="notifikasi" style="position:relative; cursor:pointer">Notification<sup style="padding: 2px 4px 2px 4px; background: red"></sup>
<div id="theNotif" style="position: absolute; top: 20px; left: 0px; background: #fff; color: #000; border: solid 1px #999; z-index: 999; padding: 10px 20px 10px 0px; width:200px; display:none">
<ul>
<li>Some Notification</li>
<li>Some Notification</li>
<li>Some Notification</li>
</ul>
</div>
</div>
<script>
$('#notifikasi').click(function(){
if($('#theNotif').css('display') == 'none'){
$('#theNotif').fadeIn('fast');
}
else{
$('#theNotif').fadeOut('fast');
}
});
</script>
Try this:
$(document).mouseup(function (e)
{
var myDiv = $("#theNotif");
if (myDiv.has(e.target).length === 0)
myDiv.hide();
});
How about:
$('#notifikasi').click(function(){
$('#theNotif').fadeIn('fast', function() {
$(document).one('click', function(e) {
$('#theNotif').fadeOut('fast');
});
});
});
// prevent triggering when clicking the actual notification
$('#theNotif').click(function() { return false; });
Demo
Once the notification has faded in, a one-time-only click listener will be added to the document listening to any click.
Edit
Having played around like this a bit myself, I've come to the conclusion that .one is not really as useful here as I first imagined, as it requires a few other workarounds. The reason I used it was that it irked me to have to constantly listen to every single document click, just to cover the scenario where a notification was open.
I've decided instead that a neater way would be to use bind and unbind.
function closeNotification(e) {
if($(e.target).closest('#theNotif').length > 0) {
// notification or child of notification was clicked; ignore
return;
}
$('#theNotif').fadeOut('fast');
$(document).unbind('click', closeNotification);
};
$('#notifikasi').click(function(){
$('#theNotif').fadeIn('fast', function() {
$(document).bind('click', closeNotification);
});
});
Demo
The code above is conceptually rather similar to the original code. After fade-in, a click listener is registered at the document. This time, a check is made within the document click listener, to see if the clicked element was #theNotif or a child of #theNotif, in which case the close function exits immediately.
Otherwise, it proceeds to close the notification and then immediately unbind the listener.
Note that you'll have to use a named function, not an anonymous inline one as you might be used to in jQuery, in order to be able to properly unbind it.
Set a variable when mouse moves over notifikasi (say a=1), unset it when moves outside.
Similarly for theNotif.
Now
$(document).click(function(){
if(a == 0){
if($('#theNotif').css('display') == 'block' || $('#theNotif').css('display') == ''){
$('#theNotif').fadeOut('fast');
}
}
});