4

This is the jQuery code I have

$('p').click(function(){
    alert("click successful!");
});

This is the JS code I could come up with

window.onload = function() {
    var para = document.getElementsByTagName('p');
    for(var i = 0; i < para.length; i++) {
        para[i].addEventListener('click',function(){
            alert("click successful!");
        });
    }
}

The Javascript code is too bulky, is there a way where I can select a tag by its name and write the code as -

"If any 'p' tag is clicked, alert('click successful')"

instead of looping through all the <p></p> tags? Any alternative way using tag name?

13
  • do you want do it without using jquery? Commented Oct 25, 2015 at 14:09
  • 2
    Why you are want to do it without jQuery if pure JS is too bulky for you? =) Commented Oct 25, 2015 at 14:12
  • 2
    "The Javascript code is too bulky" — It's shorter than the jQuery code (which is the code you provided, plus the parts of the jQuery library which do the loop that your non-jQuery code does, plus the parts of the jQuery library that you aren't using). Commented Oct 25, 2015 at 14:15
  • 1
    My point was that people write helper libraries like jQuery for a reason. If you don't want to do things the long way, then the best way to deal with that is usually to use code written by someone else. Commented Oct 25, 2015 at 14:18
  • 1
    @Sidsec9 In that case, look up Sizzle - iirc that's what jQuery uses under the hood for selectors. Commented Oct 25, 2015 at 14:21

4 Answers 4

7

You can use event delegation - add a click handler to a higher level element and check event.target

document.body.addEventListener("click", function(e) {
    if (e.target.tagName.toLowerCase() == "p") alert("click succeeded");
});

Demo: http://jsfiddle.net/jdkr3sch/

Sign up to request clarification or add additional context in comments.

3 Comments

This doesn't work. Or rather, it only works if there is nothing but text in the paragraph. As soon as you add any element, even an innocent <span>, clicking on that child element won't trigger the alert.
As a side note, nodeName is usually a better choice stackoverflow.com/questions/4878484/… And ya, you should check for any ascendant node or node itself being a P element
@NiettheDarkAbsol It's wrong to say "this doesn't work" but that is a noteworthy caveat. Once you add in the check for descendants you're back to the bulk that OP wanted to avoid though.
3

jQuery is "less code" because you're calling a pre-written function. Don't want to use jQuery? Then write your own functions.

function addEventToElements(tagname,handler) {
    var elems = document.getElementsByTagName(tagname);
    for(var i = 0, l = elems.length; i<l; i++) {
        elems[i].addEventListener('click',handler);
    }
}

Now in your actual code, you can just write:

addEventToElements('p',function() {alert("click succeeded");});

Congratulations, you have re-invented jQuery.

... Or not, because the reason jQuery is so popular is that it does a lot more. Things like normalising browser support (for those that use attachEvent or the old onEventName handlers) are half the reason jQuery exists, and you'd have to account for all of them in your own re-invention ;)

4 Comments

If we want to be really pedantic, this still missing some support for browsers which don't support addEventListener() method, so no, this isn't equivalent to jQuery method :)
@A.Wolff What about jQuery 2.0 then? :p
Ok then... But you could mention it in answer itself maybe
@A.Wolff There we go, added a note ^^
3

Here's a shorter way.

document.addEventListener('DOMContentLoaded', function() {
    document.body.addEventListener('click', function(evt) {
        if (evt.target.matches('p, p *')) alert('Paragraph clicked!');
    }, false);
}, false);

Notes:

1) This has the advantage of event delegation, which is something I'd suggest looking into. In a nutshell, means you bind the event once, not N times, and then interrogate which element fired it when it fires, i.e. in the callback, not at the point of declaring the event as you are currently.

2) For waiting to use elements, use the DOMContentLoaded event rather than window.onload - the former is (loosely) analogous to jQuery's DOM ready handler.

3) matches() is a relatively modern method and won't work in ancient browsers, or may need a vendor-prefixed version - http://caniuse.com/#feat=matchesselector

1 Comment

This is functionally identical to Dennis' answer, and suffers the same problem. <p><span>Can't touch this.</span></p>
1

for selecting:

document.querySelectorAll('p')

(also for more than one element p ).

AFAIK this is the closest thing to $('p')


addEventListener('click',function(){alert("click successful!")}

to add click handler to single element.


to simulate an array you can use the [].slice.call on the dom element collection (in this way you use .forEach() method) .


all together:

[].slice.call(document.querySelectorAll('p')).
forEach(function(x){x.addEventListener('click',
    function(){alert("click successful!")
})})

https://jsfiddle.net/maio/m861hbmh/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.