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.

Russell
  • 655
  • 2
  • 9
  • 21
  • 1
    By adding it as id, it will be easy – Sunny Jul 11 '13 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. – Ariane Jul 11 '13 at 21:17
  • 1
    Learn about event handling: http://www.quirksmode.org/js/introevents.html. – Felix Kling Jul 11 '13 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? – Teemu Jul 11 '13 at 21:27
  • Possible duplicate: [How can you detect which element in a class was clicked on with Javascript?](http://stackoverflow.com/questions/17289558/how-can-you-detect-which-element-in-a-class-was-clicked-on-with-javascript) – Xotic750 Jul 11 '13 at 21:40
  • @Xotic750 Thanks for the link. Is this likely to have caused my down vote? – Russell Jul 11 '13 at 21:45
  • There are a number of other similar questions and answers here on SO too. But it is more likely because you didn't demonstrate anything that you had tried, other than saying that you had searched. It's a pity when down voters do not comment. – Xotic750 Jul 11 '13 at 21:47
  • @Xotic750 I appreciate the feedback. I'm aware that this q may have appeared a bit vague. – Russell Jul 11 '13 at 22:04

6 Answers6

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.

Will M
  • 2,135
  • 4
  • 22
  • 32
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)
}
Travis J
  • 81,153
  • 41
  • 202
  • 273
  • 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? – klewis Jul 11 '13 at 22:00
  • @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. – Travis J Jul 11 '13 at 22:02
  • 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. – klewis Jul 12 '13 at 14:34
  • 1
    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? – klewis Jul 12 '13 at 14:52
  • @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). – Travis J Jul 12 '13 at 17:04
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);
Givi
  • 1,674
  • 2
  • 20
  • 35
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.

Justin Self
  • 6,137
  • 3
  • 33
  • 48
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

Xotic750
  • 22,914
  • 8
  • 57
  • 79
-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>
Seano666
  • 2,238
  • 1
  • 15
  • 14