PrototypeJS事件注册表问题

时代

1.7.3更新后,原型事件注册表似乎存在问题,我正在prototype_event_registry元素存储上使用它来访问单击事件,以便可以重播它们。

这是为了让我能阻止事件和可选恢复这些基础上的回调,一切工作正常,但看的diff为以后1.7.01.7.3它似乎被删除?

我知道这是内部的,一开始我可能不应该使用它。无论如何,取决于我的问题:

我已经更新了可以使用的代码,1.7.3但对我来说似乎很hacky,是否有更好的方法来做到这一点?

/**
 * creates a toggling handler for click events taking previous click events into account.
 *
 * w.r.t stopping of a click event, handles cases where the button is a submit or a normal button.
 * in the case of a submit, calling <tt>Event.stop()</tt> should be sufficient as there are no other listeners on the button.
 * however, if a normal button has a handler that calls <tt>save()</tt>, and another handler using client code and calling stop,
 * it will not affect stopping of the event, since <tt>Event.stop</tt> only stops propagation, not other handlers!
 *
 * note that this function will always execute the specified handler before any other defined events.
 *
 * @param {Element} element the element to use for this click event
 * @param {Function} handler the handler to use for this stopping click event, if this handler returns true,
 * all other actions for the click event will be prevented
 * @returns {Element} the element that was supplied as argument
 */
function stoppingClickEvent(element, handler) {
    if (!element) throw 'cannot use method, if element is undefined';

    // assign default handler if none was supplied
    handler = handler || Prototype.emptyFunction;

    if (element.type && element.type === 'submit') {
        element.on('click', function(submitEvent) {
            // call the supplied handler with the current element as context and the event as argument
            // if it returns true, we should stop the event
            var stopEvent = handler.call(element, submitEvent);

            if (stopEvent) {
                // since the element's default action will be to submit a form, we prevent it
                submitEvent.stop();
            }
        });
    } else {
        // prototype 1.7.3 removed support for 'prototype_event_registry', so we need to do multiple hacks here
        // first get the window of the element so we can access the prototype
        // event cache from the correct context (frames)
        var elementDoc = element.ownerDocument;
        var elementWindow = elementDoc.defaultView || elementDoc.parentWindow;

        if (!elementWindow) {
            throw 'cannot access the window object for element ' + element.id;
        }

        // we are dealing with a normal element's click event, so we don't know how many click events have been set up.
        // capture them all so we can decide to call them or not.
        // FIXME: need a better way of doing this
        var registry = elementWindow['Event'].cache[element._prototypeUID || element.uniqueID] || {},
            events = registry['click'] || [];

        // now that we have a copy of the events, we can stop them all and add our new handler
        element.stopObserving('click').on('click', function(clickEvent) {
            // call the supplied handler with the current element as context and the event as argument
            // if it returns true, we should stop the event
            var stopEvent = handler.call(element, clickEvent);

            if (!stopEvent) {
                // the event should not be stopped, run all the original click events
                events.each(function(wrapper) {
                    wrapper.handler.call(element, clickEvent);
                });
            }
        });
    }

    return element;
}
时代

使用上面的代码运行3-4个月后,我最终决定还原它。似乎有很多问题,尤其是在单个页面上处理多个框架和事件处理程序时。

最流行的是,Event.cache对于特定元素是undefined

这可能是由于上面的错误处理所致,但是我强烈怀疑新Event框架在某种程度上是不正确的,因为还原到1.7.0完全可以解决我遇到的所有问题。

仅供参考,这是我现在使用的代码1.7.0

/**
 * creates a toggling handler for click events taking previous click events into account.
 *
 * w.r.t stopping of a click event, handles cases where the button is a submit or a normal button.
 * in the case of a submit, calling <tt>Event.stop()</tt> should be sufficient as there are no other listeners on the button.
 * however, if a normal button has a handler that calls <tt>save()</tt>, and another handler using client code and calling stop,
 * it will not affect stopping of the event, since <tt>Event.stop</tt> only stops propagation, not other handlers!
 *
 * note that this function will always execute the specified handler before any other defined events.
 *
 * @param {Element} element the element to use for this click event
 * @param {Function} handler the handler to use for this stopping click event, if this handler returns true,
 * all other actions for the click event will be prevented
 * @returns {Element} the element that was supplied as argument
 */
function stoppingClickEvent(element, handler) {
    if (!element) throw 'cannot use method, if element is undefined';

    // assign default handler if none was supplied
    handler = handler || Prototype.emptyFunction;

    if (element.type && element.type === 'submit') {
        element.on('click', function(submitEvent) {
            // call the supplied handler with the current element as context and the event as argument
            // if it returns true, we should stop the event
            var stopEvent = handler.call(element, submitEvent);

            if (stopEvent) {
                // since the element's default action will be to submit a form, we prevent it
                submitEvent.stop();
            }
        });
    } else {
        // we are dealing with a normal element's click event, so we don't know how many click events have been set up.
        // capture them all so we can decide to call them or not.
        var registry = element.getStorage().get('prototype_event_registry') || $H(),
            events = registry.get('click') || [];

        // now that we have a copy of the events, we can stop them all and add our new handler
        element.stopObserving('click').on('click', function(clickEvent) {
            // call the supplied handler with the current element as context and the event as argument
            // if it returns true, we should stop the event
            var stopEvent = handler.call(element, clickEvent);

            if (!stopEvent) {
                // the event should not be stopped, run all the original click events
                events.each(function(func) {
                    func.call(element, clickEvent);
                });
            }
        });
    }

    return element;
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Windows注册表问题

来自分类Dev

RMI:注册表安全问题

来自分类Dev

远程注册表查询问题

来自分类Dev

我的 onClick 注册表有问题

来自分类Dev

删除注册表时出现重复的日志事件

来自分类Dev

Docker推动私有注册表问题

来自分类Dev

Docker不下载图像(注册表连接问题)

来自分类Dev

使用cpp向注册表添加值的问题

来自分类Dev

使用架构注册表时遇到问题:下载

来自分类Dev

导入刚从regedit导出的Windows注册表的问题

来自分类Dev

php注册表格问题

来自分类Dev

多个注册表FluentScheduler

来自分类Dev

使用Laravel的注册表

来自分类Dev

注册表句柄泄漏?

来自分类Dev

从文件导入注册表

来自分类Dev

注册表删除值

来自分类Dev

设置注册表值

来自分类Dev

注册表值访问

来自分类Dev

注册表访问被拒绝

来自分类Dev

擦除 Hive 注册表

来自分类Dev

Plone注册表问题:重新启动和权限问题后数据消失

来自分类Dev

Plone注册表问题:重新启动和权限问题后,数据消失

来自分类Dev

多次注册事件的问题

来自分类Dev

Gulp 4 / Undertaker问题-自定义注册表必须具有“ init”功能

来自分类Dev

在Windows中从Bootdocker登录到Docker Hub注册表时出现问题

来自分类Dev

将工件设置为Docker注册表时出现问题

来自分类Dev

架构注册表中的向后兼容性问题和不确定性

来自分类Dev

两个问题-我正在尝试修改注册表,但出现错误

来自分类Dev

Windows中的64位和32位注册表问题(在C#中编程)