请教一下,如何用 js 合并连续的相同的 span

2021-11-02 09:44:05 +08:00
 shubei

=>

情已 逐晓云空

2409 次点击
所在节点    程序员
29 条回复
shubei
2021-11-02 09:45:49 +08:00
<\span>高<\/span>
<\span class="del">情<\/span>
<\span class="del">已<\/span>
<\span class="match"><\span class="add">逐<\/span><\span class="add">晓<\/span><\/span>
<\span>云</span>
<\span>空</span>
shubei
2021-11-02 09:46:17 +08:00
.. 可以注入的竟然
shubei
2021-11-02 09:48:48 +08:00
<\span>高<\/span>
<\span class="del">情<\/span>
<\span class="del">已<\/span>
<\span class="match"><\span class="add">逐<\/span><\span class="add">晓<\/span><\/span>
<\span class="match"><\span>云</span><\span>空</span><\/span>

=>

<\span>高<\/span>
<\span class="del">情已<\/span>
<\span class="match"><\span class="add">逐晓<\/span><\span>云空</span><\/span>
AoEiuV020
2021-11-02 09:52:21 +08:00
感觉只能普通的循环遍历然后一个一个判断构造新的,
kkocdko
2021-11-02 09:57:41 +08:00
@shubei 不是注入,是 markdown
zhea55
2021-11-02 10:01:09 +08:00
用 jquery 的话,非常简单。

找到这些所有 span 的父节点

$(parentNode).text()
waiaan
2021-11-02 10:02:53 +08:00
@zhea55
它要合并相同 class 的文字,这个就只能遍历了。
zhea55
2021-11-02 10:07:13 +08:00
@waiaan 哦,感觉有发帖这个时间,代码都写完了。


浪费时间、浪费生命。
shubei
2021-11-02 10:12:39 +08:00
主要有 match 这种的嵌套,双指针好像不好使
zhea55
2021-11-02 10:20:17 +08:00
@shubei 迭代的时候,把当前循环元素的 classname 拿出来,

在当前循环元素的 siblings 里面查找这个选择器。就拿到了所有同类,然后.text(),然后去空格。



然后下一个的 classname 要是和上次循环的一样,continue


再说下去,代码都给你写好了。
rongchuan
2021-11-02 10:28:49 +08:00
最简单的方式,获取 dom 字符串,用正则匹配处理,想咋弄都行。弄完如果没有光标需求,直接 innerHTML 完事。要操作光标就用 appendChild
shubei
2021-11-02 10:29:55 +08:00
@zhea55 额,首先我这个就是单纯的字符串,并没有渲染,所以 siblings 、text 这些都不能用(因为就是 dom 节点过多,所以在渲染前用 js 合并一下的),然后对于字串符而言,我遇到的第一个问题就是用什么 split ,我最早的版本是用</span>,加了 match 之后不好使了
zhea55
2021-11-02 10:33:34 +08:00
@shubei 你这些数据,应该是入库之前就应该把数据整理好。

入库前爬取程序,一定是有 dom 节点的。


你要处理字符串的话,即使你用正则表达式,还是容易出现很多异常情况。


远远没有处理 dom 节点的代码可靠。
zjsxwc
2021-11-02 10:34:19 +08:00
搞个 html parser https://github.com/andrejewski/himalaya
后当普通数据处理呗
shubei
2021-11-02 10:36:31 +08:00
@zhea55 唉,这就孩子没娘,说来话长了呀。反正现在就堆到我这里了 [大哭]
cyrbuzz
2021-11-02 10:38:06 +08:00
这个用 CSS 选择器啦。
```
let plus = document.querySelectorAll("span + span")
let temp1 = plus[0]
temp1.previousSibling.innerText += temp1.innerText
temp1.parentElement.removeChild(temp1)
```

首先遍历一遍 span ,没有 class 的一律先加一个虚拟 class ,然后把所有 class 找出来,去重,所有 class 挨个跑上面的代码,最后把虚拟的 class 去掉就完事了。
shubei
2021-11-02 10:45:34 +08:00
@cyrbuzz 兄弟 看 12 楼,我想在渲染之前通过 js 直接合并好
cyrbuzz
2021-11-02 10:51:47 +08:00
@shubei

那你这不 parse 一下处理 DOM ,DOM 没有那么脆弱。刚打开一个 13WDOM 的页面只占用 31MB(当然每个的内容比较少)。
shubei
2021-11-02 10:56:13 +08:00
@cyrbuzz 也可能是我别的地方有问题?我是用的 v-html 。原文 span 比较多,接口 200ms ,js 循环一遍 140ms ,但是渲染出来就要 2s 左右了
ookkxw
2021-11-02 11:17:24 +08:00
感觉纯 string 处理难点在于切割同时还要区分有没有子节点,我写的话先全部<\/span>切割掉变成数组,然后循环变成 VDOM tree ,接下来就简单了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/812340

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX