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
});
Related
$('body').on("click", "*", function(e) {
console.log("clicked tag:" + this.tagName);
console.log("index:(" + this.tagName + ")[" + $(this).index(this.tagName) + "]");
});
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
<div>
<p>hello !</p>
<div>
<p>stack overflow</p>
</div>
</div>
</body>
</html>
This code identifies the click event and gets the html tag clicked by the person and also displays the index of the element. The problem is that it first returns the html tag of the clicked element(which is required) and then after that it also returns the parent element as well(which is not required). I only want the clicked element, not the parent element. How am i supposed to do it?
Because you're using the * selector, when you click on an element, it's propagating and triggering the click handler for every ancestor on the way up to the body. You could just use evt.stopPropagation(), but there's no need because what you want is already available via evt.target (ie. the element that triggered the click handler bound to the body):
$( 'body' ).on( 'click', function( evt ) {
console.log( evt.target );
} );
I am trying to trigger a custom event in a parent element from the child elements event. The parent element is HelpMenuHeader and it's custom event is defined in HTML as "onsubmenu_click".
Here's a snippet of the HTML that just shows one menu tree.
<span class="formMenu" id="HelpMenuHeader" onsubmenu_click="OnMenuClick()">Help
<div class="formMenu" id="HelpAbout" onmouseup="MenuChildClick()">About us...</div>
</span>
In the child element, HelpAbout, the MenuChildClick event needs to trigger the parent's onsubmenu_click event so that that will execute (that event handler uses the parent's information).
Here's a snippet of the javascript I have for MenuChildClick:
function MenuChildClick()
{
var srcElement = this.event.srcElement;
if (srcElement.id != "spacer" && srcElement.tagName != "HR")
{
// NONE OF THE LINES BELOW WORK
//parent.$(srcElement).trigger('onsubmenu_click');
//$(srcElement).trigger('onsubmenu_click');
//var event = document.createEvent('Event');
//event.initEvent('submenu_click', true, true, null);
//srcElement.dispatchEvent(event);
//oEvent = createEventObject();
//oEvent.result = srcElement.id;
//onsubmenu_click.fire(oEvent);
}
}
I'm having a problem getting a reference to the correct parent element in the MenuChildClick event because when I check the parent reference doesn't have the parent ID.
And then once I have the correct parent reference I need to execute the parent's onsubmenu_click custom event. (The parent event is already being listened to since it's defined in the HTML, right?)
I have to support IE compatibility view so I need it to work for previous IE versions as well.
Anyone tell me how I can do these things (1 & 2 above) leaving the HTML as it is?
Thanks in advance.
You can use jQuery methods .on() and .trigger() instead of event handler attribute
$(function() {
function parentHandler(event, args) {
console.log(event.type, args)
}
$("#HelpMenuHeader").on("submenu_click", parentHandler);
$("#HelpAbout").on("mouseup", function() {
$(this).parent().trigger("submenu_click"
, ["triggered from #" + this.id])
})
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<span class="formMenu" id="HelpMenuHeader">Help
<div class="formMenu" id="HelpAbout">About us...</div>
</span>
First you have to pass the element that is triggering the event in your HTML by changing your HTML to this:
<span class="formMenu" id="HelpMenuHeader" onsubmenu_click="OnMenuClick()">Help
<div class="formMenu" id="HelpAbout" onmouseup="MenuChildClick(this); return false;">About us...</div>
</span>
Notice that I pass the element that is triggering the function call by passing 'this' through the onmouseup function call.
Then you can use the passed element to define which elements you want to monitor as follows:
function MenuChildClick(element)
{
var srcElement = element;
var parent = element.parentNode
if (srcElement.id != "spacer" && srcElement.tagName != "HR")
{
//parent.trigger('onsubmenu_click');
}
}
Is there a way to add some kind of listener for a type of html element? For example if i wanna call a function when the user clicks any p element
the easiest answer would be using addEventListener() if you want a specific html tag just like what i wanted in my question then you'll find the answer there ill paraphrase it here too
add this
<script>
document.addEventListener("click", function(e){
//your desired nodeName like : DIV , SPAN , LI etc
if(e.target && e.target.nodeName== 'DIV')
//add a function below to trigger
{alert('bingo')}
});
</script>
to the end of your document
by the way don't forget to use uppercase nodeNames or just put a toLowerCase() before it. cheers :)
Add the event listener to the window / document / document.body and check the type of the element and the types of its parents because if you have a <span> inside a <p>, clicking the span won't trigger the click in the paragraph.
document.addEventListener("click", function (eventArgs) {
var target = eventArgs.target;
var elementToLookFor = "p";
while (target !== null) {
if (target.tagName.toLowerCase() === elementToLookFor) {
// Do magic stuff with the paragraph
console.log(target);
}
target = target.parentElement;
}
});
This technique is called "event delegation."
Edit: Note that you cannot early return from the loop above. If your have nested paragraphs, i.e.
<p>
Hey,
<p>there!</p>
</p>
Having an early return will only call your event handler for the inner paragraph, whereas you said that you'd like the handler to be invoked on every paragraph which is why you need to traverse all the ancestors of the element.
I assume that you are looking for code along these lines:
var paras = document.getElementsByTagName("p");
// Loop through elements.
for(var i = 0; i < paras.length; i++) {
// Add listener.
paras[i].addEventListener("click",
function() {
// Execute function.
}, false);
}
I'd just select all the elements on the page and add eventListeners on them like so:
function addListeners(elementType, eventType, callback) {
Array.prototype.slice.call(document.querySelectorAll(elementType)).forEach(function (el, i) {
el.addEventListener(eventType, callback, false);
});
}
Above we use querySelectorAll to pick all the wanted elements, convert it to an Array (if you use es6, you can use Array.from) and then we loop through the array and add listeners with the wanted callback.
Here's an example: https://jsfiddle.net/a7en4d4s/
Look at this JSFiddle, and see if it works for you
<span>Click Yes</span><br/><br/>
<span>Click No</span><br/><br/>
<a>Clicked: <b id="result"></b></a>
<script>
$("span").click(function(){
var a = $(this).html();
$("#result").html(a);
});
</script>
I wants to get the ID or the name of the clicked elemt by using the following code. this code is working fine if i have only one element.
$(window).mousedown( function(e) {
mouseTracker.clickState = true;
console.log( "id:" + e.target.id + " name:" + e.target.name );
}).mouseup( function() {
mouseTracker.clickObject = '';
});
but if element is wrapped up in other elements then i am unable to get the ID. for example:
<div id="main">
<div id="subDiv">
<span id="spID" onClick="alert ('hello world')"> Click Me </span>
</div>
</div>
in the above case, it is return the ID of the main div. how can i get the clicked element.
The most secure way to do this is to add an event listener to each element. There are different ways to do that:
First as you have coded in your HTML:
var testfunction = function(event){
// Do something
};
<span id="spID" onclick="testfunction(event)"></span>
Or nicer:
<span id="spID"></span>
var element = document.getElementById('spID');
element.addEventListener('click', function(event){
// do something
})
Best regards
Dustin
I wouldn't use inline scripting if it was me. The bigger a project gets, the messier this becomes. I tend to have all my event listeners tucked away together in an init function that you can just add to as you need more event listeners:
In the head of your HTML:
<script src="global.js"></script>
<script>
$(document).ready(function() {
global.init();
});
</script>
In a separate js file, linked to your HTML (e.g. global.js):
(function (global, $, undefined) {
global.init = function() {
//bind your event listeners in here
};
})(window.global = window.global || {}, jQuery));
In terms of using this for the purposes of what you are trying to do, if you have a series of these clickable spans, I would use a class selector, so you only have to bind the click event once, otherwise if you are binding to only one span as above then you already know the ID anyway as you had to use it in the bind.
Using class:
global.init = function() {
//assuming you have applied the class "clickable-span" to all the spans you want to be clickable
$('.clickable-span').on('click', function(evt) {
var id = $(this).attr('id'),
name = $(this).attr('name');
console.log( "id:" + id + " name:" + name );
});
//add more event listeners here
};
Background:
I'm currently writing a greasemonkey script that embeds/modifies a specific page's html. The page is setup with 3 nested divs. Of those 3 divs, I can only add an event listener to the outer most div(This is due to other events and the such already added to the elements). With the inner most div, links are added via AJAX/COMET. As with the inner divs, I can not add event handlers to these links due to the page's current event handlings.
What I need: When a link in the inner most div is clicked, the event will bubble up to the outer most div. From the outer most div, is there a way 1: to tell if it was a link clicked in the inner most div, and if so, 2: how to get that link's href
Please no jQuery solutions. It seems a bit over doing it sense this is the only javascript that will be embedded into the page
I would just use a simple cross-browser event listener and the event.target (or event.srcElement in IE), like so:
var addEvent = function (el, ev, fn) {
if (el.addEventListener) {
el.addEventListener(ev, fn, false);
} else if (el.attachEvent) {
el.attachEvent('on' + ev, fn);
} else {
el['on' + ev] = fn;
}
};
var outer = document.getElementById('outer');
addEvent(outer, 'click', function(ev){
ev = ev || window.event;
var target = ev.target || ev.srcElement;
alert(target.href);
});
See demo