1

我相信那是一个棘手的问题。我想将两个标签合并在一起。例如,<span>具有不同 ID 的两个彼此相邻,如下所示:

Lorem ipsum <span id="selected-1">dolor sit</span><span id="selected-2" title="important info here"> amet, consectetur</span> adipiscing elit.

最后,我想合并selected-1保留 to 的属性selected-2最终带有如下内容:selected-2

Lorem ipsum <span id="selected-2" title="important info here">dolor sit amet, consectetur</span> adipiscing elit.

有小费吗?我实在想不通这个。

谢谢。

4

6 回答 6

1

这里真的没有必要使用 jQuery,它必须完成对 DOM 节点进行字符串化然后重新解析它们以将它们放回 DOM 的所有工作。

var span1=document.getElementById("selected-1"), 
    span2=document.getElementById("selected-2"),
    insert=span2.firstChild,
    elt;

while (elt=span1.lastChild) {
  insert=span2.insertBefore(elt,insert); // removes the node from span1
}

span1.parentNode.removeChild(span1);

确实,OP 询问了 jQuery 解决方案。但是如果有人问如何用瑞士军刀敲钉子,建议用锤子代替似乎还是合理的,特别是如果他们已经有锤子,应该知道如何使用它,并且使用它会快 100 倍。

我知道大多数应用程序都使用 jQuery,因此加载它不会增加成本。在许多情况下,它确实提供了一种令人满意的简洁性——当你把所有东西都放在一条线上时,催产素的小冲动。但也有成本。性能成本可能高达两个数量级,还有将程序员隐藏在真正发生的事情之外的成本。

在这种情况下,如果 OP 知道四个基本的 DOM API,他可能已经想出了如何编写简单的单行 while 循环将元素从一个地方移动到另一个地方,而不是试图弄清楚什么神奇一系列 jQuery 咒语链接在一起以实现这一目标,卡住了,不得不发布到 SO。

考虑http://jsperf.com/combine-dom-nodes上的性能比较,它表明 jQuery 解决方案慢了 100 倍。

另一方面,即使是 Brendan Eich 似乎也开始转向 jQuery 链式单线范式,给出以下示例:

$(document).getTDs().getEven().hover().css("yellow").addCustomEvent("setSelected").setSelected(this.currentMagicNode).get.out("white").getTDs().getOdd().hover().css("yellow").addCustomEvent("setSelected").setSelected(this.currentMagicNode).out("white");

并评论说,“事后看来,我明白为什么 JavaScript 从未流行起来”,Brendan 说。“所有这些分号和换行符使代码非常难以阅读。而且你水平阅读代码,而不是垂直阅读 - DUHHHH!JavaScript 没有赢!” 请参阅http://clubajax.org/brendan-eich-redesigns-javascript-to-look-like-jquery/#more-1491

于 2012-06-21T02:49:13.937 回答
1

这是我的 1 行版本:

$('#selected-2').html( $('#selected-1').html() + $('#selected-2').html() ).prev().remove();

...甚至是更短的版本。

$('#selected-2').prepend($('#selected-1').html()).prev().remove();

更短的版本 = 需要下载的代码更少(尤其是对于移动浏览器)。


编辑:由于我的简短单行答案陷入困境并且与此页面上最长的标记答案正面交锋,因此重要的并不总是基准速度,而只是代码的功能和维护。

此外,每秒计算量并不等同于真实世界和真实浏览器页面渲染,最终不会显示出真正的性能提升。

恕我直言,在现实世界中使用一行标记比一大堆代码更实用和更常识,而这些代码很容易出现用户创建的错误(每个 i 点和每个 t 交叉点),这也会创建更多数据(.js 文件)下载和解析。

于 2012-06-21T02:29:35.810 回答
1

三行应该做到这一点:

$("#selected-1").html($("#selected-1").html() + $("#selected-2").html());
$("#selected-1").attr("title", $("#selected-2").attr("title"));
$("#selected-2").remove()
于 2012-06-21T02:11:22.653 回答
1

希望这是最简单的方法(严格按照示例进行):

var s1 = $('#selected-1').html();
$('#selected-1').remove();
$('#selected-2').prepend(s1);

您可以在http://jsfiddle.net/KFXRe/上验证这一点。

于 2012-06-21T02:15:24.593 回答
0

我没有测试你所有的解决方案,但我附带了这段代码:

var $wrapper = $( "#selected-1, #selected-2" )
    .wrapAll( "<span title='" + $( "#selected-2" ).attr( "title" ) + "'></span>" )
    .parent();

$( "#selected-1, #selected-2" ).replaceWith(function() {
    return $( this ).html();
});

$wrapper.attr( "id", "selected-2" );

我不知道我的方式是否更快......

于 2012-06-21T02:26:11.523 回答
0
var s1= $('#selected-1');
var s2= $('#selected-2');
s2.html(s1.html()+s2.html());
s1.remove();

基本上,我单独获取元素。然后我将第一个元素中的 html 和当前在第二个元素中的 html 插入到第二个元素中(否则它将被覆盖)。最后,但同样重要的是,我删除了第一个元素。

->>>>>>> jsFiddle <<<<<<-

于 2012-06-21T02:11:06.473 回答