views:

118

answers:

4

I can't find any good documentation on this suprisingly so I'm posting it here.

What's the raw javascript equivilent to this:

$(elem).click(function(){
    alert(this.text());
});

All I can find is this <elem onlick="func()" /> which is not what I want, I want to be able to do it just with javascript not within the context of an element.

+4  A: 

You can do object.onclick = handler

var el = document.getElementById('elem');
elem.onclick = function(){ alert("Clicked!") };

That should work - i'm a bit ropey on javascript nowadays!

adam
A: 

Maybe you need something like that:

document.getElementById('element_id').setAttribute("onclick","alert('hello world')");
Evgeniy
Don't use `setAttribute` on HTML documents. There are bugs in it in IE, which will stop many attributes from working, including `onclick` and all the other event handlers. Use the DOM Level 1 HTML properties like `elem.onclick= function() {...};` instead: they are more reliable and easier to read.
bobince
+6  A: 

Assuming elem is an element node (if not, you'll need to work your selector into use of getElementById or whatever):

elem.onclick= function() {
    var text= 'textContent' in elem? elem.textContent : elem.innerText;
    alert(text);
};

textContent is the standards-compliant way of getting text from an element; innerText is the IE way. (There are a few differences, but hopefully nothing that will affect you.) If you need to support old/obscure browsers that have neither you would have to do an tedious tree-walk to pick up all text (this is what jQuery's text() does.)

(I'm assuming that's what you want from this.text(). That wouldn't actually work — presumably you meant $(this).text().)

bobince
Beat me to it by seconds :)
Tim Down
I enjoy the simple-JS-question typing races!
bobince
@Tim: They do say great minds think alike ;-)
Andy E
What's wrong with `elem.textContent || elem.innerText`?
J-P
@J-P: fails when `textContent` is present but a blank string.
bobince
In that case, can't you use `elem.innerText || elem.textContent`?
Marcel Korpel
@Marcel Korpel, no, you would still have the same problem. For example, if you're using IE and the `innerText` of an element is `""`, the false-like value forces `|| elem.textContent` to be evaluated and will yield `undefined` because the property does not exist in IE. Using the `in` operator is the best method of feature detection where a falsey value is possible on the property you're testing for.
Andy E
@Andy: Of course, I already wondered when `textContent` or `innerText` could be defined but containing `""`. Stupid me! :)
Marcel Korpel
Aside: I prefer to use `in` for feature detection even when a falsey value isn't possible, as it's the more explicit way to say what you're doing. However, there is one case where you shouldn't use it: `window.XMLHttpRequest`. Because when native-XHR is disabled in IE7+, the property is defined but set to `null`.
bobince
+5  A: 

There are several ways to attach a click handler without using a library. The first is assigning a function to the on[eventname] property of an element:

element.onclick = function (eventObj) { 
    alert("textContent" in this ? this.textContent : this.innerText) 
}

You can also assign a string of code to be evaluated but it's not as pretty and generally avoided. Another way is to use the w3c standard addEventListener:

element.addEventListener("click", function (eventObj) { 
    alert("textContent" in this ? this.textContent : this.innerText) 
}, false);

This is not supported by current versions of IE which require attachEvent instead:

element.attachEvent("onclick", function () { 
    alert(event.srcElement.innerText); 
});

IE has problems applying the function to the element that fired the event, so this will not correctly point to that element with attachEvent.

The first method element.onclick is useful for x-browser compatibility and quick coding, but you can only assign a single function to the property. Using attachEvent and addEventListener you can attach as many functions as you like and they will all fire correctly. You can create a cross browser semi-equivalent doing simple functionality checks in your code:

if ("addEventListener" in element)
    element.addEventListener("click", function (eventObj) { 
        alert("textContent" in this ? this.textContent : this.innerText) 
    }, false);
else
    element.attachEvent("onclick", function () { 
        alert(event.srcElement.innerText); 
    });
Andy E
Great method of feature detection!
Marcel Korpel
+1 good explanation of the pros and cons of trad event handlers vs listeners. (More detail than I could be bothered to type :-)) I'd definitely check for the presence of the standard `addEventListener` first though, so that that method is used in preference where both are available (Opera, IE9).
bobince