Javascript在下拉列表选择中停止TR单击事件

时间:2017-10-24 11:08:16

标签: javascript html html-select

我想捕获从下拉列表中选择的选项。这里的问题是当点击选项时调用TR点击事件是因为select没有点击事件。 单击下拉菜单时如何停止TR点击事件?

<html>
<script>
    function check1() {
        alert("TR clicked");
    }

    function check2() {
        alert("drop_down clicked");
    }
</script>
<table border=1>
    <tr onclick="check1();">
        <td>My Options</td>
        <td>        
            <select name="" id="drop_down" onchange="check2();">
              <option value="A">A</option>
              <option value="B">B</option>  
            </select>           
        </td>
    </tr>
</table>

5 个答案:

答案 0 :(得分:1)

您需要在click上捕获<select>事件并阻止其传播:

function onSelectClick(ev) {
  ev.stopPropagation();
}
<select onclick="onSelectClick">

或者您可以尝试简单地为false的{​​{1}}事件返回click

<select>

答案 1 :(得分:1)

您可以检查触发点击的元素,如果是下拉列表,则忽略该事件:

font-family

jsfiddle sample

如果您希望JS更通用而不检查元素的特定ID,您还可以更改其逻辑以查找定义了自定义属性的元素:

function check1(e) {
    if (typeof e == "undefined")
        e = window.event;
    if (e.srcElement.id != "drop_down") {
        alert("TR clicked");
    }
}

要使其与您的代码一起使用,请将HTML更改为:(属性的值无关紧要)

function check1(e) {
    if (typeof e == "undefined")
        e = window.event;
    if (e) {
        var sourceElement = e.srcElement || e.target;
        if (sourceElement) {
            if (sourceElement.getAttribute("data-stop-propagation")) {
                //element being clicked asked to ignore the event, abort
                return;
            }
        }
    }
    alert("TR clicked");
}

updated fiddle

答案 2 :(得分:1)

你可以做的另一件事就是获得事件目标,

  function check1() {
   if(this.event.target.nodeName!=='SELECT'){
    alert("TR clicked");
   }
}

支持所有浏览器只捕获事件并将其作为参数传递

<tr onclick=check1(event)>....</tr>
//in js
function check1(event) {
   if(event.target.nodeName!=='SELECT'){
    alert("TR clicked");
   }
}

答案 3 :(得分:1)

使用addEventListener()代替内联属性eventHandlers。在eventListener()的末尾,或在回调结束时,添加e.stopPropagation(),以便事件永远不会起泡,从而永远不会到达<tr>

<tr>需要引用,因为它相对于另一个表组件,例如<table><td>。虽然内联属性事件适用于任何事物(包括<tr>标记),但它对维护这样的布局会有害(因为我怀疑它已经发生)。这就是为什么强烈建议使用addEventListener()而不是内联事件的原因。

在以下演示中:

  • 如果单击<select>,则控制台会记录其值。

  • 如果点击<td>,则会记录一般的“点击”

  • 它不会同时记录点击事件

支持所有现代浏览器

详情在演示

中发表

演示

var table = document.querySelector('table');

function chk() {
  var drop = document.getElementById('drop');
  var val = drop.value
  console.log(val);
}

function rowLog() {
  console.log('Clicked');
}

table.addEventListener('click', function(e) {
  /* if the clicked element (e.target) is NOT
  || the element registered to listen for
  || click event (table) then...
  */
  if (e.target !== e.currentTarget) {

    /* if clicked element's #id is drop
    || call function chk()
    */
    if (e.target.id === 'drop') {
      chk();
      
      /* Stop the event from bubbling (thereby 
      || event never reaches TR if #drop is clicked)
      */
      e.stopPropagation();
    }
    /* TR is tightly integrated with TD so
    || target TD or spicify TBODY or TABLE
    || to reference TR.
    || Note e.stopPropagation() is not invoked
    || in this function so click event will
    || bubble to <tr>
    */
    else if(e.target.tagName === 'TD') {
      rowLog();
    }
  }
  
}, false);
<table border=1>
  <tr>
    <td>My Options</td>
    <td>
      <select name="" id="drop">
              <option></option>
              <option value="A">A</option>
              <option value="B">B</option>  
            </select>
    </td>
  </tr>
</table>

答案 4 :(得分:0)

我发现此解决方案最适合我:

position:fixed

此解决方案的优点是,它适用于所需目标元素内的所有子元素。例如,此逻辑在单击选择元素时起作用,并且在单击选择元素内的任何选项时也起作用。

缺点:路径数组需要循环通过。