为什么即使在alert()之前调用了preventDefault(),alert()仍会执行?

app*_*ppu 0 javascript event-bubbling dom-events

在以下代码中,alert('Alert on btn is triggered') })即使在el event.preventDefault()click处理程序中的此行之前调用了方法,也为什么会触发事件#btn

同样,为什么onclick="alerted()不在div 上#btn或在#wrapdiv 上触发,而回调触发clickaddEventListener触发一起触发。

var btn = document.getElementById('btn')
var wrap = document.getElementById('wrap')

btn.addEventListener('click', function() {
  event.stopPropagation()
  if (event.cancelable) {
    event.preventDefault()
  }
  alert('Alert on btn is triggered')
})


function alerted() {
  alert('Alerted fired')
}

wrap.addEventListener('click', function() {
  alert(this.id)
  alert(event.target.tagName + "#" + event.target.id)
})
Run Code Online (Sandbox Code Playgroud)
#wrap {
  padding: 20px;
  border: 1px solid red;
}
Run Code Online (Sandbox Code Playgroud)
<div id="wrap" onclick="alerted">
  <button id="btn" onclick="alerted">Click Me</button>
</div>
Run Code Online (Sandbox Code Playgroud)

Cer*_*nce 6

调用event.preventDefault()event.stopPropagation不会停止当前正在进行的回调。无论函数的上下文如何,如果函数开始运行,阻止它继续运行的唯一方法就是明确地return

如果要确保在preventDefault()调用时该函数的其余部分停止运行,请更改为:

  if (event.cancelable) {
    event.preventDefault();
    return;
  }
Run Code Online (Sandbox Code Playgroud)

将其定义event为处理程序采用的参数,而不是依赖隐式全局window.event(尽管它在某些浏览器中有效,但使用它不是一个好主意),这可能也是一个好主意

  if (event.cancelable) {
    event.preventDefault();
    return;
  }
Run Code Online (Sandbox Code Playgroud)
var btn = document.getElementById('btn')
var wrap = document.getElementById('wrap')

btn.addEventListener('click', function(event) {
  event.stopPropagation()
  if (event.cancelable) {
    event.preventDefault();
    return;
  }
  alert('Alert on btn is triggered')
})


function alerted() {
  alert('Alerted fired')
}

wrap.addEventListener('click', function() {
  alert(this.id)
  alert(event.target.tagName + "#" + event.target.id)
})
Run Code Online (Sandbox Code Playgroud)
#wrap {
  padding: 20px;
  border: 1px solid red;
}
Run Code Online (Sandbox Code Playgroud)