代码之家  ›  专栏  ›  技术社区  ›  DanielMason

在javascript中延迟默认事件

  •  3
  • DanielMason  · 技术社区  · 15 年前

    我希望能够延迟事件的默认操作,直到采取其他操作为止。

    它的用途: 我正在尝试建立一种可重用的、不引人注目的方式,通过模态对话来确认动作。关键的wishlist项是任何javascript处理程序都是由脚本附加的,而不是直接以内联方式编写的。

    为了使其真正可重用,我想在不同类型的项上使用它:HTML链接、复选框,甚至其他由JavaScript驱动的操作。对于纯粹的HTML元素,如链接或复选框,我希望它们能够适当地降级,以便在没有打开javascript的情况下可用。

    以下是我对实现的设想:

    <a href="/somelink/" class="confirm">Some Link</a>
    _________
    
    <script>
        attachEvent('a.confirm','click', confirmAction.fire)
    
        var confirmAction = (function(){
            var public = {
                fire: function(e){
                    e.default.suspend();
                    this.modal();
                },
                modal: function(){
                    showmodal();
                    yesbutton.onclick = this.confirmed;
                    nobutton.onclick = this.canceled;
                },
                confirmed: function(){
                    hidemodal();
                    e.default.resume();
                },
                canceled: function(){
                    hidemodal();
                    e.default.prevent();
                }
            }
            return public;
        })()
    
    </script>
    

    我知道 e.preventDefault 函数,但这将终止默认操作,而不给我恢复它的能力。显然, default 对象与 suspend , resume prevent 这些方法是为了说明我想要的结果。

    顺便说一下,我用 Ext.Core 图书馆,如果有帮助的话。这个库为处理事件提供了大量的规范化。但是我真的很有兴趣在JavaScript中学习这个的一般原则。

    谢谢!

    1 回复  |  直到 15 年前
        1
  •  0
  •   outis    15 年前

    要恢复,可以尝试保存事件并重新激发它,设置一个标志,该标志可用于跳过调用suspend()的处理程序(在示例中为“confirmaction.fire”)。

    <a href="/somelink/" class="confirm">Some Link</a>
    _________
    
    <script>
    function bindMethod(self, method) {
        return function() {
            method.apply(self, arguments);
        }
    }
    var confirmAction = (function(){
        var public = {
                delayEvent: function(e) {
                    if (e.suspend()) {
                        this.rememberEvent(e);
                        return true;
                    } else {
                        return false;
                    }
                },
                fire: function(e){
                    if (this.delayEvent(e)) {
                        this.modal();
                    }
                },
                modal: function(){
                        showmodal();
                        yesbutton.onclick = bindMethod(this, this.confirmed);
                        nobutton.onclick = bindMethod(this, this.canceled);
                },
                confirmed: function(){
                        hidemodal();
                        this.rememberEvent().resume();
                },
                canceled: function(){
                        hidemodal();
                        this.forgetEvent();
                },
                rememberEvent: function (e) {
                    if (e) {
                        this.currEvent=e;
                    } else {
                        return this.currEvent;
                    }
                },
                forgetEvent: function () {
                    delete this.currEvent;
                }
        }
        return public;
    })()
    
    // delayableEvent should be mixed in to the event class.
    var delayableEvent = (function (){
         return {
            suspend: function() {
                if (this.suspended) {
                    return false;
                } else {
                    this.suspended = true;
                    this.preventDefault();
                    return true;
                }
            },
            resume: function () {
                /* rest of 'resume' is highly dependent on event implementation, 
                   but might look like */
                this.target.fireEvent(this);
            }
         };
    })();
    
    /* 'this' in event handlers will generally be the element the listener is registered 
     * on, so you need to make sure 'this' has the confirmAction methods.
     */
    mixin('a.confirm', confirmAction);
    attachEvent('a.confirm','click', confirmAction.fire);
    </script>
    

    这仍然存在潜在的错误,例如它如何与其他事件侦听器交互。

    推荐文章