How can I check on which element the event was triggered? - javascript

addLBEvent : function()
{
var amount = this.imageList.length;
for(var i = 0;i < amount;i++)
{
if(this.imageList[i].addEventListener)
{
this.imageList[i].addEventListener("click",this.startLB,false);
}
/*
IE<9-part
*/
}
},
startLB : function(src)
{
}
I'd like to know which element triggered the event.
If I'd do this in the HTML-Code I'd write something like onlick="startLB(this.src)" for example. How can I do such a thing with addEventListener?
I've already tried `addEventListener("click","myobjectname.startLB(this.src)" but it didn't work.
And sorry for my bad English

An event object is passed in as the first argument to any event handler.
The event object as a target property identifying the element to which the event applies.
addLBEvent : function(event) {
console.log(event.target);
}
https://developer.mozilla.org/en/DOM/event.target

You can access a reference to the element that triggered the event...
var elementThatTriggeredEvent = e.target || e.srcElement;
...assuming that e is the reference to the event.

If you want to know which element was clicked, use event.target.
If you want to know which element you had the handler on, use event.currentTarget or, in most cases, this. addEventListener will call your handler with this set to the element on which you called addEventListener.
Note the distinction. For instance, if you had this markup:
<div id="foo"><span id="bar">Hi there</span></div>
...and this code:
document.getElementById("foo").addEventListener('click', function(event) {
alert(this.id);
alert(event.target.id)
}, false);
...then if the user clicks the text "Hi there", this will be the div but event.target will be the span.
Live example | source
See how this is the element you hooked the event on, and event.target is the element on which it fired (and then it bubbled up to the div).
Note that addEventListener isn't available on older versions of IE; you have to use attachEvent instead. attachEvent doesn't ensure that this is set to the element on which you hooked it, so beware that difference between APIs. To smooth things like that out, you might look to any decent library, like jQuery, YUI, Closure, or any of several others.

Use this:
startLB : function(src)
{
var element = src.target.tagName;
alert("element >> "+element);
}

I think it's best for you to bind it like this:
var that = this;
this.imageList[i].addEventListener("click",function() {
that.startLB(this.src);
},false);
this will become the event target, so we have to access the object somehow, I named that that

try this...
addLBEvent : function(e)
{
if (!e) e = event;
e = e.srcElement || e.target;
.......
}

Related

jQuery force dynamic event to bind first

I'm binding events on the document element to make them dynamic.
The problem is that these events execute AFTER events binded directly on the elements.
I have code that binds an element to execute first, but it doesn't work with dynamic content. Here is the code I would use for non dynamic content :
bindFirst: function (name, fn) {
var elem, handlers, i, _len;
this.bind(name, fn);
for (i = 0, _len = this.length; i < _len; i++) {
elem = this[i];
handlers = jQuery._data(elem).events[name.split('.')[0]];
handlers.unshift(handlers.pop());
}
}
This function is under .fn.extend.
As I said earlier, I want to be able to do the same, for for dynamic content bound on the document variable. Eg...
$(document).on("click", "div", function(){});
I want this to execute AFTER the code directly above :
$("div").on("click", function(){});
Like #epascarello wrote in the comment:
this is not possible, you need to figure out something different.
A workaround must be thought around the logic of your code. In any case I propose you a "let me say" bad code just to create the evidence of what should happen in order to revert event bubling.
Use the .trigger() method in order to add parameters and use event.stopPropagation() in order to avoid an infinite loop.
Test in the delegated event if the current element has the click event handler and so trigger again the event.
$('#btn').on('click', function(e) {
$(document.body).append($('<div/>', {text: 'CLICK ME: NEW DIV'}));
});
$("div").on("click", function(e, fromInner){
// revert event bubling....
if (fromInner == undefined) {
return;
}
e.stopPropagation();
//normal code.........
console.log('Normal click event');
});
$(document).on("click", "div", function(e) {
// revert event bubling....
if ($._data(this).events != undefined && $._data(this).events[e.type] != undefined) {
$(this).trigger('click', ['fromInner']);
}
console.log('Delegated Click');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button" id="btn">Add new DIV</button>
<div>CLICK ME</div>
You can't do this with jQuery event delegation, it just uses event bubbling, which works from the target element out to the containers. But the plain Javascript addEventListener() method also supports event capture, which goes the other direction. The optional third argument can be used to enable capture mode for an event listener. See Event Bubbling and Capturing.
So I think you should be able to write:
document.addEventListener("click", function() {...}, true);

How to create an "about To Blur" or "will blur" event in Javascript?

I have some code that runs on a "blur" event on an element.
This code needs to actually use the activeElement, and thus can't actually run from the "blur" event.
I was hoping I could create an event like this. The aim was that the "willblur" event would fire before the "blur" event.
var lastTouchedElement;
$('body').on('click', preBlurHandler);
$('body').on('focusin', postFocusHandler);
$('.inp1').on('willblur', function() {alert('willblur');});
$('.inp1').on('blur', function() {alert('blur');});
function preBlurHandler(ev) {
if (!lastTouchedElement) {
postFocusHandler(ev);
return;
}
var focussingElement = ev.target;
if (lastTouchedElement === focussingElement || $.contains(lastTouchedElement, focussingElement)) {
//focus is staying in the same place, do nothing
return;
}
$(lastTouchedElement).trigger('willblur', [ev, {
target: lastTouchedElement,
focussingElement: focussingElement
}]);
}
function postFocusHandler(ev) {
lastTouchedElement = document.activeElement;
}
The full code is in JSFiddle at https://jsfiddle.net/t0un95jt/3/
But it doesn't work. In fact it's not even close.
Help me StackOverflow; you're my only hope.
The key was to use addEventListener instead of JQuery's on(), and to use "mousedown" instead of "click".
instead of this line:
$('body').on('click', preBlurHandler);
I use this:
window.addEventListener('mousedown', preBlurHandler, true);
The final argument for addEventListener: true, means "do this on the capturing phase". The capturing phase starts at the outermost element and works its way through firing an event on subsequent child elements, before the bubbling phase begins which works its way back up the DOM tree.

Call onclick attribute programatically and talk to the event parameter

I have read the other post relating to this matter. Unfortunately it has not resolved my problem. I am happy to use jQuery, so I am looking for the cleanest solution.
I have radio buttons defined as follow:
a = 5;
input.value = "myButton";
input.onclick = (function (a) {
return function (e) {
changeSelectedRadio(e.srcElement, a);
};
})(a);
I need to be able to execute this when user click on the radio button (this works fine), and programatically.
I have tried:
$("input[type='radio'][value='myButton']").triggerHandler("click");
$("input[type='radio'][value='myButton']").click();
Both produce the same result: e (the event parameter) does not exist.
$("input[type='radio'][value='myButton']").onclick();
Does not work
Changing the input.onclick to input.click also did not work. When the use click, the function does not get triggered.
Thanks
If you're using jquery already, might as well build the inputs that way:
var input = $('<input value="something">').click(function(){
var elem = $(this); // the element clicked, as a jquery obj
alert(elem.attr('id');
});
$('body').append(input);
$('input').trigger('click');
Adjust the selectors as needed, and you'll need to actually append the elements to the DOM, but it'll work.
try this:
$("input[type='radio'][value='myButton']").bind( "click", function() {
alert( "clicked" );
});
What is passed to the function is a jQuery event, not a native event. You can use the target element to get at the source that was clicked on or use this to reference the properties of the object directly. See fiddle at http://jsfiddle.net/YQh3Q/
<p><input id="foo1" name="foo" type="radio" value="0" checked="checked"> Foo1</p>
<p><input id="foo2" name="foo" type="radio" value="1"> Foo2</p>
(function ($) {
var input = document.getElementById("foo2");
var a = 5;
input.value = "myButton";
input.onclick = (function (a) {
return function (e) {
alert(e.target + '|' + this.id);
};
})(a);
$("input[type='radio'][value='myButton']").each(function() {
$(this).trigger("click");
});
})(jQuery);
Alternatively (and probably better) you can use a pure jQuery solution
$(function() {
var a = 5;
$('input#foo2').on('click', function() {
changeSelectedRadio(this, a);
})
.val('myButton');
$("input[type='radio'][value='myButton']").trigger('click');
});
Its best to use addEventListener() you can add all types of events. example: "click", "mousemove", "mouseover", "mouseout", "resize" and many more. the false at the end is to stop the event from traversing up the dom. If you want parent dom objects to also receive the event just change it to true. also this example requires no javascript libraries. This is just plain old javascript and will work in every browser with nothing extra needed.
Also addEventListener() is better than onClick() as you can add an unlimited number of event listeners to a dom element. If you have an onClick() on an element and then set another onClick() on the same element you have overwritten the first onClick(). Using addEventListener() if i want multiple click events to trigger when i click on an element i can do it with no problem.
If you want data about the element that is triggering the event you can pass the event to the function. You will see in my example function(e) e is the event and you can use e or this to target the element that is being triggered. Using e or this i can also get more data about the triggered event. for example if the event was a mousemove or mouseclick i can get the x and y position of the mouse at the time of the event.
<!DOCTYPE html>
<html>
<head>
<title>exampe</title>
</head>
<body>
<a id="test" href="">test</a>
<script>
document.getElementById("test").addEventListener("click",function(e){
alert('hello world');
alert('my element '+e);
alert('my element '+this);
},false);
</script>
</body>
</html>
if you want to have addEventListener call a function just change the 2nd value to the function name like this.
document.getElementById("test").addEventListener("click",f1,false);
this will execute the function
function f1(){ ... }
When you want to remove an event listener just call target.removeEventListener(type, listener[, useCapture]). Very simple and easy to manage.

Help me understand JavaScript events

I have a table full of cells and i would like to get on which cell the mouse is.
For this i have attached events to all the cells and then i am finding the elements. But i guess there could be a better options. right ?
Is it possible that i attach only single event handler on top and still be able to catch all the information. like which cell user is currently on etc.
Something like below,
<table onMouseOver="monitorFuntion(event)" >...</table>
It's possible to do exactly what you said: You can put a handler on the table, and then find the cell from that. (This is sometimes called "event delegation".) You can do this for some events, including mouseover and mouseout, because they bubble. You can't do it for other events (like blur or focus) because they don't bubble.
Suppose you have a table with the ID "myTable". You can hook up an event handler for mouseover:
var table = document.getElementById("myTable");
if (table.attachEvent) {
table.attachEvent("onmouseover", handleMouseOver);
}
else {
table.addEventListener("mouseover", handleMouseOver);
}
And then handle it like this:
function handleMouseOver(event) {
var target;
// Handle IE event difference from standard
event = event || window.event;
// Find out what element the event actually happened on
// (Another IE difference here, srcElement vs target)
target = event.srcElement || event.target;
// Since that might be an element *within* your cell (like
// a link, or a `span`, or a `strong`, etc.), find the cell
while (target && target.tagName != "TD" && target.tagName != 'BODY') {
target = target.parentNode;
}
if (target && target.tagName != 'BODY') {
// Found one, `target` now points to the cell the mouse is over
}
}
Note that it's important you handle the case where target ends up being null or referring to the body element, because you'll get this event over the table's borders, row padding, etc.
Javascript libraries can help you with this a lot. For instance, the above using Prototype looks like this:
$("myTable").observe("mouseover", handleMouseOver);
function handleMouseOver(event) {
var target;
target = event.findElement("td");
if (target) {
// ...
}
}
jQuery, Closure, and others will similarly help quite a bit.
Based on the code snippet you posted you are looking for event delegation.
Step 1: use jQuery 1.4.2 +
Step 2:
// you can use move, enter, out, over whatever...
$("table").delegate("mouseenter", "td", click, function(){
var tableCell = $(this); // the cell which is currently moused-over.
});
Yes, you can do exactly that, and then use the event object to find the element. The event object differs between IE and other browsers, but getting the "target" is about the same:
function handler(ev) {
ev = ev || window.event;
var targetElement = ('target' in ev) ? ev.target : ev.srcElement;
// ...
}
Now not all events will "bubble up" for you, but I think that the mouse events do. The problems are mostly with "change". Frameworks like jQuery or Prototype generally try to give you more normalized behavior.
edit fixed for IE compatibility

Simple click event delegation not working

I have a div
<div class="myDiv">
somelink
<div class="anotherDiv">somediv</div>
</div>
Now, using event delegation and the concept of bubbling I would like to intercept clicks from any of myDiv, myLink and anotherDiv.
According to best practices this could be done by listening for clicks globally (hence the term 'delegation') on the document itself
$(document).click(function(e) {
var $eventElem = $(e.target);
var bStopDefaultClickAction = false;
if ($eventElem.is('.myDiv'))
{
alert('Never alerts when clicking on myLink or anotherDiv, why????');
bStopDefaultClickAction = true;
}
return bStopDefaultClickAction;
});
See my alert question above. I was under the impression that clicks bubble. And it somewhat does because the document actually receives my click and starts delegating. But the bubbling mechanism for clicks on myLink and anotherDiv doesn't seem to work as the if-statement doesn't kick in.
Or is it like this: clicks only bubble one step, from the clicked src element to the assigned delegation object (in this case the document)? If that's the case, then I need to handle the delegation like this:
$('.myDiv').click(function(e) {
//...as before
});
But this kind of defeates the purpose of delegation as I now must have lots of 'myDiv' handlers and possibly others... it's dead easy to just have one 'document' event delegation object.
Anyone knows how this works?
You should use live event from JQuery (since 1.3), it use event delegation :
http://docs.jquery.com/Events/live
So you code will be :
$(".myDiv").live("click", function(){
alert('Alert when clicking on myLink elements. Event delegation powaa !');
});
With that, you have all the benefices of event delegation (faster, one event listener etc..), without the pain ;-)
The event target will not change. You need to mirror what jquery live does and actually check if $eventElem.closest('. myDiv') provides a match.
Try:
$(document).click(function(e) {
var $eventElem = $(e.target);
var bStopDefaultClickAction = false;
if ( $eventElem.closest('.myDiv').length )
{
alert('Never alerts when clicking on myLink or anotherDiv, why????');
bStopDefaultClickAction = true;
}
return bStopDefaultClickAction;
});
Event.target is always the element that triggered the event, so when you click on 'myLink' or 'anotherDiv' you store a reference to these objects using $(e.target); So what you do in effect is: $('.myLink').is('.myDiv') which returns false, and that's why the alert() is not executed.
If you want to use event delegation this way, you should check wheter event.target is the element or any of its children, using jQuery it could be done like this:
$(e.target).is('.myDiv, .myDiv *')
Seems to work fine to me. Try it here: http://jsbin.com/uwari
Check this out: One click handler in one page
var page = document.getElementById("contentWrapper");
page.addEventListener("click", function (e) {
var target, clickTarget, propagationFlag;
target = e.target || e.srcElement;
while (target !== page) {
clickTarget = target.getAttribute("data-clickTarget");
if (clickTarget) {
clickHandler[clickTarget](e);
propagationFlag = target.getAttribute("data-propagationFlag");
}
if (propagationFlag === "true") {
break;
}
target = target.parentNode;
}
});

Categories

Resources