javascript - 如果 PreventDefault() 仅阻止默认浏览器操作,如何取消自定义事件?

标签 javascript

const log = console.log;

const child = document.getElementById('child');
const parent = document.getElementById('parent');


parent.addEventListener('newColor', function(e) { 
    e.preventDefault()
    log('parent')
    this.style.color = e.detail.textColor;
})

child.addEventListener('newColor', function(e) { 
    log('child')
    this.style.color = e.detail.textColor;
    this.style.backgroundColor = e.detail.bgrColor;
})


function changeColor() { 
    const myEvent = new CustomEvent('newColor', { 
        detail: { 
            textColor: 'red',
            bgrColor: 'blue',
        },
        cancelable: true,
        bubbles: true
    })

    child.dispatchEvent(myEvent);
}


changeColor()
<p id="parent">this is the parent<span id="child"> THIS IS THE CHILD ELEMENT </span></p>

既然 event.preventDefault() 只能阻止默认的浏览器操作,那么如何“取消”自定义事件呢?

例如,在这里:

$("#but").click(function (ev) {
    ev.preventDefault()
    alert('child button clicked');
  })
 <script src="https://code.jquery.com/jquery-3.6.0.js"></script>


<button id="but">button</button>

preventDefault() 仅阻止默认操作,即提交表单,而不是执行其余函数语句。

那么,当您无法使用 preventDefault() 实际上取消事件时,拥有“cancellable”属性有什么意义呢?

最佳答案

通常当您在浏览器提供的对象上调用 Event.preventDefault() 时,例如:

document.querySelector("#id-checkbox").addEventListener("click", function(event) {
     console.log("run") // This is still run
     event.preventDefault()
});

它不会触发浏览器定义的默认操作,例如检查复选框(但您的代码仍将运行,因此事件不会“取消”)。它实际上相当于:(不完全相当于,请阅读 here )

function(event) {
    console.log("run") // This is still run
    return false
});

因此,Event.preventDefault() 所做的是取消默认的浏览器操作。但是,您无法定义自定义事件的默认操作。那它还有什么用呢?其实在一些特殊场合还是有用的。为了演示它如何与自定义 Event 配合使用,下面是一个示例:

const log = console.log;

const child = document.getElementById('child');
const parent = document.getElementById('parent');
const child2 = document.getElementById('child2');
const parent2 = document.getElementById('parent2');


parent.addEventListener('newColor', function(e) {
    if (e.defaultPrevented) return;
    log('parent')
    this.style.color = e.detail.textColor;
})

child.addEventListener('newColor', function(e) { 
    e.preventDefault();
    log('child')
    this.style.color = e.detail.textColor;
    this.style.backgroundColor = e.detail.bgrColor;
})

parent2.addEventListener('newColorNotCancelable', function(e) {
    if (e.defaultPrevented) return; // does not return as event is not cancelable
    log('parentNotCancelable')
    this.style.color = e.detail.textColor;
})

child2.addEventListener('newColorNotCancelable', function(e) { 
    e.preventDefault();
    log('childNotCancelable')
    this.style.color = e.detail.textColor;
    this.style.backgroundColor = e.detail.bgrColor;
})


function changeColor() { 
    const myEvent = new CustomEvent('newColor', { 
        detail: { 
            textColor: 'red',
            bgrColor: 'blue',
        },
        cancelable: true,
        bubbles: true
    })    
    child.dispatchEvent(myEvent)
    const myEventNotCancelable = new CustomEvent('newColorNotCancelable', { 
        detail: { 
            textColor: 'red',
            bgrColor: 'blue',
        },
        cancelable: false,
        bubbles: true
    })
    child2.dispatchEvent(myEventNotCancelable)
}


changeColor()
<p id="parent">this is the parent<span id="child"> THIS IS THE CHILD ELEMENT </span></p>
<p id="parent2">this is the parent<span id="child2"> THIS IS THE CHILD ELEMENT </span></p>

当您在 childchild2 上分派(dispatch)事件时,该事件将传播到其父级。通过对其子级调用 Event.preventDefault(),如果 Event 是可取消的,您可以让父级知道该事件已被“默认阻止”。它类似于 Event.stopPropagation() 但它更强大,因为您只能跳过传播链上的某些 DOM 对象。

关于javascript - 如果 PreventDefault() 仅阻止默认浏览器操作,如何取消自定义事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68772591/

相关文章:

javascript - (b === null) 的测试是否与 (b) 相同?

javascript - 显示/隐藏文本区域框+在图像之间交换onclick

Javascript 节点点击顺序

javascript - innerHTML 忽略 Angular ng-show

声明全局变量的 Javascript 情况?

javascript - 我想添加独立于 HTML 的 jQuery 文件

javascript - 在点击事件之外访问 ngx-bootstrap 模态

javascript - 无法编译此 Typescript

javascript - Node.js、express、html 表单 req.body 未定义

javascript - React hook 表单handlesubmit 不起作用