Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/400.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript授权最佳实践_Javascript_Jquery_Delegation - Fatal编程技术网

Javascript授权最佳实践

Javascript授权最佳实践,javascript,jquery,delegation,Javascript,Jquery,Delegation,我现在正在开发/已经开发了一些系统,我在编程中遇到了一个问题,我似乎将我的JQuery函数委托给文档,如下所示: $(document).on('click', '.modal-editor', function () { //code }); $(document).on('click', '.another-class', function () { //code }); $(document).on('click', '#another-id', function ()

我现在正在开发/已经开发了一些系统,我在编程中遇到了一个问题,我似乎将我的JQuery函数委托给文档,如下所示:

$(document).on('click', '.modal-editor', function () {
    //code
});

$(document).on('click', '.another-class', function () {
    //code
});

$(document).on('click', '#another-id', function () {
    //code
});
这有什么问题吗

更新:

好的,所以本质上这没有问题,直到:

  • 应用程序达到了一个规模,授权需要更加本地化,以防止减慢UI。“发生的每个事件都需要针对e.target和文档之间的每个元素运行每个选择器”

  • 如果使用嵌套函数,这样的委托将增加意外行为(如传播)的可能性


  • 回到我的问题(最佳实践),最佳实践是尽可能将事件委托给最近的静态元素,以避免上述情况。

    您的代码没有问题

    $(document)
    不必始终放置在事件委派中,该选择器引用动态添加元素的最近父元素:

    语法:

    $(closest parent selector).on('event','target selector', function(){
    });
    
    您也可以使用
    document.body

    $(document.body).on('event','target selecor',function(){
    });
    
    旁注:对于现有的DOM元素,可以使用普通的单击事件

    $('selector').click(function(){
    });
    

    $('selector').on('click',function(){
    });
    

    有关更多信息,请参阅API文档。

    当您希望将特定事件应用于多个元素,而每个元素都没有自己的事件处理程序时,委托非常有用。在上面的例子中,前两种方法可能会出现这种情况

    在理论上只有一个元素与标准匹配的情况下,根据文档的大小,可能会产生性能影响,因为每个事件都必须根据处理程序过滤器进行测试,以查看是否匹配

    此外,如果每个方法都作为委托添加,并且您经常加载和上载页面的部分,那么这些事件将比它们所属的页面上的元素停留的时间更长

    您可以将处理程序委托给document元素以外的其他元素,例如周围的
    div
    ,或者在这种情况下可以委托给其他元素。或者使用事件名称空间来确保没有多次添加事件

    “这有什么问题吗?”

    对。发生的每个事件都需要针对
    e.target
    文档之间的每个元素运行每个选择器。那太贵了

    基本上就像这个简化的伪代码:

    // start on the e.target
    var node = e.target;
    
    // For the target and all its ancestors until the bound element...
    while (node && node !== this) {
    
        // ...test the current node against every click selector it was given
        for (var i = 0; i < click_selectors.length; i++) {
    
            // If a selector matches...
            if ($(node).is(selector)) {
                // ...run the handler for that selector
            }
        }
        node = node.parentNode;
    }
    
    //从e.target开始
    var节点=e.target;
    //对于目标及其所有祖先,直到绑定元素。。。
    while(节点和节点!==此){
    //…根据给定的每个单击选择器测试当前节点
    对于(变量i=0;i<单击_selectors.length;i++){
    //如果选择器匹配。。。
    if($(节点).is(选择器)){
    //…运行该选择器的处理程序
    }
    }
    node=node.parentNode;
    }
    
    此外,如果您的代码或加载的其他代码在
    e.target
    文档之间绑定了一个处理程序,并调用
    e.stopPropagation()
    ,则事件将永远不会到达
    文档,因此您的事件将不会触发


    最好让您的委派尽可能接近预期的元素。并且主要用于动态加载的元素,因为它增加了额外的开销,特别是在快速触发事件的情况下。

    是的。实际上,它本身并不存在,但从
    文档(DOM的根)中委派所有事件确实意味着所有单击事件,包括您不感兴趣的事件,将至少部分地得到处理:

    $(document).on('click', '$another-id', function(){});
    
    在这方面,这是一个特别糟糕的主意:你只关注一个元素,但是如果我点击身体的任何地方,jQ会做如下事情:

    if (event.target.id == 'another-id')
    {
        return callback.call(event.target, $(event));//where callback is the anonymous function you passed to on
    }
    return event;
    
    因此,所有单击事件都会导致函数调用。这会降低您的UI速度。
    你决不能停止委派事件,而是要明智地约束听众。例如,如果要使用的所有DOM元素都包含在
    #container
    div中,则将侦听器绑定到该容器中。如果要处理导航事件,请将侦听器绑定到包含所有导航元素的节点
    此外,如果您取消了一个事件,但未能停止ProPagation,那么该事件仍将调用可能排队的所有其他侦听器。Returnign
    false
    也会引起问题,因为在jQ中,
    return false
    被翻译为
    e.preventDefault();e、 stopPropagation()
    。因此,在处理嵌套元素时要小心,如果要处理页面中的链接,也要处理
    等元素,则可能会调用这两个处理程序,具体取决于使用的选择器:

    $(document).on('click', 'a', function(){});//is called for all links
    $(document).on('click', 'a.navigation', function(){});//is called for navigation
    
    哪个将首先被调用?在特定情况下,您希望使用哪一种?这里有错误的空间,这不应该存在:

    $('#navContainer').on('click', 'a.navigation', function(){});//is called for all links
    
    至少让事情变得更安全、更清晰、更轻松

    如果要使用ID选择器委派事件,且该元素已存在于DOM中,请不要委派:


    它比较短,而且无论如何可能会更快

    我不这么认为。。。你应该很好…这可能会成为一个大规模的问题;没有全面的答案。关于你的更新,不,我不会等待出现性能问题。jQuery出于某种原因放弃了
    .live()
    方法。对于明智的实践,即使它们目前没有明显的好处,也有一些值得一提的地方。@cookiemonster-jQuery放弃了
    live()
    方法,因为它的功能太具体了。jQueryAPI倾向于使用同一方法执行多项操作,具体取决于您提供的参数。您可以使用
    on()
    delegate执行与
    live()相同的功能
    
    $('#another-id').on('click', function(){});