jQuery - .remove()方法和.html('')方法的区别

3
在下面的例子中,.remove() 和 .html("") 有什么区别吗?我在哪里可以找到相关的JS代码?
HTML
 <div class="wrap">
   <div class="content"> <div> ... </div></div>
 </div>

JS

$('.content').remove();

//vs

$('.wrap').html('');

1
它们在你的测试用例中在功能上是等效的,但这仅因为 .wrap 包含一个具有类 .content 的单个子元素 - Terry
@Terry 谢谢,当然我指的是更复杂的情况,我修改了我的问题。 - user5372
.remove() 会移除元素,而 .html('') 则会删除元素中的内容(.html('') 还有一个快捷方式:.empty() ;))。 - Toni Michel Caubet
即使进行编辑,这两行JS代码仍然具有相同的功能。 - Terry
3个回答

2
在下面的示例中,.remove()和.html("")有区别吗?
没有显著区别,因为在您的示例中,唯一的.wrap元素包含唯一的.content元素。这仅仅是由于元素之间的关系而产生的。
在两种情况下,jQuery都会确保释放由.content及其后代(如果有)引用的任何数据和事件处理程序,然后删除相关元素。如果您想了解速度方面的问题,那么答案几乎总是会因目标浏览器而异,所以请在目标浏览器上进行测试,看看它是否重要,但是this answer提到了删除节点和设置innerHTML之间速度差异的内容(答案让我感到惊讶)。
在哪里可以找到引用的JS代码?
jQuery源代码中。

关于您的评论:

感谢您提供jQuery链接,我当然看了这个库,但是我找不到.html()函数在哪里定义(抱歉,我是JavaScript新手)

如果您是JavaScript新手,我不建议您尝试理解jQuery源代码 - 它非常复杂,并使用许多技巧来保持大小并具有很多实用性。

但是我要注意一下,因为在这一点上存在混淆,jQuery的html函数不仅仅是在相关元素上设置innerHTML。它做了更多的工作,以防止内存泄漏并释放不再需要的数据。目前详细信息在 manipulation.js 中的 第407行(当然,随着时间的推移,该行号将会改变),但是再次强调,这是高级内容,我不建议您在JavaScript教育的早期就跳入其中。


谢谢提供 jQuery 的链接,我当然看了这个库,但是我找不到 .html() 函数在哪里定义(抱歉,我刚接触 js)。 - user5372

2
基本上,它们是相同的,但实际上(如果你对细节挑剔),这里有区别:
$('.wrap').html('');
console.log( $('body').html() );  // see below

//  <div class="wrap"></div>

vs:

$('.content').remove();
console.log( $('body').html() ); // see below

//    <div class="wrap">
//
// </div>
.remove()方法删除元素,而使用.html("")实际上是将HTML元素格式化为仅包含空字符串。虽然.remove()有其优点,在这里解释了:http://api.jquery.com/remove/

类似于 .empty() 方法,.remove() 方法从 DOM 中取出元素。当您想要删除元素本身以及其中的所有内容时,请使用 .remove()。除了元素本身之外,还删除与元素相关联的所有绑定事件和 jQuery 数据。要删除元素而不删除数据和事件,请改用 .detach()。

所以,如果与您刚刚删除的元素相关的某些复杂内容,例如事件处理程序、数据、操作、引用等,都将被垃圾回收并且不能访问,从而提高了内存利用率并获得了一些性能。使用.detach(),您无需为以后在DOM中再次包含它们的相同选择器重置事件处理程序等。 为什么上述内容(提到.empty())很有趣,是因为当使用"string"作为参数时,.html()方法执行的操作是遍历所有元素的选择器并清除内部节点和数据(以防止内存泄漏):
jQuery.cleanData(getAll(elem, false));
elem.innerHTML = value;

在那个循环内部,你可以看到如果使用 innerHTML 成功的话,它会设置:elem = 0 // the innerHTML was successful!! YEY

所以,是使用 elem.innerHTML 来赋值传递的参数值(如果可能的话)。

如果仍然存在匹配的 eleminnerHTML 出问题或抛出错误导致捕获),它只会执行: this.empty().append( value );

因此,让我们来看看 .empty() 方法到底是做了些什么jQ source line 309

for ( ; (elem = this[i]) != null; i++ ) {        // Loops the selectors
    if ( elem.nodeType === 1 ) {                 // If it's an Element node 
      jQuery.cleanData( getAll( elem, false ) ); // Prevent memory leaks
      elem.textContent = "";                     // Remove any remaining nodes
                                                 // using the native textContent
                                                 // which is from jQ v2 I think.
    }
}

现在是时候看看 .remove()jQ 源代码第 359 行 到底是做什么的了:

remove: function (selector, keepData /* Internal Use Only */ ) {
    // the .detach() method uses keepData, but not we,
    // we're only using .remove() as a bound Method to our selector
    // so `elems>>>this` in the code below will be our fella.
    var elem,
    elems = selector ? jQuery.filter(selector, this) : this,
        i = 0;
    for (;
    (elem = elems[i]) != null; i++) {
        if (!keepData && elem.nodeType === 1) { // yes, no keepData!
            jQuery.cleanData(getAll(elem));     // remove all data stored
        }
        if (elem.parentNode) { // Yes, our element has a parentNode
            if (keepData && jQuery.contains(elem.ownerDocument, elem)) { //no..
                setGlobalEval(getAll(elem, "script")); // not our case...
            }
            elem.parentNode.removeChild(elem); // jQ data are removed now go with
                                               // the native way of doing things!
        }
    }
    return this; // (maintains Methods chainability...)
}

0

是的,在你的例子中两者之间有区别。

.remove();

当你想要删除元素本身以及其中的所有内容时,请使用 .remove()。所以在你的情况下,只有<div class="content"> <div>从 DOM 中被移除。它将变成:

<div class="wrap">
 ... </div></div>
</div>

.html('');

这个代码用于设置元素的内容。在你的情况下,所有在.wrap内部的div都将被替换为''。它将变成:

<div class="wrap"></div>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接