9
<tr class="DesignedTableTR" onclick="OpenAdPreview()">
    <td></td>
    <td></td>
    <td></td>
    <td></td>
</tr>

I want that the onclick will be set on all the td-s except for the second td.

I know I can do it like:

<tr class="DesignedTableTR">
    <td onclick="OpenAdPreview()"></td>
    <td></td>
    <td onclick="OpenAdPreview()"></td>
    <td onclick="OpenAdPreview()"></td>
</tr>

but maybe there is another efficient way..

4

7 回答 7

10

另一种做事方式

<tr class="DesignedTableTR" onclick="OpenAdPreview()">
<td></td>
<td onclick="event.cancelBubble=true; return false;"></td>
<td></td>
<td></td>

于 2015-06-21T08:41:50.967 回答
6

使用:not():nth-child()选择器。

$("tr.DesignedTableTR > td:not(:nth-child(2))").on("click", OpenAdPreview);
于 2013-09-08T11:40:22.697 回答
2

如果您使用的是jQuery ,答案 1 是可以的。如果您使用支持querySelectorAll.

第二个也有一个缺点:它将事件侦听器分配给所有<td>s,这是一种非常繁重的方法。您第一次尝试仅将事件处理程序放在 上<tr>实际上更轻量级(顺便说一下,这称为事件委托)但有一点缺点:您必须过滤掉正确的元素。

因此,如果您想坚持跨浏览器“香草 javaScript ”,您可能需要尝试以下操作:

首先将thisandevent作为函数调用的参数:onclick="OpenAdPreview(event, this)",然后将函数更改OpenAdPreview为:

function OpenAdPreview(event, that){
    var e = event || window.event,
        elm = e.target || e.srcElement,
        allTDs = that.getElementsByTagName('td');

    while (elm.nodeName.toLowerCase() !== 'td' && elm !== that) {
        elm = elm.parentNode; // get the right element if it's not the td already
    }

    if (elm !== allTDs[1] && elm !== that) { // this filters out your second td
        ... here goes your code
    }
}

that提供<tr>您可以查找所有tds 的位置getElementsByTagName,然后过滤掉。

另一种(更好的)方法是将类名分配给td您不想单击的类名并按其过滤:<td class="dont-touch-me"></td>然后在您的代码中:

if ((' ' + elm.className + ' ').indexOf('dont-touch-me') < 0) { ...

这样你就不会让你的代码依赖于你的布局。然后总是保存以更改 HTML 标记的类名,并且您的代码仍然按预期工作。

顺便说一句:内联事件不是一个好方法。尝试坚持使用传统的事件处理程序分配,例如.addEventListener,.attachEventjQuery.on()事件处理。这样您也不必为this,thatevent.

添加了一个 JSFiddle:http: //jsfiddle.net/5zxun/4/

于 2013-09-08T12:38:06.657 回答
2

如果您使用 jQuery,首先您可能希望坚持使用事件委托,因为它更轻量级,其次,您希望将 HTML 与 JavaScript 代码分开,这意味着:如果您决定让您的布局有所不同,假设您的第二个<td>现在应该是可点击的,但不是你的第三个和你的第七个......那么你必须改变你的代码。

如果您为您<td>的 s 分配类,那么您只需更改您的 HTML 并且您的代码将按预期工作。

<tr class="DesignedTableTR">
    <td></td>
    <td class="dont-toch-me"></td>
    <td></td>
    <td></td>
    <td></td>
    <td class="dont-toch-me"></td>
    <td></td>
</tr>

在你的代码中你做:

$("tr.DesignedTableTR").on("click", "td:not(.dont-toch-me)", function(event){
    // ... here goes your code
});

因此,事件(并且只有一个)位于,<tr>第二个参数.on是您的过滤器。这称为事件委托

JSFiddle:http: //jsfiddle.net/5zxun/9/

于 2013-09-08T14:21:55.387 回答
2

那么你可以这样做:

// its zero-based so second td would be at 1st index, so bind all td's onclick instead of second td
$("tr.DesignedTableTR > td:not(:eq(1))").on("click",function(){
    alert("clicked :" + $(this).html());
});

在这里工作小提琴:http: //jsfiddle.net/5zxun/2/

我希望它有帮助。

于 2013-09-08T12:05:46.030 回答
1

普通(但“现代”)的 JavaScript 解决方案:

var tds=document.querySelectorAll("tr.DesignedTableTR td:not(:nth-of-type(2))");
var len = tds.length;
for(var i=0; i< len; i++){
    tds[i].onclick=function(){
        //.. here you go
    }
}

JSFiddle:http: //jsfiddle.net/cherniv/5zxun/

于 2013-09-08T11:42:47.453 回答
1

您可以根据需要使用 td 的索引值来防止点击事件。

$(document).ready(function(){
$('tr.DesignedTableTR td').click(function(){
    if($(this).index()==1){
    ev.preventDefault();
        return false;
    }else{
    alert($(this).index());
    //your code here
    }
});
});

JSFiddle:http: //jsfiddle.net/5zxun/1/

于 2013-09-08T12:06:41.750 回答