I need to have a handler on the calling object of onclick event.
link
<script>
function click123(event) {
//i need <a> so i can manipulate it with Jquery
}
</script>
I want to do this without the use of $().click or $().live of jQuery but with the method described above.
pass in this in the inline click handler
link
or use event.target in the function (according to the W3C DOM Level 2 Event model)
function click123(event)
{
var a = event.target;
}
But of course, IE is different, so the vanilla JavaScript way of handling this is
function doSomething(e) {
var targ;
if (!e) var e = window.event;
if (e.target) targ = e.target;
else if (e.srcElement) targ = e.srcElement;
if (targ.nodeType == 3) // defeat Safari bug
targ = targ.parentNode;
}
or less verbose
function doSomething(e) {
e = e || window.event;
var targ = e.target || e.srcElement || e;
if (targ.nodeType == 3) targ = targ.parentNode; // defeat Safari bug
}
where e is the event object that is passed to the function in browsers other than IE.
If you're using jQuery though, I would strongly encourage unobtrusive JavaScript and use jQuery to bind event handlers to elements.
I think the best way is to use currentTarget property instead of target property.
The currentTarget read-only property of the Event interface identifies the current target for the event, as the event traverses the DOM. It always refers to the element to which the event handler has been attached, as opposed to Event.target, which identifies the element on which the event occurred.
For example:
<span class="icon"></span> blah blah
Javascript:
a.addEventListener('click', e => {
e.currentTarget; // always returns "a" element
e.target; // may return "a" or "span"
})
The easiest way is to pass this to the click123 function or
you can also do something like this(cross-browser):
function click123(e){
e = e || window.event;
var src = e.target || e.srcElement;
//src element is the eventsource
}
http://docs.jquery.com/Events/jQuery.Event
Try with event.target
Contains the DOM element that issued
the event. This can be the element
that registered for the event or a
child of it.
The thing with your method is that you clutter your HTML with javascript. If you put your javascript in an external file you can access your HTML unobtrusive and this is much neater.
Lateron you can expand your code with addEventListener/attackEvent(IE) to prevent memory leaks.
This is without jQuery
link
window.onload = function () {
var el = document.getElementById('elementid');
el.onclick = function (e) {
var ev = e || window.event;
// here u can use this or el as the HTML node
}
}
You say you want to manipulate it with jQuery. So you can use jQuery. Than it is even better to do it like this:
// this is the window.onload startup of your JS as in my previous example. The difference is
// that you can add multiple onload functions
$(function () {
$('a#elementid').bind('click', function (e) {
// "this" points to the <a> element
// "e" points to the event object
});
});
Related
I want to get the href of an anchor element when it is clicked.
I am using the following javascript code:
document.addEventListener('click', function (event)
{
event = event || window.event;
var el = event.target || event.srcElement;
if (el instanceof HTMLAnchorElement)
{
console.log(el.getAttribute('href'));
}
}, true);
This works perfectly for an embedded anchor such as this:
<div><p><a href='link'></a></p><div>
But it doesn't work when I am working with an anchor and an image:
<div><a href='link'><img></a></div>
The event.target is returning the image instead of the anchor.
The javascript code can be amended with the following if case to get around this:
document.addEventListener('click', function (event)
{
event = event || window.event;
var el = event.target || event.srcElement;
if (el instanceof HTMLImageElement)
{
// Using parentNode to get the image element parent - the anchor element.
console.log(el.parentNode.getAttribute('href'));
}
else if (el instanceof HTMLAnchorElement)
{
console.log(el.getAttribute('href'));
}
}, true);
But this doesn't seem very elegant and I'm wondering if there is a better way.
!IMPORTANT!
NOTE: Keep in mind, I have no access to an ID or class, or any other traditional identifier for that matter. All I know is that there will be an anchor clicked and I need to get its href. I don't even know where it will be, if it exists or will be created later.
EDIT: Please no jQuery or other javascript libraries.
Instead of looping all anchors in the DOM, lookup from the event.target element.
Using JavaScript's .closest() MDN Docs
addEventListener('click', function (event) {
event.preventDefault(); // Don't navigate!
const anchor = event.target.closest("a"); // Find closest Anchor (or self)
if (!anchor) return; // Not found. Exit here.
console.log( anchor.getAttribute('href')); // Log to test
});
<a href="http://stackoverflow.com/a/29223576/383904">
<span>
<img src="//placehold.it/200x60?text=Click+me">
</span>
</a>
<a href="http://stackoverflow.com/a/29223576/383904">
Or click me
</a>
it basically works like jQuery's .closest() which does
Closest or Self (Find closest parent... else - target me!)
better depicted in the example above.
Rather than adding a global click handler, why not just target only anchor tags?
var anchors = document.getElementsByTagName("a");
for (var i = 0, length = anchors.length; i < length; i++) {
var anchor = anchors[i];
anchor.addEventListener('click', function() {
// `this` refers to the anchor tag that's been clicked
console.log(this.getAttribute('href'));
}, true);
};
If you want to stick with the document-wide click handler then you could crawl upwards to determine if the thing clicked is-or-is-contained-within a link like so:
document.addEventListener('click', function(event) {
event = event || window.event;
var target = event.target || event.srcElement;
while (target) {
if (target instanceof HTMLAnchorElement) {
console.log(target.getAttribute('href'));
break;
}
target = target.parentNode;
}
}, true);
This way at least you'd avoid writing brittle code that has to account for all of the possible types of anchor-children and nested structure.
How to apply live() like feature for JavaScript appended DOM elements?
Like a li list inside ul which is added through JavaScript. I need to do this in plain JavaScript.
Since .live() is simply event delegation, place your handler on the nearest element to the ones being added.
var container = document.getElementById('my_container');
container.onclick = function(e) {
e = e || window.event;
var target = e.target || e.srcElement;
while(target && target.nodeName.toUpperCase() !== 'LI' ) {
if( target === this )
target = null;
else
target = target.parentNode;
}
if( target ) {
// work with the LI
}
};
This is also similar to .live() in the sense that it searches from the e.target up to the container with the delegate to see if it is your targeted element.
Just testing the e.target itself isn't enough if the li has descendants.
For more complex analysis of the elements, you could use .matchesSelector, though you'd need to stick it on the HTMLElement.prototype under the correct name, since most browsers include it as an extension.
Also, you'd need a patch for IE8, but that's pretty easy.
if (HTMLElement) {
if (!HTMLElement.prototype.matches && !HTMLElement.prototype.matchesSelector) {
HTMLElement.prototype.matches =
HTMLELement.prototype.matchesSelector =
HTMLElement.prototype.webkitMatchesSelector ||
HTMLElement.prototype.mozMatchesSelecvtor ||
HTMLElement.prototype.msMatchesSelector ||
HTMLElement.prototype.oMatchesSelector;
}
} else if (!Element.prototype.matchesSelector && Element.prototype.querySelectorAll) {
Element.prototype.matches =
Element.prototype.matchesSelector =
function() {
// exercise for reader to implement using .querySelectorAll,
// though it's pretty easy, and available online if you search
}
}
You have to bind an event to the document root, and check the event.target property. If it matches the given selector, then do something.
Example (assuming addEventListener)
Example: Match all elements with id test:
var root = document.documentElement;
root.addEventListener('click', function(event) {
var target = event.target; // <-- Clicked element
while (target && target !== root) { // Tree traversing
if (target.id == 'test') { // <------ Matches selector
// Do something.
break; // Optional: Stop traversal, because a match has been found
}
target = target.parentNode; // Go up in the tree
}
}, true);
the live() is a function of jquery library
.live( events, handler(eventObject) )
events: A string containing a JavaScript event type, such as "click" or "keydown."
As of jQuery 1.4 the string can contain multiple, space-separated event types or custom event names.
handler(eventObject): A function to execute at the time the event is triggered.
for your example, when you created the li inside the ul, you have to you live to capture the li,e.g,
$('li').live('mouseover',function(){
alert('hello');
});
You can manually attach the event handler whenever you create a new element. Or, you can do it exactly how jQuery is doing it by looking into the jQuery library and extracting the parts you need.
I have the following event handler
document.addEventListener('keydown', handleBodyKeyDown, false);
HOW DO i prevent it from occurring when inside a input box
Within your handleBodyKeyDown function, check if
event.target.tagName.toUpperCase() == 'INPUT'
(or 'TEXTAREA').
Note: For older versions of IE, use event.srcElement.tagName.
Like so:
document.addEventListener('keydown', handleBodyKeyDown, false);
function handleBodyKeyDown(event)
{
var e = event || window.event,
target = e.target || e.srcElement;
if (target.tagName.toUpperCase() == 'INPUT') return;
// Now continue with your function
}
P.S. Why are you using addEventListener if you have jQuery on the page? In jQuery, all of this gets sorted out for you:
$(document).on('keydown', ':not(input)', function(e)
{
// Your code goes here...
});
In your handleBodyKeyDown method, check to see if the event originated on an input element:
function handleBodyKeyDown(event) {
if (event.target.tagName.toUpperCase() === 'INPUT') {
return; // do nothing
}
// do the rest of your code
}
Note that the toUpperCase call is necessary because the conditions that determine the case of the tagName property are quite complicated and sometimes all but uncontrollable.
See event.target at MDN.
If you are using jQuery you can try this which uses is() method to test the target element is input then do nothing.
function handleBodyKeyDown(event) {
if ($(event.target).is("input")) {
return;
}
else{
//Do your stuff here
}
}
This worked for me:
const fromInput = event => event.srcElement instanceof HTMLInputElement;
function handleBodyKeyDown(event) {
if(fromInput(event))
return;
// do your magic here
}
You could do something like:
handleBodyKeyDown = function(e) {
var e = e || window.event
if (e.target.tagName != "INPUT") {
// handle this since it isn't input
}
}
Sometimes (as to me) it is better not to prevent it to occur, but to ignore in the event cases, when it occured in the input. It's looks like this is also your case as well.
Just inspect evt.target || evt.srcElement property (modern frameworks do this normalization work for you, so, most probably this will be called target) whether it's input or not. If not, just ignore.
QuirksMode tells you how to get an event's target. You can check that it is not an input:
function doSomething(e) {
var targ;
if (!e) var e = window.event;
if (e.target) targ = e.target;
else if (e.srcElement) targ = e.srcElement;
if (targ.nodeType == 3) // defeat Safari bug
targ = targ.parentNode;
if( targ.tagName != "INPUT" ) {
//Perform your action here
}
}
Your question is tagged jQuery, in which case you can just test event.target as the framework normalizes this for you.
$(document).bind("keydown", function (event) {
if(event.target.tagName != "INPUT") {
//Do something
}
});
HandleBodyKeyDown function will be invoked in any case. You can not prevent its call on the method of recording as you indicated. You can only add a logic for checking if this an 'input' and return. Additionaly (if needed) you can prevent it from bubble up:
function handleBodyKeyDown(ev) {
ev=ev||event;
var sender=ev.target||ev.srcElement;
if(sender.tagName.toLowerCase()==="input") {
if(ev.stopPropagation)ev.stopPropagation();
else ev.cancelBubble=true; // for IE8 or less
return true; // do not prevent event from default action
}
// your code for global keydown
}
If you're using Prototype (which you have tagged but you also have two other frameworks tagged) then the event can be registered and filtered in one like this:
document.on('keydown', ':not(input)', handleBodyKeyDown);
I am try to catch form event in javascript
var event = window.event.srcElement;
This is working fine in IE, but in
Netscape/Firefox where event return undefined.
Can someone tel me how to catch event
in Netscape/Firefox?
IE and Netscape play different games.
But you can easily make it crossbrowser as such:
if (window.event) e = window.event;
var srcEl = e.srcElement? e.srcElement : e.target;
Use .target:
var event = event.target;
Or to check for both/fallback in a single statement:
function myHandler(event) {
var target = window.event.srcElement || event.target;
}
(In both cases... I'd rename your variable, since this isn't the actual event object, but an element.)
Is this possible?
I am attempting to write a function for onmousedown that will return the ID of the element you just clicked for later use in recreating that element in a different div.
You can use event delegation, to basically connect only one event handler to your entire document, and get the element which the event was originally dispatched, using event.target:
document.body.onmousedown = function (e) {
e = e || window.event;
var elementId = (e.target || e.srcElement).id;
// call your re-create function
recreate(elementId);
// ...
}
function recreate (id) {
// you can do the DOM manipulation here.
}
Edit: You can assign events to all your Scriptaculous draggables in this way:
Event.observe(window, 'load', function () {
Draggables.drags.each(function (item) {
Event.observe(item.element, 'mousedown', function () {
alert('mouseDown ' + this.id); // the this variable is the element
}); // which has been "mouse downed"
});
});
Check an example here.
CMS pretty much has the correct answer but you will need to make it a little more cross browser friendly.
document.body.onmousedown = function (e) {
// Get IE event object
e = e || window.event;
// Get target in W3C browsers & IE
var elementId = e.target ? e.target.id : e.srcElement.id;
// ...
}
Pls insert this code to your javascript.
document.getElementById("article").onmouseup(handMu);
If you want to replicate the div id, an easy way might be cloneNode like this:
<div id="node1">
<span>ChildNode</span>
<span>ChildNode</span>
</div>
<div id="container"></div>
<script type="text/javascript">
var node1 = document.getElementById('node1');
var node2 = node1.cloneNode(true);
node2.setAttribute('id', 'node2');
var container = document.getElementById('container');
container.appendChild(node2);
</script>