编程语言
首页 > 编程语言> > 在JavaScript OOP中从经典事件管理转移到事件委托

在JavaScript OOP中从经典事件管理转移到事件委托

作者:互联网

将有关特定操作的每个处理程序直接附加到目标元素的旧事件管理已过时,因为有关性能和内存节省的考虑因素已在开发人员社区中广泛传播.

自从jQuery用新的.on()方法更新了旧的.bind()和.live()方法以允许委派以来,事件委托实现有了加速.

这决定了某些经验丰富方法的改变,在这种情况下,使用事件委派是必要的.
我试图制定一些最佳实践,同时保持库的编码风格,并寻找其他开发人员面临的类似情况以寻找答案.

通过将OOP与函数一起用作构造函数,我通常具有如下的对象创建接口:

var widget = new Widget({
    timeout: 800,
    expander: '.expanders'
});

使用对象常量作为参数,提供了传递的输入的名称和值的清晰映射.该代码所基于的类可能类似于以下内容:

var Widget = function(options) {
    // some private members
    var _timeout;
    var _$widget;
    var _$expander;

    // methods
    this.init = function() {
        _timeout = options.timeout || 500;
        _$expander = $(options.expander);
        _$widget = _$expander.next();
        _$expander.on('click', _toggle);
    };
    var _toggle = function(e) {
        if (_$widget.is(':visible')) {
            _$widget.hide(_timeout);
        } else {
            _$widget.show(_timeout);
        }
    };
    this.init();
};

使用“私有”方法在代码的可读性和简洁性方面给我带来了一些好处(只有有用的方法才向用户公开),而在性能方面却获得很小的收益(每个范围解析比本地变量花费更多的时间).但是,当谈到事件处理程序时,它与事件委托范式冲突.

我想公开一下我以前在班级内部与侦听器关联的方法:

    this.toggle = function(e) {
        if (_$widget.is(':visible')) {
            _$widget.hide(_timeout);
        } else {
            _$widget.show(_timeout);
        }
    };

然后在外部或在另一个代理类中进行适当的委派,并添加类似以下内容:

var widget = new Widget({
    expander: '.expanders'
});

$(delegationContext).on('click', '.expanders', widget.toggle);

但是在我看来,这并不是最好的方法,无法在接口中公开无用的方法,因此我尝试了一种方法,让主类通过接口直接知道所有信息以自主地委托事件:

var widget = new Widget({
    timeout: 800,
    expander: {
        delegationContext: '.widgetContainer',
        selector: '.expanders'
    }
});

这将允许在类内部继续使用私有方法:

var $context = $(options.expander.delegationContext);
$context.on('click', options.expander.selector, _toggle);

您对此有何做法和建议?
到目前为止,您听说过的其他开发人员的主要趋势是什么?

解决方法:

it clashes with the event delegation paradigm.

忘记这种范式!不要选择它,因为它“很酷”并且直接附加事件“已经过时”,只有在必要时才选择它.事件委托对您来说不是必需的,也不会加快任何速度.这不是您可以应用的解决方案-您没有问题!

您只有一个元素和一个特定于元素的事件处理程序功能(每个小部件扩展器都有其自己的功能).您已经可以从应用事件委派的问题中推断出您不能也不应在此处使用它.直接附加处理程序.

仅当您有大量相似的元素(在一个共同祖先中位于DOM中一致)且所有这些元素都将附加相同的事件处理函数时,事件委托才有用.对于Widget构造函数,情况并非如此,它确实具有实例特定的选项,例如扩展器选择器.

在当前的Widget类中,使用事件委托将与single responsibility principle发生冲突.在事件委托范例中,您需要查看委托上下文中的所有元素,并使其尽可能地统一.您添加的元素特定的数据和状态越多,您失去的委派优势就越多.

如果您真的想在这里使用事件委托,我建议

var Widgets = {
    init: function(delegationContext) {
        $(delegationContext).on("click", ".widget-expander", function(e) {
             $this = $(this);
             $this.next().toggle($this.data("widget-expander-timeout") || 500);
        });
    },
    activate: function(options) {
        $(options.expander)
         .addClass("widget-expander")
         .data("widget-expander-timeout", options.timeout);
    }
};

这里没有使用构造函数.您只需初始化事件委托上下文,然后可以添加要由委托机制捕获的单个元素.所有数据都存储在元素上,可从事件处理程序进行访问.例:

Widgets.init('.widgetContainer');
Widgets.activate({expander: '.expanders', timeout: 800});

And what are the main trends of other developers you heard about as far as today?

除了这个问题在StackOverflow上不合时宜外,我只能建议您不要关注别人听到的所有趋势.是的,要了解新的(或广告的或新颖的)技术,但不要忘记了解何时使用它们.

标签:event-delegation,javascript,oop,refactoring,coding-style
来源: https://codeday.me/bug/20191009/1880775.html