3

I'm trying get the element clicked within a TR in a HTML table. If I click on the Select input inside a TR, CurrentTarget field returns "TR", and OriginalTarget returns "SELECT".

This is my HTML:

<table id="0" class="tableEdit">
    <thead>
        <tr>
            <th name="id"></th>
            <th name="name">Descripción Registro</th>
            <th name="select">Fecha</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>1651</td>
            <td>Name</td>
            <td>
                <select name="selectName">
                    <option value="1">1</option>
                    <option value="2">2</option>
                </select>
            </td>
        </tr>
    </tbody>
</table>

And this is my code:

            //trb is each TR element of the line
    $(trb).click(function(elem){
        if (elem.currentTarget && elem.currentTarget.tagName.toLowerCase() === "tr" && !isInput(elem.originalTarget)){
            if (editableRow){
                var rowTrigger = editableRow.find("button").get();
                $.editRow(rowTrigger,$.tableEditor.vault.getTableID($("#" + id)));
            }
    });

This code is working fine on my web browser, but it doesn't on mobile devices, because OriginalTarget returns undefined. Is there any way to get the original target on a mobile web browser?

Amin Abu-Taleb
  • 4,423
  • 6
  • 33
  • 50

2 Answers2

3

You haven't actually said what trb is but it sounds like it might be a set of the tr elements in your table.

What you're looking for is elem.target. That's the topmost element that was clicked, the one that initiated the event. (FWIW, I wouldn't call the argument passed to the event handler elem, it's an event, not an element.)

For instance, if you have:

<table>
<tbody>
<tr>
<td><span><strong>Click me</strong></span></td>
</tr>
</tbody>
</table>

...and this:

$("tr").click(function(e) {
    console.log(e.target.tagName);
});

...and you click the text "click me," you'll see

STRONG

...in the console.


Side note: It's handy to use closest with that if you want to know what cell or row was clicked, e.g.:

var $td = $(e.target).closest('td');
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • element that was clicked is `currentTarget` , no? – Ivan Chernykh Sep 11 '13 at 07:11
  • 1
    @Cherniv: No, `currentTarget` is the same as `this` (usually). It refers to the element the handler was *bound* to. – Felix Kling Sep 11 '13 at 07:12
  • @Cherniv: No, it's `target`. All the gory details: http://www.w3.org/TR/DOM-Level-3-Events/#events-event-type-target – T.J. Crowder Sep 11 '13 at 07:13
  • @FelixKling ok , that's why his `currentTarget` returns `tr` , cause he binded like this: `$(trb).click(...` – Ivan Chernykh Sep 11 '13 at 07:17
  • @T.J.Crowder these two names are very confusing , more intuitive to think that `currentTarget` is a "topmost element" , isn't it? – Ivan Chernykh Sep 11 '13 at 07:19
  • @Cherniv: I don't think it is, no, not if you look at how event dispatch occurs. Ignoring the capturing phase for simplicity, the event starts at `target`, and the handlers (if any) on `target` are called with both `target` and `currentTarget` set to the same (topmost) element. Then the event bubbles to that element's parent, whose handlers are called with `target` being the original element and `currentTarget` being the parent -- e.g., the *current* target of the event in the bubbling. Rinse, repeat. – T.J. Crowder Sep 11 '13 at 07:34
0

To properly understand you need to know the basics of javascript.

most of the browser especially modern ones like mobile use standard javascript like:

element.addEventListener //to add Event Handlers
//those eventListeners return always the event as first parameter
//and this event contains the target which can be called with
event.target

but older browsers or internet explorer uses different ways to achieve this

attachEvent //to add eventListener
// the event needs to be called with
window.event
// and the target is called
event.srcElement

knowing that you can write a function like this:

//addEvent checks if addEventListener exists else it uses attachEvnet
//as you can see attachEvent also has only 2 parameters and needs a 'on'
//before the event name
function addEvent(a,e,f){//Element,Event,Function(the actual eventHandler)
 window.addEventListener?a.addEventListener(e,f,false):a.attachEvent('on'+e,f);
}

//handler handles in this case the click event
//it checks if the first parameter is event else it uses the window.event
//it checks if inside the event exists a event.target else event.srcElement
//then it loops through the parentNode until it finds(this case) the TR Element
//and just to test it alerts the content of it
//if you want to get the TD element replace e.target.parentNode with e.target
//and TR with TD
// so you get the proper row or column clicked.
function handler(e){
 e=e||window.event;
 e.target=e.target||e.srcElement;
 var x=e.target.parentNode;
 while(x.nodeName!='TR'){//or x.localName but thats lowercase 'tr'
  x=x.parentNode;
 }
 alert(x.innerHTML);
}

//when the page loads it it searches for the first table (note the [0])
//and adds a eventListener to the whole table.
//this allows you to have one eventListener on the full table but
//control every single row or column.
window.onload=function(){
 var table=document.getElementsByTagName('table')[0];
 addEvent(table,'click',handler);
}

thats why jQuery exists... to avoid all this double checks.

anyway ... after some tests and as mobile browsers support the modern standard ways... i prefer to leave out jQuery from mobile webapps as it just slows down everything.

So for mobile devices i use:

function handler(e){
 var x=e.target;
 while(x.nodeName!='TR'){
  x=x.parentNode;
 }
 console.log(x.innerHTML);
}
window.onload=function(){
 var table=document.getElementsByTagName('table')[0];
 table.addEventListener('click',handler,false);
}
cocco
  • 16,442
  • 7
  • 62
  • 77