0

脚本很长,所以我会尽量解释而不是全部粘贴。编辑:看起来我确实需要展示更多。

每秒几次我用新内容更新 UL(调用 updateDomTree)。DOM 树表示 CKEditor 中的元素。

function updateDomTree(editor) {
    var selection = editor.getSelection();
    var jqElements = $(document.createElement('div'));
    var editorData = editor.document.getBody();
    var kids = editorData.getChildren();

    // Gather LI to represent Editor content DOM element hierarchy
    for (var i = 0, len = kids.count(); i < len; i++) {
        jqElements.append(HandleNode(kids.getItem(i), selectedElement, editor));
    }

    var domUL = document.createElement('ul');
    domUL.id = "dom";
    var jqUL = $(domUL).append(liElements);
    $(document.getElementById('dom')).replaceWith(jqUL);
}

// This is a recursive function, but it has no other issues than the memory leak
// If I comment out the click event, it works fine. 
// The **obj** variable is why I don't use the "delegation" method.
function HandleNode(obj, selection, editor) {
    // do other stuff, handle recursion etc.
    liElement.on('click', function(e) {
        editor.getSelection().selectElement( obj );
        editor.focus();
        editor.getSelection().scrollIntoView();
        e.stopPropagation();
    }); 
    return liElement;
}

现在在 IE9 中,内存使用开始迅速攀升。如果我注释掉点击处理程序,内存泄漏就会消失,但我没有任何功能。我将如何解决这个问题?

替代解释:#dom 是 DOM 结构的 UL 可视化表示,我需要单击事件来引用元素,这就是为什么在单击事件处理程序创建期间需要对象引用的原因。当底层 DOM 发生变化时,UL 表示应该反映这种变化,这就是快速更新的原因。

4

2 回答 2

2

li您可以使用事件委托并将一个处理程序绑定到ul自身,而不是每次创建元素时都创建一个新的处理程序:

// when you create the list :
$('#dom').on('click', 'li', function(e) {
    // do some cool stuff
    e.stopPropagation();
});

// instead of creating a new ul,
// replace thhe existing ul's content
$('#dom').empty().append(liElements);

如果您需要为每个节点存储自定义数据,请尝试使用以下.data()功能:

$(liElement).data('obj', obj);

然后,您可以从处理程序访问它:

$('#dom').on('click', 'li', function(e) {
    var obj = $(this).data('obj');
    ...
    e.stopPropagation();
});

有了这种设计,javascript 就不必维护一个实时闭包来保持对obj变量的访问。我不是 100% 肯定它会吹走你的内存泄漏,你必须测试并看看。

于 2013-07-10T07:56:19.763 回答
0

将它委托给 UL 的级别,只需设置它直到 UL 元素是 DOM 可用:

$('#dom').on('click','li', function(e) {
    // do some cool stuff
    e.stopPropagation(); //stopPropagation couldn't give you expected result depending why you need to stop bubbles and at which level, check it.
}); 
于 2013-07-10T07:54:43.947 回答