无法单击子元素,因为父级始终处于焦点

时间:2017-10-02 09:32:35

标签: javascript d3.js

我有一个按钮列表,在悬停时,按钮的右上角会出现一个小(x)。我试图在(x)上附加一个点击处理程序,但是,当我点击它时,点击实际按钮,而不是(x)。

代码:

btnArray.forEach(function (button) {

    const btn = document.createElement('div');
    btn.type = 'button';
    btn.value = button.name;
    btn.onClick = evt => {
        // do soemthing on click
    }

    btn.onmouseover = function(e) {
        var me = d3.select(btn);
        me.append('div')
            .classed({'btn-close': true})
            .append('div')
            .classed({'btn-x-icon': true})
            .text('x')
            .on('click', function() {
                alert('you clicked on the x!');
            });
    }

    btn.onmouseout = function(e) {
        var me = d3.select(btn);
        me.selectAll('.btn-close')
            .remove();
    }

    btn.appendChild(document.createTextNode(button.name))

});

即使我将鼠标放在(x)上,父按钮仍然显示为焦点。

更新

我可以通过增加(x)图标的z-index来点击图标。

然而,点击时,会调用(x)onclick以及主要的btn.onclick调用。

更新

标记:

<button type="button" value="Checkout" class="btn btn-primary">
    Check out

    <div class="btn-close">
        <div class="btn-x-icon">x</div>
    </div>

</button>

2 个答案:

答案 0 :(得分:1)

使用event.target,您可以确保只响应所点击的正确元素。

  

在下面的示例中,我只添加了标识符,因此我可以附加标识符   点击事件更容易演示,但事件中的代码   处理程序适用于您的代码。

     

另请注意,我没有在处理程序中指定event参数   因为在指定参数时会自动分配event   对于'click', function(evt)这样的事件,你现在正在使用   d3指定的事件对象,可能是也可能不是同一事件   对象

&#13;
&#13;
var button = document.getElementById("button");
button.addEventListener('click', function() {
  if (event.target == this) {
    console.log('button clicked')
  }
})

var button = document.getElementById("close");
button.addEventListener('click', function() {
  console.log('close clicked')
})
&#13;
#close {
  background-color: red;
}
&#13;
<button id="button" type="button" value="Checkout" class="btn btn-primary">
    Check out
    <div id="close" class="btn-close">
        <div class="btn-x-icon">x</div>
    </div>

</button>
&#13;
&#13;
&#13;

或者您可以使用stopPropagation

&#13;
&#13;
var button = document.getElementById("button");
button.addEventListener('click', function() {
  console.log('button clicked')
})

var button = document.getElementById("close");
button.addEventListener('click', function() {
  event.stopPropagation();
  console.log('close clicked')
})
&#13;
#close {
  background-color: red;
}
&#13;
<button id="button" type="button" value="Checkout" class="btn btn-primary">
    Check out
    <div id="close" class="btn-close">
        <div class="btn-x-icon">x</div>
    </div>
</button>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

您应该在点击时停止传播事件。该事件一旦产生,就会传播到所有固有元素。您应该停止该传播,以避免为该事件执行更多处理程序。

有关该事件冒泡(以其他方式)和传播的更多信息 http://www.javascripter.net/faq/eventbubbling.htm https://www.sitepoint.com/event-bubbling-javascript/

btnArray.forEach(function (button) {

    const btn = document.createElement('div');
    btn.type = 'button';
    btn.value = button.name;
    btn.onClick = evt => {
        // do soemthing on click
    }

    btn.onmouseover = function(e) {
        var me = d3.select(btn);
        me.append('div')
            .classed({'btn-close': true})
            .text('x')
            .on('click', function(evt) {
                evt.stopPropagation();
                alert('you clicked on the x!');
            });
    }

    btn.onmouseout = function(e) {
        var me = d3.select(btn);
        me.selectAll('.btn-close')
            .remove();
    }

    btn.appendChild(document.createTextNode(button.name))

});