backbone.js 附加的事件处理程序的“元数据”存储在哪里?在“DOM”上,对象上,还是......?

flvtvl50  于 2022-11-10  发布在  其他
关注(0)|答案(4)|浏览(147)

我一直在想...所以你有一个这样的代码:

$('#click-me');

然后附上这个:

$('#click-me').click(someFunction);

其中的“元数据”表示:

“嘿,“jQuery-object #click-me,”当您被单击时,我会将您指向“someFunction”!"

我知道事件处理程序可能会被破坏,比如我在使用Backbone.js时的情况,由于我重新呈现了整个页面,事件停止了触发,同时破坏了一些后台函数/对象/视图.. (这是我问这个问题的原因)
我的问题是

**事件的“元数据”存储在哪里,如何销毁?**它们是否存储在将其绑定到函数的函数中?它们是否在DOM“元数据”(如果有)本身中?

我正在尝试学习JavaScript的复杂性,因为我厌倦了bug。除此之外,我想知道我是否应该注意垃圾收集,它可能会分离我的事件等等。来自C#,我会说带有DOM的JavaScript真的很棒...
(also,作为一个侧记,我如何访问这些事件并“调试”它们?火狐?Chrome?)

更新
**换句话说,将DOM元素连接到特定事件的信息存储在哪里?DOM?对象?(或者.. jQuery是否Map它?JavaScript是否有“元数据”?***它围绕着上下文.. *

jdg4fx2g

jdg4fx2g1#

更新:所以我误解了你的问题,你想知道事件是如何在javascript和html的上下文中绑定的,我最初的回答是描述jquery如何创建和管理事件,归结起来就是调用element.addEventListener

从MDN文档中,你可以看到 eventtarget 可以是 elementdocumentwindowXMLHttpRequest。从关于DOM事件的w3规范中,事件目标可以添加、删除和调度事件。因此,即使信息可能存储在封装元素之类的东西中,这也将在浏览器级别实现。
从你提到的 * 复制然后替换正文中的html会删除事件 * 的问题来看,我认为浏览器只是给了你标记(没有事件元数据),然后当你替换它时,元数据就不见了。

原始答案:jquery事件处理程序如何工作。

好吧,我开始为JQuery 1.4.2挖掘这个(因为我必须使用几个工具,所有这些工具都没有更新)
先看看这个:http://james.padolsey.com/jquery/#v=1.4.2&fn=click

function (fn) {
    return fn ? this.bind(name, fn) : this.trigger(name);
}

这就是click是如何 * 定义 * 的,它实际上并不是在代码中定义的。JQuery为所有事件/处理函数定义了这个函数,如下所示,是的!它们是动态 * 创建/定义 * 的:

jQuery.each( ("blur focus focusin focusout load resize scroll unload click
            dblclick " +
        "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
        "change select submit keydown keypress keyup error").split(" "), 
    function( i, name ) {
        // the magic happens here..
        //each string is added as a function to the prototype
        jQuery.fn[ name ] = function( fn ) {
                return fn ? this.bind( name, fn ) : this.trigger( name );
        };//if a handler is NOT specified then attach an event OR call/trigger it

        if ( jQuery.attrFn ) {
                jQuery.attrFn[ name ] = true;
        }
});

从这里开始,我们需要查看bind,现在bind()one()也是这样定义的。搜索 “Code:绑定和一个事件”here
从这里我使用chrome和http://jsfiddle.net/qu9bF/来单步执行代码。来自c.each(["bind"的块是如何定义bind函数的。源代码被缩小了,但是chrome can format it

从这里开始,代码调用JQuery.events.add,您可以在Events部分here下找到它。
下面这段代码的作用就是调用element.addEventListenerattachEvent,看看它是如何为attachEvent加上 on 的。

// Check for a special event handler
// Only use addEventListener/attachEvent if the special
// events handler returns false
if ( !special.setup || 
      special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
      // Bind the global event handler to the element
       if ( elem.addEventListener ) {
             elem.addEventListener( type, eventHandle, false );

        } else if ( elem.attachEvent ) {
             elem.attachEvent( "on" + type, eventHandle );
        }
 }

我希望它回答了你的两个问题。你可以链接到jquery源代码的非迷你版本,然后一步一步地浏览它来解决问题。有时候,IE9的调试器更直观(这是我唯一使用它的目的),使用我提到的页面来明智地浏览源代码。

6uxekuva

6uxekuva2#

jQuery将所有的事件绑定和数据缓存存储在jQuery.cache对象上。当您使用jQuery htmlemptyremovereplace等时,所有被jQuery Package 的DOM节点以及绑定到它们的事件或数据集将被自动清除。
这就是为什么绝不能使用innerHTML或其他原生DOM方法来插入/替换jQuery修改过的内容,这一点非常重要。这将导致泄漏,除非手动重置jQuery.cache对象,否则无法清除。
还有一个未公开的方法jQuery.cleanData,它将DOM节点的集合作为参数,并迭代它们,清除它们所有的事件绑定、数据,并该高速缓存中删除对这些元素的引用。如果您有从主DOM树分离的DOM片段,并且存在无法正确清除它们的风险,则该方法可能会很有用。

uubf1zoe

uubf1zoe3#

像click或submit这样的常规事件(当没有被jQuery绑定时)实际上只是DOM元素本身的属性(“onclick”、“onsubmit”)。
对于jQuery事件,当你绑定它们时,这个库会保存它自己的记录,当你触发它们时,它会查看它。jQuery把所有关于元素的数据放在一个标准的地方,你可以用$(e).data()访问这个地方。对于事件,它只是$(e).data('events')
您可以解除jQuery事件与$().unbind()的绑定,并使用delete关键字删除与给定事件对应的对象属性。

nc1teljy

nc1teljy4#

jQuery有自己的元素事件处理器Map,很少有理由担心这个,除非你在滥用这个库。

相关问题