This question already has answers here:
How to have click event ONLY fire on parent DIV, not children?
(12 answers)
Closed 8 years ago.
I'm looking for a jquery function doing the following :
if I click everywhere inside the div (but elements inside this div), the code is executed .
if I click in an html element inside this div , noting happens .
You need to test if the clicked target is this. Fiddle here: http://jsfiddle.net/ZBC43/
$('div').on('click', function(e) {
if (e.target !== this) return;
alert('div clicked');
});
The event is lopped through the element, until a element with a click element is found.
Solutions:
Test if the target element is the same as the delegateTarget
You set the event of the inner elements to a empty function
You need something like this (i try to find parent div with your class):
<div class='foobar'>
<span>child1</span>
<span>child2</span>
</div>
<span>child3</span>
<script>
$('.foobar').on('click', function(e) {
var testelem = $(e.target);
while (testelem != undefined && !testelem.hasClass('foobar')){
testelem = testelem.parent();
}
if (testelem != undefined && testelem.hasClass('foobar')) {
alert('code');
}
});
</script>
http://jsfiddle.net/eaVzx/
You can use tagName dom property to get current target element name.
TagName: Returns the name of the element.
HTML
<div id="myDiv" style='display:inline-block; width:300px;'><span style='display:inline-block;'>Hello Click here</span><br /><span style='display:inline-block;'>Click here</span></div>
Javascript
$(document).ready(function(){
$('#myDiv').click(function (e) {
if (e.target.tagName == "DIV") {
alert('Clicked on Div');
}
else{
alert('Clicked on Inner Element');
}
});
});
Try in fiddle
OR also use nodeName property to get current element.
NodeName: Returns the name of the current node as a string.
Try in fiddle 2
Try this:
$("div").click(function(e) {
if (e.target !== this) return;
alert("inside a div");
});
Related
I'm doing event targeting experiment and compare its execution in vanilla JS and jQuery. I was surprised that the result was different; it was successful in vanilla JS but not in jQuery. If I'm not mistaken, the code for event targeting in jQuery is $(event.target) and in vanilla JS is event.target. In my experiment, I've only got a button inside the <body> tag, and whenever it is being target by an event, the browser is supposed to alert "button element is target", otherwise it will be "window itself is targeted". But the alert notification was only "window itself is targeted" even if the targeted element is the button. Here is my code:
Vanilla JS
let $ = document.querySelector.bind(document);
window.onclick = function(event) {
if(event.target != $('button')) {
alert('window itself is targeted');
} else {
alert('button element is targeted');
}
}
jQuery
$(window).on('click', function(event) {
var $eventTarget = $(event.target);
if($eventTarget != $('button')) {
alert('window itself is targeted');
} else {
alert('button element is targeted');
}
});
In jQuery code, I tried to replace the $(event.target) with event.target to see if its execution would be similar to vanilla JS, but nothing changed. Is it the grammar of my code that makes it fail or is there something else wrong that I just don't notice. I hope someone could point it out to me.
Your test is flawed as event.target != $('button') will always be true as you're comparing a DOMElement and a jQuery object, and $eventTarget != $('button') will also always be true as you cannot directly compare objects.
To fix this compare properties of the objects:
// Native:
let $ = document.querySelector.bind(document);
window.addEventListener('click', function(e) {
if (e.target.id != $('button').id) {
alert('window itself is targeted');
} else {
alert('button element is targeted');
}
});
Note the preferred use of addEventListener() here, over onclick().
Working native example
// jQuery
$(window).on('click', function(e) {
if (e.target.id != $('button').prop('id')) {
alert('window itself is targeted');
} else {
alert('button element is targeted');
}
});
Working jQuery example
Because $('button') and $(event.target), even if they refer to the same Button, they are not the same Object.
The correct way to compare two dom elements using jQuery is to compare their tag / class / id or any other attribute
alert($(event.target) == $(event.target)); // false (same target, different jQuery objects)
alert($('button') == $('button')); // false (same button, different jQuery objects)
alert($(event.target).is('button')); // true (comparing element tags)
alert($(event.target).attr('id') == 'buttonId'); // true (comparing element ids)
alert($(event.target).hasClass('buttonClass')); // true (comparing element classes)
DEMO
I have a listener which runs when I click on document.
document.addEventListener('click', print);
function print(element)
{
doSomething();
}
It creates div id=panel, where I print some information.
When I run the print function I would like to detect whether I clicked outside of the div#panel (The panel exists when I click second time).
I wish not to use the mouseout event listener because I think it is redundant to use listener for mouse movements when the event click is already fired.
How to detect when I clicked out of div#panel?
You can check the target of jQuery's click event, which element it was:
$(document).click(function(e) {
var target = $(e.target);
if( !target.is("#panel") && target.closest("#panel").length === 0 ) {
// click was not on or inside #panel
}
});
Your event handler gets passed an event object, not an element. Since you are listening for the click event, the event will be of type MouseEvent and that event object will have a target property which you can use to check if the target element matches your desired element.
function handler(event) {
if (event.target == document.getElementById("panel")) {
// Do stuff
}
}
document.addEventListener('click', handler);
Edit: I intentionally gave the vanilla JS answer since your own code fragments don't use jQuery. But jQuery wouldn't change anything as its event handling API is almost just a thin wrapper over JS.
I am just using event from the click. Here it is
var elem=document.getElementById("elem");
var rects=elem.getBoundingClientRect();//get the bounds of the element
document.addEventListener('click', print);
function print(e)
{
//check if click position is inside or outside target element
if(e.pageX<= rects.left +rects.width && e.pageX>= rects.left && e.pageY<= rects.top +rects.height && e.pageY>= rects.top){
console.log("Inside element");
}
else{
console.log("Outside element");
}
}
JS Bin link : https://jsbin.com/pepilehigo/edit?html,js,console,output
A different approach, using only javascript is:
function print(evt) {
if (!(evt.target.tagName == 'DIV' && evt.target.classList.contains('myDiv'))) {
var div = document.createElement('div');
div.classList.add('myDiv');
div.textContent="new div";
document.body.appendChild(div);
}
}
window.onload = function() {
document.addEventListener('click', print);
}
.myDiv {
border:1px solid green;
}
This question already has answers here:
Getting the ID of the element that fired an event
(24 answers)
Closed 9 years ago.
I want to identify each element by it's name attribute. Each element has the same class and will ultimately contain differing dynamic information.
For example I would want the following code to alert the individual element's name value:
html:
<p class="pexample" name="0">this is p #1</p>
<p class="pexample" name="1">this is p #2</p>
<p class="pexample" name="2">this is p #3</p>
jquery:
$('p').on('click', function() {
if ($('p').attr('name') !== undefined) {
alert($('p').attr('name'));
}
})
Here is a jsfiddle.. http://jsfiddle.net/XG7nd/1/
This code however only alerts the initial elements name value. Help is greatly appreciated.
This should do:
$('p').on('click', function() {
var name = $(this).attr('name');// `this` here refers to the current p you clicked on
if (name ) {
alert(name);
}
})
While doing $('p').attr('name') this will always give you the name of the first item in the collection.
Demo
Try this:
$(document).on('click','p', function() {
alert($(this).attr('name'));
});
DEMO
You want to use $(this)
$('p').on('click', function() {
if($(this).attr('name') !== 'undefined') {
alert($(this).attr('name'));
}
});
This is occurring because you are getting the name attribute for the first <p> on every click. You need to specify the one that the event originated from:
$('p').on('click', function() {
if ($(this).attr('name') !== undefined) {
alert($(this).attr('name'));
}
})
Note, jQuery selectors return an array of matching elements. You must use the this keyword to get a handle on the element in the current context.
FIDDLE
Explanation
You keep looking for the p element even on click, so it'll select the first one it finds.
What your code says:
When p is clicked:
Find a p element and alert its attribute.
What you really want:
When p is clicked:
alert the clicked element's attribute
Solution
Select the attribute of this, which is the clicked element.
JSFiddle
JavaScript
$('p').on('click', function() {
if ($(this).attr('name') !== undefined) {
alert($(this).attr('name'));
}
})
Read more about the this keyword.
I would like to detect which HTML element was double clicked. Seems to something not fire in my code. Following is my HTML code structure where you double click detect which item is clicked.
<div id="mainWrapper">
<div id="Banner" name="Banner" class="editable">This is the banner</div>
<div id="MainMenu" class="editable">This is the main menu</div>
<div id="LeftSideBar" class="editable">This is the submenu or left sidebar content</div>
<div id="MainContent"class="editable">Here is the main content</div>
<div id="RightSideBar" class="editable">Here are commercial ads</div>
<div id="Footer"class="editable">This is the footer
Go Home
</div>
</div>
External JavaScript
window.onload = function(){
// Listen to the double click event.
if ( window.addEventListener )
document.body.addEventListener( 'dblclick', onDoubleClick, false );
}
Get the element which fired the event. This is not necessarily the element to which the event has been attached.
function onDoubleClick( ev ){
var element = ev.target || ev.srcElement; //target = W3C, srcElement = Microsoft
alert(ev.type); //displays which event has fired
var targ;
if (!ev) var e = window.event;
if (ev.target) targ = ev.target;
else if (ev.srcElement) targ = ev.srcElement;
alert(ev.target); //displays which type of html element has been clicked (it shows div but not which div)
// Find out the div that holds this element.
var name;
do {
element = element.parentNode;
}
while ( element && ( name = element.nodeName.toLowerCase() ) && ( name != 'div' ||
element.className.indexOf( 'editable' ) == -1 ) && name != 'body' )
alert("The class name for the element is " + element.className); // I get nothing
alert("The node name for the html element is " + element.nodeName);// I get "body"
}
I'm not sure exactly what it is you're trying to accomplish. Is it so people can edit things? I'd be tempted to apply the onclick event listener just to those items you want to be editable. If they all have "editable" css classes, doing so is trivial with jquery:
$('.editable').dblclick(dblclickFunc)
This would apply an event listener to every element with a class of editable. However, to make it more useful, I'd change that to
$('.editable').dblclick(function(e){ dblclickFunc(e, this); })
and for the function
dblclickFunc(e, el){
alert('received an event of type ' + e.type + ' on ' + el.tagName);
}
So you've got a reference to the element that sent the event. From there, you could check IDs, or even go so far as to loop through all your editable elements and compare them to the one that got passed to you. Once you have a match, you know precisely which element was clicked on.
You are using JavaScript in your example, but you also tagged the question with jQuery, so I assume jQuery is OK to use. In fact, exactly this type of event handling is greatly simplified using jQuery’s API, since it normalizes the events for all modern browsers. Highly recommended.
You can delegate the event to the document and detect all double clicks in the entire document using jQuery using the on() function:
$(document).on('dblclick', function(e) {
console.log(e.target); // target is the element that triggered the event
alert("The class name for the element is " + e.target.className);
alert("The node name for the html element is " + e.target.nodeName);
});
If you want to listen on certain elements inside a specific container, try this:
$('#mainwrapper').on('dblclick', 'div', function(e) {
console.log(e.target);
});
This will listen for any double clicks inside #mainwrapper, but only trigger the handler if a DIV element was the target.
You can use .on()
$(".editable").on("dblclick", function(e){
$(this).attr('class') //Class Name
});
I have a function that I am calling with two images like so.
$('#image1').bind('click',doNext);
$('#image2').bind('click',doNext);
I need to be able to tell which one called the function.
function doNext(){
if(target == $('#image1'){
alert('image1');
}else{
alert('image2');
}
}
this within doNext will be the raw DOM element, so:
function doNext() {
if (this.id === "image1") {
alert('image1');
}else{
alert('image2');
}
}
There I'm branching on the id because you specifically did that in your code, but usually you just interact with the object.
If you need to use any jQuery functions, wrap the raw DOM element in a jQuery object (var $this = $(this);), but you don't need to if all you want to do is look at the id as I did above.
Within jQuery event handlers, there are (at least) two significant DOM elements you have access to: The element on which you hooked the event (this), and the element that triggered the event (event.target). In your case, assuming that image1 and image2 are img elements, they'll be the same because img can't contain any other element, but in the case of elements that can contain other elements (div, p, etc. — e.g., most elements), event.target may be different from this. Say you have:
<div id="foo">
<p>Blah blah blah</p>
</div>
and this
$("#foo").click(function(event) {
alert(this.tagName);
alert(event.target.tagName);
});
If you click the paragraph, you'll get
DIV
P
...because you hooked the event on the div, but it was triggered by a click on the p. (This is the basis of event delegation.)
var id = $(this).attr('id');
if (id == 'image1') {
alert('image1');
} else{
alert('image2');
}
Use the attr() function to retrieve the ID of the element. Also, I would further simplify this by adding a common class to both images so that you can do this:
$('.myimages').click(function() {
if($(this).attr() == 'image1') {
alert('image1');
}
else {
alert('image2');
}
});
You can use event.target:
function doNext(event){
if($(event.target).attr('id') == 'image1'){
alert('image1');
}else{
alert('image2');
}
}
You can get the event.target in the event handler function:
function doNext(event) {
var target = event.target;
}
Alternatively, this will refer to the clicked element:
function doNext() {
var clickedID = this.id;
}
$(document).ready(function() {
$('#image1').click(function(){doNext('image1')});
$('#image2').click(function(){doNext('image2')});
});
doNext = function (target){
if(target == "image1"){
alert('image1');
}else{
alert('image2');
}
}