【问题标题】:Javascript: cancel or let an event continue?Javascript:取消或让事件继续?
【发布时间】:2014-05-15 00:19:15
【问题描述】:

我的场景涉及 Kendo UI,但我认为它可能普遍适用于 JavaScript,因此 JavaScript 标记。

我有一个 Kendo 调度程序,其编辑事件选项设置为 functionA。

在 functionA 中,我创建了一个向用户提问的 Kendo 窗口(基本上是一个模式);在一种情况下,编辑事件应该继续并冒泡,就好像模式从未存在过一样,在另一种情况下,它应该阻止默认并返回。

问题是模态是非阻塞的,所以确认模态出现了,但事件逻辑继续并冒泡到编辑器的内置编辑事件。

如何捕获和暂停当前事件,并且只有在我从 Kendo 窗口中获得所需结果时才继续它?

我知道由于 JavaScript 的单线程特性,我不能也不应该使 Kendo 窗口阻塞,但是有没有办法让这个事件暂停,只有在我这样说的情况下才能恢复它。

基本上,我想做event.Hold()之类的事情,如果满足条件,则event.Resume(),否则,执行event.preventDefault()

【问题讨论】:

    标签: javascript events kendo-ui dom-events


    【解决方案1】:

    更新

    我测试了我之前发布的代码,发现它不能正常工作。这是经过测试的,可以完全按照您的要求工作,而且它是一种解决方案:

    var event_store;
    
    function handle_click(event) {
        event.stopPropagation();
        event_store = event;
    
        //Open the modal here
        //If it's possible, pass the event pointer to the modal's confirm callback
        //instead of using event_store and pass that pointer to fire_event() when
        //it's confirmed
    }
    
    function confirm_handle() {
        resume_event("click");
    }
    
    function resume_event(type) {
        if (event_store.target.parentNode) {
            var event;
    
            if (document.createEvent) {
                event = document.createEvent("HTMLEvents");
                event.initEvent(type, true, true);
            } else {
                event = document.createEventObject();
                event.eventType = type;
            }
    
            event.eventName = type;
    
            if (document.createEvent) { //Not IE
                event_store.target.parentNode.dispatchEvent(event);
            } else { //IE
                event_store.target.parentNode.fireEvent("on" + event.eventType, event);
            }
        }
    }
    

    上一个

    您可以使用类似的方法来“暂停”事件冒泡。它取消事件传播并在调用单击处理程序时显示模式并将 show_modal 变量设置为 false。在确认调用 fire_event() 并触发原始事件后,这次不显示模态,然后将 show_modal 重置为 true。如果用户未确认模式,您还应该将 show_modal 恢复为 true。

    var show_modal = true;
    var event_store;
    
    function handle_click(event) {
        event.stopPropagation();
        event_store = event;
    
        show_modal = !show_modal;
        if (show_modal) {
            //Open the modal here
            //If it's possible, pass the event pointer to the modal's confirm callback
            //instead of using event_store and pass that pointer to fire_event() when
            //it's confirmed
        }
    }
    
    function fire_event() {
        if (document.createEvent) { //Not IE
            element.dispatchEvent(event_store);
        } else { //IE
            element.fireEvent("on" + event_store.eventType, event_store);
        }
    }
    

    【讨论】:

    • 我知道它不被普遍接受,但可以扩展原生事件对象以支持这样的暂停并使用 event.hold() 和 event.resume()
    • 非常好! JS 从未停止让我感到惊讶。
    • 对不起,我忽略了原始答案中的某些内容。我做了一些修改并简化了实现。这应该可以按照您的意愿工作。
    【解决方案2】:

    你真正应该做的是

    1. 在显示对话框之前在处理程序中调用 e.preventDefault()
    2. 当你的对话被确认(或者被拒绝,我不知道要求)后,使用API​​方法开始编辑调度器事件

    这应该可以帮助您开始(仅适用于第一次编辑;您需要在某个地方重置 _confirmed 条件):

    edit: function (e) {
        if (!this._confirmed) {
            e.preventDefault();
    
            // your dialog logic here..
            if (window.confirm("Confirm edit?")) {
                this._confirmed = true;
                // in your code, you probably won't need the setTimeout wrapper
                setTimeout(function () { 
                    $("#scheduler").getKendoScheduler().editEvent(e.event);
                }, 5);
                // at some point, you'll probably want to reset this._confirmed
            }
        }
    },
    

    (see it work)

    【讨论】:

    • 这些事件不一定都是剑道事件。我发布的方法将允许恢复本机 javascript 事件。此外, preventDefault 不会阻止事件传播到父元素。另外,我根本找不到 getKendoScheduler 函数的任何文档。
    • @aecend 您的解决方案可能适用于 DOM 事件,我认为现在的问题是模棱两可的,因为它涉及 JS 事件以及 Kendo UI 小部件;对于 Kendo Scheduler,事件将始终是 Kendo 事件; preventDefault 实现也是 Kendo 特定的(在这种情况下,它只是阻止编辑事件,该小部件没有冒泡); getKendoScheduler 相当于 .data("kendoScheduler") - 我不确定它是否记录在任何地方
    猜你喜欢
    • 2011-12-10
    • 2012-02-18
    • 1970-01-01
    • 1970-01-01
    • 2019-01-13
    • 2018-10-14
    • 2017-07-01
    • 2011-03-25
    • 1970-01-01
    相关资源
    最近更新 更多