0

I have several spans labelled.

<span class="viewEdit">View and edit class one.</span>
<span class="viewEdit">View and edit class two.</span>
<span class="viewEdit">View and edit class three.</span>
<span class="viewEdit">View and edit class four.</span>
<span class="viewEdit">View and edit class five.</span>

I would like to create a function that adds an 'on click' event which detects which of the spans was clicked. I.e. if the first was clicked first it will return '0', the second '1'... etc.

I realise I can use

document.getElementByClassName("viewEdit)

to create an array, but I am not sure how to detect which one has been clicked.

I've tried to research the question here but suspect I am phrasing it wrong as I can find nothing. Apologies if this a re hash of a similar question answered elsewhere.

8
  • 1
    By adding it as id, it will be easy <span class="viewEdit" id="0"> Commented Jul 11, 2013 at 21:17
  • Uhm, this, inside an event function, refers to the object that activated the function. If you need a number, uhm, maybe there's a function that'll tell you, dunno. Or you can do it the cheap, dirty way and give each one an unique ID/name. Commented Jul 11, 2013 at 21:17
  • 1
    Learn about event handling: quirksmode.org/js/introevents.html. Commented Jul 11, 2013 at 21:19
  • "onclick... will return '0'" Where this "returnValue" is supposed to use? Events are fired by browser, and return values are returned to the browser, what you actually try to achieve? Commented Jul 11, 2013 at 21:27
  • Possible duplicate: How can you detect which element in a class was clicked on with Javascript? Commented Jul 11, 2013 at 21:40

6 Answers 6

5

You handler will be passed an event object.

function myHandler(event) {
  var el = event.target;
  // Use el here
}

event.target will hold the node that was clicked.

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

Comments

2

jsFiddle Demo

Attach a click handler to each element. When clicked have the callback reference the element which caused the handler to fire, and then make some inference there about what the index is relative to the other elements.

Inside of the event handler, this will refer to the element which fired the event.

To accomplish this, you can iterate through the set of elements with your class name

var els = document.getElementsByClassName("viewEdit");
var elClicked = {};//a public variable in case you wish to use it. the requirements for storage was vague
for( var i = 0; i < els.length; i++ ){

And then inside of the iteration, assign an event handler, and store the index which was used so you can know what number was clicked (this requires a closure).

for( var i = 0; i < els.length; i++ ){
 (function(local){
  els[i].onclick = function(){
   elClicked.element = this;
   elClicked.text = this.innerText;
   elClicked.index = local;
  };
 })(i)
}

5 Comments

very cool, but how to you get 1 or 2 or 3, etc...when you click on each span tag. the length position of that specific item when it's clicked?
@blachawk - If you wanted that instead of the index, you would use elClicked.index = local +1 as the index currently represents the 0 based position in the elements array.
thank you so much for the insight. If you don't me asking one more question and I don't mean to take away from the context of this original discussion in anyway, but I really love your solution. the part at the end of your script... the (i), I notice if I remove the i, i get undefined results, but if I use (i), i get the appriopriate values. Whats going on here in that part of your code? i.e., why place the (i) there to begin with for your self-invoking function? thanks for any insight.
I think I get it now, as you mentioned too...You are storing an index (i) into a closure function. Anything that need to come into the closure, needs to be stored there, and in this case its (i). And local represents the target item right?
@blachawk - The (i) will pass the value of i into the function. Once passed in, i is mapped to the function's argument variable, which I named local. So essentially, local = i;. This is done because without the closure, i would always be the last value of the loop, 5 (because there are 4 elements in els, and once i becomes 5 it breaks out of the loop).
1

So, this will let you find the clicked item's index in the collection.

var elements = document.getElementsByClassName("viewEdit");

for (var i = 0; i < elements.length; i++) {
    (function (index) {
        elements[index].addEventListener("click", function () {
            for (var x = 0; x < elements.length; x++) {
                if (elements[x] === this) alert(x);
            }

        }, false);
    })(i);
}

It's a quickie but should do what you are asking thus far... Here is a fiddle for you.

Comments

1

Easiest way to get parent node of your span elements and then add event handler...
Live Demo

var eles = document.getElementsByClassName("viewEdit");

eles[0].parentNode.addEventListener("click", function (e) {
    // if (e.target.classList.contains("viewEdit")) {
    if (e.target.nodeName.toLowerCase() === "span") {
        alert([].indexOf.call(eles, e.target));
    }
}, false);

Comments

0

You could add a click event listener to document.body which will catch all clicks, and then filter by the tag type and the elements class. Something like this.

Javascript

/*jslint maxerr: 50, indent: 4, browser: true */

(function () {
    "use strict";

    function addEvent(elem, event, fn) {
        if (typeof elem === "string") {
            elem = document.getElementById(elem);
        }

        function listenHandler(e) {
            var ret = fn.apply(null, arguments);

            if (ret === false) {
                e.stopPropagation();
                e.preventDefault();
            }

            return ret;
        }

        function attachHandler() {
            window.event.target = window.event.srcElement;

            var ret = fn.call(elem, window.event);

            if (ret === false) {
                window.event.returnValue = false;
                window.event.cancelBubble = true;
            }

            return ret;
        }

        if (elem.addEventListener) {
            elem.addEventListener(event, listenHandler, false);
        } else {
            elem.attachEvent("on" + event, attachHandler);
        }
    }

    function whatClicked(e) {
        var target = e.target;

        if (target.tagName.toUpperCase() === "SPAN" && /(^| )viewEdit( |$)/.test(target.className)) {
            console.log(target);
        }
    }

    addEvent(document.body, "click", whatClicked);
}());

On jsfiddle

Comments

-2
<span class="viewEdit" onclick:"fn(this)">View and edit class one.</span>
<span class="viewEdit" onclick:"fn(this)">View and edit class two.</span>
<span class="viewEdit" onclick:"fn(this)">View and edit class three.</span>
<span class="viewEdit" onclick:"fn(this)">View and edit class four.</span>
<span class="viewEdit" onclick:"fn(this)">View and edit class five.</span>

<script type="text/javascript">
   function fn(sender){
  //add the sender object to your array
  //or maybe even just the sender's id
}
</script>

2 Comments

It's better to use unobtrusive Javascript.
I appreciate the constructive comment, so many people just kill with downvotes.

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.