我在动态创建元素的表中遇到了有关事件传播的问题。

当我单击div“菜单”(我们称其为“按钮”)时,发生onclick操作。
我需要不执行该动作。

我在“按钮”功能中添加了event.stopPropagation();,但这并没有任何改变。

有关工作示例,请参见以下代码段:



// Open menu function
function open_menu(elm) {
  elm.css({
    "top": PosY,
    "left": PosX
  }).fadeIn(200);
}

// Mouse move
var PosX, PosY;
$(document).mousemove(function(e) {
  PosX = e.pageX;
  PosY = e.pageY;
});

// If document is clicked somewhere else than the menu, close menu
$(document).on("mousedown", function(e) {
  $(".menu").fadeOut(100);
});

// I bind my function on click, on the menuBtn.
// I am doing it this way because .menuBtn are created dynamically
$('table').on('click', '.menuBtn', function(event) {
  event.stopPropagation(); // Why it isn't working ?
  open_menu($(this).closest('tr').find(".menu"));
});

* {
  margin: 0;
  padding: 0;
}

p {
  display: inline-block;
  cursor: inherit;
}

table {
  table-layout: fixed;
  width: 100%;
  border: 0;
  border-collapse: collapse;
  margin-bottom: 800px;
}

tr {
  background-color: #eee;
  cursor: pointer;
}

td {
  position: relative;
  padding-left: 10px;
  height: 64px;
}

.menuBtn {
  position: absolute;
  display: inline-block;
  left: 100px;
}

.menu {
  position: fixed;
  display: none;
  background: #f8f8f8;
  border: 2px solid #888;
  height: 80px;
  width: 100px;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body>
  <table>
    <tbody>
      <tr onclick="console.log('I do not want to see that.')">
        <td>
          <p>Element</p>
          <div class='menuBtn' title='Open menu'>[ ↓ ]</div>
        </td>
        <td>
          <ul class="menu">
            <p>menu of “Element”</p>
          </ul>
        </td>
      </tr>
    </tbody>
  </table>
</body>





我究竟做错了什么?
拜托,请赐教。

最佳答案

您正在将委托事件绑定到<table>,后者将监听事件并检查此事件的触发元素是否与.menuBtn匹配。因此,直接绑定到<tr>的事件与按钮单击事件无关。

此代码段与您的代码段相同。您可以看到tr事件在.menuBtn事件之前触发。在这种情况下,两个事件就像平行线一样。



// Open menu function
function open_menu(elm) {
  elm.css({
    "top": PosY,
    "left": PosX
  }).fadeIn(200);
}

// Mouse move
var PosX, PosY;
$(document).mousemove(function(e) {
  PosX = e.pageX;
  PosY = e.pageY;
});

// If document is clicked somewhere else than the menu, close menu
$(document).on("mousedown", function(e) {
  $(".menu").fadeOut(100);
});

$('tr').on('click', function(){
  console.log('tr clicked')
})

// I bind my function on click, on the menuBtn.
// I am doing it this way because .menuBtn are created dynamically
$('table').on('click', '.menuBtn', function(event) {
  event.stopPropagation(); // Why it isn't working ?
  console.log('btn clicked')
  open_menu($(this).closest('tr').find(".menu"));
});

* {
  margin: 0;
  padding: 0;
}

p {
  display: inline-block;
  cursor: inherit;
}

table {
  table-layout: fixed;
  width: 100%;
  border: 0;
  border-collapse: collapse;
  margin-bottom: 800px;
}

tr {
  background-color: #eee;
  cursor: pointer;
}

td {
  position: relative;
  padding-left: 10px;
  height: 64px;
}

.menuBtn {
  position: absolute;
  display: inline-block;
  left: 100px;
}

.menu {
  position: fixed;
  display: none;
  background: #f8f8f8;
  border: 2px solid #888;
  height: 80px;
  width: 100px;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body>
  <table>
    <tbody>
      <tr>
        <td>
          <p>Element</p>
          <div class='menuBtn' title='Open menu'>[ ↓ ]</div>
        </td>
        <td>
          <ul class="menu">
            <p>menu of “Element”</p>
          </ul>
        </td>
      </tr>
    </tbody>
  </table>
</body>





为了显示tr事件不会通过单击.menuBtn传播,这是一个演示:



// Open menu function
function open_menu(elm) {
  elm.css({
    "top": PosY,
    "left": PosX
  }).fadeIn(200);
}

// Mouse move
var PosX, PosY;
$(document).mousemove(function(e) {
  PosX = e.pageX;
  PosY = e.pageY;
});

// If document is clicked somewhere else than the menu, close menu
$(document).on("mousedown", function(e) {
  $(".menu").fadeOut(100);
});

$('tr').on('click', function(){
  console.log('tr clicked')
})

// added for demonstration
$('table').on('click', function(){
  console.log('table clicked')
})

// I bind my function on click, on the menuBtn.
// I am doing it this way because .menuBtn are created dynamically
$('table').on('click', '.menuBtn', function(event) {
  //event.stopPropagation(); // Why it isn't working ?
  console.log('btn clicked')
  open_menu($(this).closest('tr').find(".menu"));
});

* {
  margin: 0;
  padding: 0;
}

p {
  display: inline-block;
  cursor: inherit;
}

table {
  table-layout: fixed;
  width: 100%;
  border: 0;
  border-collapse: collapse;
  margin-bottom: 800px;
}

tr {
  background-color: #eee;
  cursor: pointer;
}

td {
  position: relative;
  padding-left: 10px;
  height: 64px;
}

.menuBtn {
  position: absolute;
  display: inline-block;
  left: 100px;
}

.menu {
  position: fixed;
  display: none;
  background: #f8f8f8;
  border: 2px solid #888;
  height: 80px;
  width: 100px;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body>
  <table>
    <tbody>
      <tr>
        <td>
          <p>Element</p>
          <div class='menuBtn' title='Open menu'>[ ↓ ]</div>
        </td>
        <td>
          <ul class="menu">
            <p>menu of “Element”</p>
          </ul>
        </td>
      </tr>
    </tbody>
  </table>
</body>





这个绑定了一个委托事件,表明.menuBtn事件首先被触发。原因是它从.menuBtn传播到table



// Open menu function
function open_menu(elm) {
  elm.css({
    "top": PosY,
    "left": PosX
  }).fadeIn(200);
}

// Mouse move
var PosX, PosY;
$(document).mousemove(function(e) {
  PosX = e.pageX;
  PosY = e.pageY;
});

// If document is clicked somewhere else than the menu, close menu
$(document).on("mousedown", function(e) {
  $(".menu").fadeOut(100);
});

$('table').on('click', 'tr', function(){
  console.log('tr clicked')
})

// added for demonstration
$('table').on('click', function(){
  console.log('table clicked')
})

// I bind my function on click, on the menuBtn.
// I am doing it this way because .menuBtn are created dynamically
$('table').on('click', '.menuBtn', function(event) {
  // event.stopPropagation(); // Why it isn't working ?
  console.log('btn clicked')
  open_menu($(this).closest('tr').find(".menu"));
});

* {
  margin: 0;
  padding: 0;
}

p {
  display: inline-block;
  cursor: inherit;
}

table {
  table-layout: fixed;
  width: 100%;
  border: 0;
  border-collapse: collapse;
  margin-bottom: 800px;
}

tr {
  background-color: #eee;
  cursor: pointer;
}

td {
  position: relative;
  padding-left: 10px;
  height: 64px;
}

.menuBtn {
  position: absolute;
  display: inline-block;
  left: 100px;
}

.menu {
  position: fixed;
  display: none;
  background: #f8f8f8;
  border: 2px solid #888;
  height: 80px;
  width: 100px;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body>
  <table>
    <tbody>
      <tr>
        <td>
          <p>Element</p>
          <div class='menuBtn' title='Open menu'>[ ↓ ]</div>
        </td>
        <td>
          <ul class="menu">
            <p>menu of “Element”</p>
          </ul>
        </td>
      </tr>
    </tbody>
  </table>
</body>





因此,如果要防止出现此问题,也只需对<tr>使用一个委托事件。



// Open menu function
function open_menu(elm) {
  elm.css({
    "top": PosY,
    "left": PosX
  }).fadeIn(200);
}

// Mouse move
var PosX, PosY;
$(document).mousemove(function(e) {
  PosX = e.pageX;
  PosY = e.pageY;
});

// If document is clicked somewhere else than the menu, close menu
$(document).on("mousedown", function(e) {
  $(".menu").fadeOut(100);
});

$('table').on('click', 'tr', function(){
  console.log('I do not want to see that.')
})

// I bind my function on click, on the menuBtn.
// I am doing it this way because .menuBtn are created dynamically
$('table').on('click', '.menuBtn', function(event) {
  event.stopPropagation(); // Why it isn't working ?
  open_menu($(this).closest('tr').find(".menu"));
});

* {
  margin: 0;
  padding: 0;
}

p {
  display: inline-block;
  cursor: inherit;
}

table {
  table-layout: fixed;
  width: 100%;
  border: 0;
  border-collapse: collapse;
  margin-bottom: 800px;
}

tr {
  background-color: #eee;
  cursor: pointer;
}

td {
  position: relative;
  padding-left: 10px;
  height: 64px;
}

.menuBtn {
  position: absolute;
  display: inline-block;
  left: 100px;
}

.menu {
  position: fixed;
  display: none;
  background: #f8f8f8;
  border: 2px solid #888;
  height: 80px;
  width: 100px;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body>
  <table>
    <tbody>
      <tr>
        <td>
          <p>Element</p>
          <div class='menuBtn' title='Open menu'>[ ↓ ]</div>
        </td>
        <td>
          <ul class="menu">
            <p>menu of “Element”</p>
          </ul>
        </td>
      </tr>
    </tbody>
  </table>
</body>





如果有任何错误,误导或不清楚的地方,请随时让我知道或编辑该帖子。

10-06 04:00