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
};
Related
My code is :
var draggedElement = this.template.querySelector("[id='"+divId+"']");
var cln = draggedElement.cloneNode(true,true);
cln.classList.add('completed');
cln.classList.add('box-height');
cln.id='clone-'+divId;
event.target.appendChild(cln);
Now if I want to alert the event target id on the onclick event it gives empty result.
Trying to use like this but did not work.
const btn = this.template.querySelector("[id='clone-"+divId+"']");
btn.addEventListener('click', function(event){
console.log('Button Clicked');
console.log(event.target.id);
});
Can anyone please help? Thanks in advance.
You are probably binding the event handler before the dragged element is created (which I suppose is done in response of a user action).
Instead of playing with id attributes, just bind the event handler at the moment you add the cloned element to the document. At that time you have the reference to the cloned element, so you can just add the event listener to it.
Little, simplified, demo:
var draggedElement = document.querySelector("#test");
var cln = draggedElement.cloneNode(true,true);
cln.removeAttribute("id"); // Don't use `id`
cln.textContent = "cloned " + cln.textContent;
document.body.appendChild(cln);
cln.addEventListener('click', function(event){
console.log('Cloned button Clicked');
});
<button id="test">test</button>
Event Delegation
Although I would strongly advise against using dynamically generated id attributes, if you really require to identify elements by such id attributes, then use event delegation:
setTimeout(function () { // In reality this would be some drag event handler
var draggedElement = document.querySelector("#test");
var cln = draggedElement.cloneNode(true,true);
cln.id = "cloned-" + cln.id; // Bad practice
cln.textContent = "cloned " + cln.textContent;
document.body.appendChild(cln);
}, 500);
// Event delegation
document.body.addEventListener('click', function(event){
if (event.target.id = "cloned-test") {
console.log('Cloned button Clicked');
}
});
<button id="test">test</button>
I have some dynamically created objects from a jade template which contain buttons. I would like to be able to get the object when the button inside it is clicked. Here is what I currently have
mixin ad(name,media,payout)
.box.box-primary
.box-header.with-border
h3.box-title=name
.box-body
img(src=media, style='width:130px;height:100px;')
p.text-muted.text-center="$"+payout
p.text-muted.text-center preview
.box-footer.text-right
button.btn.btn-primary(type='button',id="share",name="share",onclick='getSelf()') Share
and the jQuery
var getSelf = function() {
var clickedBtnID = $(this).parent();
alert('you clicked on button #' + clickedBtnID.name);
}
I know my jQuery is incorrect because It just prints "undefined" but how would I print the name?
Thanks.
As of now, this doesn't refer to the button element, it refers to window object.
You can pass the this reference to the function
button.btn.btn-primary(type='button',id="share",name="share",onclick='getSelf(this)')
Modify your function to accept the reference, which can be used later.
var getSelf = function(elem) {
var clickedBtnID = $(elem).parent();
alert('you clicked on button #' + clickedBtnID.name);
}
However I would recommend you to use unobtrusive event handler instead of ugly inline click handler(get rid of it).
$(function(){
$("#share").on('click', function(){
var clickedBtnID = $(this).parent();
alert('you clicked on button #' + clickedBtnID.name);
});
})
You can reference to the element which triggered the event using the event.target property. The event information is passed as the first parameter to the event handler.
Complete working code.
$('div').click(function(event){
console.log(event.target.id)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="div1">div1</div>
<div id="div2">div2</div>
<div id="div3">div3</div>
<div id="div4">div4</div>
<div id="div5">div5</div>
I'll try to explain my problem:
I have a website where the user dynamically adds elements. They all belong to the "toBuy" class. Whenever a new element is added to this class I need to attach a click-handler to only this element but not to all others. To keep my code clean I want to have a function that does this work. Here is what i've tried:
this is how the stuff is added:
$("#addItemButton").click(function(){
var item= $('#item').val();
$('#item').val("");
var quantity= $('#quantity').val();
$('#quantity').val("");
var comment=$('#addComment').val();
$('#addComment').val("");
//construct new html
var newitem="<div class='toBuyItem'><div class='item'>";
newitem+=item;
newitem+="</div><div class='quantity'>";
newitem+=quantity;
newitem+="</div><div class='comment'><img src='img/comment";
if(comment==""){
newitem+="_none"
}
newitem+=".png' alt='Comment'></div><div class='itemComment'>"
newitem+=comment;
newitem+="</div></div>";
$("#toBuyItems" ).prepend( newitem );
toggle("#addItemClicked");
initializeEventListeners();
});
then this is the initializeEventListeners function (which I also run when the page loads so that the existing elements have the event handlers already:
function initializeEventListeners(){
$(".toBuyItem").click(function(){
console.log($(this).html());
console.log($(this).has('.itemComment').length);
if($(this).has('.itemComment').length != 0){
console.log("toggling");
$(this).addClass("toggling");
toggle(".toggling .itemComment");
$(this).removeClass("toggling");
}
});
}
function toggle(item){
$( item ).slideToggle(500);
}
now apparently what happens is that when a new element is added the existing elements get a new event handler for clicking (so they have it twice). Meaning that they toggle on and off with just one click. Probably it's damn simple but I cannot wrap my head around it....
EDIT:
so this works:
$(document).on('click', '.toBuyItem', function(){
if($(this).has('.itemComment').length != 0){
console.log("toggling");
$(this).addClass("toggling");
toggle(".toggling .itemComment");
$(this).removeClass("toggling");
}
});
Use jquery's on method. This way you have to add event only once. This will be added automatically to dynamically added elements.
$(document/parentSelector).on('click', '.toBuyItem', function() {
// Event handler code here
});
If you are using parentSelector in the above syntax, it has to be present at the time of adding event.
Docs: https://api.jquery.com/on
You can use jQuery.on method. It can attach handlers to all existing in the DOM and created in future tags of the selector. Syntax is as follows:
$(document).on('click', '.toBuyItem', function(){
//do onClick stuff
})
As others have suggested, you can delegate click handling to document or some suitable container element, and that's probably what I would do.
But you could alternatively define a named click handler, which would be available to be attached to elements already present on page load, and (scope permitting) to elements added later.
You might choose to write ...
function buy() {
if($(this).has('.itemComment').length != 0) {
$(this).addClass("toggling");
toggle(".toggling .itemComment");
$(this).removeClass("toggling");
}
}
function initializeEventListeners() {
$(".toBuyItem").on('click', buy);
}
$("#addItemButton").on('click', function() {
var item = $('#item').val(),
quantity = $('#quantity').val(),
comment = $('#addComment').val();
$('#item', '#quantity', '#addComment').val("");
//construct and append a new item
var $newitem = $('<div class="toBuyItem"><div class="item">' + item + '</div><div class="quantity">' + quantity + '</div><div class="comment"><img alt="Comment"></div><div class="itemComment">' + comment + '</div></div>').prependTo("#toBuyItems").on('click', buy);// <<<<< here, you benefit from having named the click handler
$newitem.find(".comment img").attr('src', comment ? 'img/comment.png' : 'img/comment_none.png');
toggle("#addItemClicked");
});
I have several jQuery click functions- each is attached to a different DOM element, and does slightly different things...
One, for example, opens and closes a dictionary, and changes the text...
$(".dictionaryFlip").click(function(){
var link = $(this);
$(".dictionaryHolder").slideToggle('fast', function() {
if ($(this).is(":visible")) {
link.text("dictionary ON");
}
else {
link.text("dictionary OFF");
}
});
});
HTML
<div class="dictionaryHolder">
<div id="dictionaryHeading">
<span class="dictionaryTitle">中 文 词 典</span>
<span class="dictionaryHeadings">Dialog</span>
<span class="dictionaryHeadings">Word Bank</span>
</div>
</div>
<p class="dictionaryFlip">toggle dictionary: off</p>
I have a separate click function for each thing I'd like to do...
Is there a way to define one click function and assign it to different DOM elements? Then maybe use if else logic to change up what's done inside the function?
Thanks!
Clarification:
I have a click function to 1) Turn on and off the dictionary, 2) Turn on and off the menu, 3) Turn on and off the minimap... etc... Just wanted to cut down on code by combining all of these into a single click function
You can of course define a single function and use it on multiple HTML elements. It's a common pattern and should be utilized if at all possible!
var onclick = function(event) {
var $elem = $(this);
alert("Clicked!");
};
$("a").click(onclick);
$(".b").click(onclick);
$("#c").click(onclick);
// jQuery can select multiple elements in one selector
$("a, .b, #c").click(onclick);
You can also store contextual information on the element using the data- custom attribute. jQuery has a nice .data function (it's simply a prefixed proxy for .attr) that allows you to easily set and retrieve keys and values on an element. Say we have a list of people, for example:
<section>
<div class="user" data-id="124124">
<h1>John Smith</h1>
<h3>Cupertino, San Franciso</h3>
</div>
</section>
Now we register a click handler on the .user class and get the id on the user:
var onclick = function(event) {
var $this = $(this), //Always good to cache your jQuery elements (if you use them more than once)
id = $this.data("id");
alert("User ID: " + id);
};
$(".user").click(onclick);
Here's a simple pattern
function a(elem){
var link = $(elem);
$(".dictionaryHolder").slideToggle('fast', function() {
if (link.is(":visible")) {
link.text("dictionary ON");
}
else {
link.text("dictionary OFF");
}
});
}
$(".dictionaryFlip").click(function(){a(this);});
$(".anotherElement").click(function(){a(this);});
Well, you could do something like:
var f = function() {
var $this = $(this);
if($this.hasClass('A')) { /* do something */ }
if($this.hasClass('B')) { /* do something else */ }
}
$('.selector').click(f);
and so inside the f function you check what was class of clicked element
and depending on that do what u wish
For better performance, you can assign only one event listener to your page. Then, use event.target to know which part was clicked and what to do.
I would put each action in a separate function, to keep code readable.
I would also recommend using a unique Id per clickable item you need.
$("body").click(function(event) {
switch(event.target.id) {
// call suitable action according to the id of clicked element
case 'dictionaryFlip':
flipDictionnary()
break;
case 'menuToggle':
toggleMenu()
break;
// other actions go here
}
});
function flipDictionnary() {
// code here
}
function toggleMenu() {
// code here
}
cf. Event Delegation with jQuery http://www.sitepoint.com/event-delegation-with-jquery/
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
});