相关疑难解决方法(0)

JavaScript闭包中的内存泄漏风险

解决了

关于这个问题,网上有很多矛盾的信息.感谢@John,我设法解决了闭包(如下所示)不是内存泄漏的原因,即使在IE8中 - 它们并不像人们所说的那样普遍.事实上,我的代码中只发生了一次泄漏,事实证明并不难解决.

从现在开始,我对这个问题的回答是:
AFAIK是唯一一次IE8泄漏的时候,就是在全局对象上设置了事件/处理程序.(window.onload,window.onbeforeunload,...).要解决这个问题,请参阅下面的答案.


巨大的更新:

我现在已经完全迷失了......经过一段时间深入挖掘新旧文章,我至少留下了一个巨大的矛盾.尽管之一 JavaScript的大师的(道格拉斯·克罗克福德)说:

由于IE无法完成其工作并重新开始循环,因此我们不得不这样做.如果我们明确地打破循环,那么IE将能够回收内存.根据微软的说法,闭包是造成内存泄漏的原因.这当然是非常错误的,但它导致微软向程序员提供了关于如何应对微软错误的非常糟糕的建议.事实证明,很容易打破DOM端的循环.几乎不可能在JScript端打破它们.

正如@freakish所指出的,我的下面的代码段与jQuery的内部工作类似,我觉得我的解决方案不会导致内存泄漏.与此同时,我找到了这个MSDN页面,该部分Circular References with Closures对我特别感兴趣.下图几乎是我的代码如何工作的示意图,不是它:

带闭包的循环引用

唯一的区别是我的常识是不将我的事件监听器附加到元素本身.
所有相同的Douggie都是非常明确的:闭包不是IE中mem泄漏的根源.这个矛盾使我无法理解谁是对的.

我也发现泄漏问题在IE9中也没有完全解决(找不到链接ATM).

最后一件事:我还得知IE管理JScript引擎之外的DOM,当我<select>根据ajax请求更改元素的子元素时,这让我感到烦恼:

function changeSeason(e)
{
    var xhr,sendVal,targetID;
    e = e || window.event;//(IE...
    targetID = this.id.replace(/commonSourceFragment/,'commonTargetFragment');//fooHomeSelect -> barHomeSelect
    sendVal = this.options[this.selectedIndex].innerHTML.trim().substring(0,1);
    xhr = prepareAjax(false,(function(t)
    {
        return function()
        {
            reusableCallback.apply(this,[t]);
        }
    })(document.getElementById(targetID)),'/index/ajax');
    xhr({data:{newSelect:sendVal}});
}

function reusableCallback(elem)
{
    if (this.readyState === 4 && this.status === 200)
    {
        var data = JSON.parse(this.responseText);
        elem.innerHTML …
Run Code Online (Sandbox Code Playgroud)

javascript closures memory-leaks cross-browser

26
推荐指数
1
解决办法
9003
查看次数

JavaScript:如何模拟Internet Explorer中的更改事件(委派)

更新:( 回顾,小提琴和赏金)

这个问题并没有得到太多的关注,所以我要花一些代表.我知道我的答案和问题往往过于冗长.这就是为什么我继续设置这个小提琴,在我看来,这是我目前不得不用来接近冒泡change事件的代码.我正试图解决的几个问题:

  1. pseudo-change事件不会触发一个select元素,除非它失去焦点.在某些情况下,应在选择新值时重定向客户端.我该如何实现这一目标?
  2. 单击标签时调用处理程序,以及复选框本身.这本身就是你所期望的,但是由于事件冒泡它(AFAIK)无法确定点击了哪个元素.IE的事件对象没有realTarget属性.
  3. checked通过单击标签在IE中更改复选框的-state时,一切都很好(虽然它需要一些讨厌的解决方法),但是当直接单击复选框时,会调用处理程序,但是检查状态保持不变,直到我单击一个第二次.然后值会更改,但不会调用处理程序.
  4. 当我切换到另一个选项卡,然后再次返回时,会多次调用该处理程序.如果检查状态实际发生了变化,则三次,如果我直接单击一次,则两次.

任何可以帮助我解决上述一个或多个问题的信息将不胜感激.拜托,我没有忘记添加一个jQuery标签,我喜欢纯JS,所以我正在寻找一个纯粹的JS答案.


我有一个网页上有超过250个选择元素,以及20~30个复选框.我还必须跟踪用户的操作,并采取适当的措施.因此,我很自然地委派变更事件,而不是添加数百个听众,恕我直言.

当然,IE -company策略:IE8必须得到支持 - 在我需要时不会触发onchange事件.所以我想假装一个onchange事件.到目前为止,我所做的工作相当不错,除了一件真正让我烦恼的事情.
我正在使用onfocusinonfocusout注册活动.在某些情况下,当用户从select元素中选择一个新值时,脚本应立即响应.但是,只要选择没有失去焦点,就不会发生这种情况.

这是我到目前为止所提出的:

i = document.getElementById('content');
if (!i.addEventListener)
{
    i.attachEvent('onfocusin',(function(self)
    {
        return function(e)
        {
            e = e || window.event;
            var target = e.target || e.srcElement;
            switch (target.tagName.toLowerCase())
            {
                case 'input':
                    if (target.getAttribute('type') !== 'checkbox')
                    {
                        return true;
                    }
                    return changeDelegator.apply(self,[e]);//(as is
                case 'select':
                    self.attachEvent('onfocusout',(function(self,current)
                    {
                        return function(e)
                        {
                            e = e || window.event; …
Run Code Online (Sandbox Code Playgroud)

javascript internet-explorer javascript-events event-delegation

14
推荐指数
1
解决办法
3072
查看次数

addEventListener() 的替代快捷方式

可能的重复:
使用 addEventListener 有什么区别?

我注意到可以直接在对象上分配事件,而不必使用 addEventListener:

document.onload = function(e){
  // do stuff..
};
Run Code Online (Sandbox Code Playgroud)

代替:

document.addEventListener('load', function(e){
  // do stuff..
});
Run Code Online (Sandbox Code Playgroud)

那么有什么理由我不应该使用第一种方法吗?为什么其他人不使用它?

这似乎也适用于旧的 IE(在其中您需要 attachEvent)。

javascript optimization javascript-events

3
推荐指数
1
解决办法
7710
查看次数