{"id":10635,"date":"2022-11-30T22:21:27","date_gmt":"2022-11-30T14:21:27","guid":{"rendered":"https:\/\/www.zhangxinxu.com\/wordpress\/?p=10635"},"modified":"2022-11-30T22:50:39","modified_gmt":"2022-11-30T14:50:39","slug":"js-text-node-master","status":"publish","type":"post","link":"https:\/\/www.zhangxinxu.com\/wordpress\/2022\/11\/js-text-node-master\/","title":{"rendered":"\u4ece\u4eca\u5929\u5f00\u59cb\uff0c\u8bf7\u53eb\u6211Node\u6587\u672c\u8282\u70b9\u5904\u7406\u5927\u5e08"},"content":{"rendered":"<p>by <a href=\"https:\/\/www.zhangxinxu.com\/\">zhangxinxu<\/a> from <a href=\"https:\/\/www.zhangxinxu.com\/wordpress\/?p=10635\">https:\/\/www.zhangxinxu.com\/wordpress\/?p=10635<\/a> \u946b\u7a7a\u95f4-\u946b\u751f\u6d3b<br \/>\n\u672c\u6587\u6b22\u8fce\u5206\u4eab\u4e0e\u805a\u5408\uff0c\u5168\u6587\u8f6c\u8f7d\u5c31\u4e0d\u5fc5\u4e86\uff0c\u5c0a\u91cd\u7248\u6743\uff0c\u5708\u5b50\u5c31\u8fd9\u4e48\u5927\uff0c\u82e5\u6025\u7528\u53ef\u4ee5\u8054\u7cfb\u6388\u6743\u3002<\/p>\n<p><script>window.wxShareImgUrl = 'https:\/\/www.zhangxinxu.com\/study\/image\/share\/202211-textnode.jpg';<\/script><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/image.zhangxinxu.com\/image\/blog\/202211\/node-cover.jpg\" width=\"480\" height=\"312\" alt=\"\u5c01\u9762\u56fe node\u8282\u70b9\" class=\"alignright clip thumb size-medium\" \/><\/p>\n<p>\u6700\u8fd1\u505a\u7684\u67d0\u4e2a\u9879\u76ee\u9700\u8981\u5927\u91cf\u7684DOM\u8282\u70b9\u4ea4\u4e92\uff0c\u4ee5\u524d\u8fd9\u4e9bAPI\u90fd\u662f\u4e34\u65f6\u7528\u7528\uff0c\u8fd9\u4e00\u6b21\u90fd\u662f\u6df1\u5165\u5b9e\u8df5\uff0c\u611f\u89c9\u5b8c\u5168\u4e0d\u4e00\u6837\u3002<\/p>\n<p>\u679c\u7136\uff0c\u5b9e\u8df5\u624d\u662f\u7cbe\u6df1\u6280\u672f\u6700\u597d\u7684\u65b9\u5f0f\u3002<\/p>\n<p>\u8d81\u7740\u8fd8\u5f88\u6e29\u70ed\uff0c\u611f\u89c9\u603b\u7ed3\u68b3\u7406\u4e0b\u3002<\/p>\n<p>\u6ce8\uff1a\u672c\u6587\u7ae0\u6240\u4f7f\u7528\u7684 API \u5747\u4e0d\u8003\u8651 IE \u6d4f\u89c8\u5668\uff0c\u4ee5\u6587\u672c\u8282\u70b9\u5904\u7406\u4e3a\u4e3b\u3002<\/p>\n<h3>\u4e00\u3001\u5e38\u89c1\u65b9\u6cd5<\/h3>\n<p>\u9700\u8981\u4e86\u89e3\u7684\u57fa\u672c\u6982\u5ff5\uff1a<\/p>\n<blockquote><p>\u6587\u672c\u8282\u70b9\u5c31\u662f\u7eaf\u6587\u5b57\u8282\u70b9\uff0c\u5143\u7d20\u8282\u70b9\u5c31\u662f\u6709HTML\u6807\u7b7e\u7684\u5143\u7d20\uff0c\u6587\u672c\u8282\u70b9\u548c\u5143\u7d20\u8282\u70b9\u90fd\u5c5e\u4e8e\u8282\u70b9\uff0c\u5728\u6587\u6863\u4e2d\u4f7f\u7528 Node \u8868\u793a\uff0c\u5143\u7d20\u8282\u70b9\u5728\u6587\u6863\u4e2d\u4f7f\u7528 Element \u8868\u793a\uff0c\u6587\u672c\u8282\u70b9\u5219\u662f\u4f7f\u7528 Text \u8868\u793a\u3002<\/p><\/blockquote>\n<h4>1. \u521b\u5efa\u6587\u672c\u8282\u70b9<\/h4>\n<p>\u4f7f\u7528 <code>document<\/code> \u5bf9\u8c61\u4e2d\u7684 <code>createTextNode<\/code> \u65b9\u6cd5\u3002<\/p>\n<p>\u4f8b\u5982\uff0c\u521b\u5efa\u4e00\u4e2a\u5185\u5bb9\u662f\u201cCSS\u65b0\u4e16\u754c\u201d\u7684\u6587\u672c\u8282\u70b9\uff0c\u5219\u53ef\u4ee5\uff1a<\/p>\n<pre>const textNode = document.createTextNode('CSS\u65b0\u4e16\u754c');<\/pre>\n<p>\u5982\u679c\u9879\u76ee\u4e0d\u9700\u8981\u517c\u5bb9IE\u6d4f\u89c8\u5668\uff0c\u4e5f\u53ef\u4ee5\u76f4\u63a5\u4f7f\u7528 Text() \u65b9\u6cd5\u8fdb\u884c\u6784\u9020\uff0c\u4f8b\u5982\uff1a<\/p>\n<pre>const textNode = new Text('CSS\u65b0\u4e16\u754c');<\/pre>\n<p>\u5728\u67d0\u4e9b\u573a\u666f\u4e0b\uff0c\u4e5f\u53ef\u4ee5\u4f7f\u7528 cloneNode() \u65b9\u6cd5\u4ee5\u514b\u9686\u7684\u65b9\u5f0f\u8fdb\u884c\u521b\u5efa\uff0c\u4f8b\u5982\u5e0c\u671b\u4e0b\u9762\u7684 <code>&lt;span&gt;<\/code> \u5143\u7d20\u540e\u9762\u53ef\u4ee5\u518d\u65b0\u589e\u201c\u771f\u68d2??\u201d\u8fd9\u6837\u7684\u5b57\u7b26\uff0c\u53ef\u4ee5\u8fd9\u4e48\u5904\u7406\uff1a<\/p>\n<pre>&lt;span id=\"span\"&gt;CSS\u65b0\u4e16\u754c&lt;\/span&gt;<\/pre>\n<pre>const firstChild = span.firstChild;\r\nconst appendNode = firstChild.cloneNode();\r\nappendNode.textContent = '\u771f\u68d2??';\r\nfirstChild.after(appendNode);<\/pre>\n<p>\u6b64\u65f6\uff0c\u867d\u7136\u89c6\u89c9\u4e0a\u6587\u5b57\u662f\u8fde\u7eed\u7684\uff0c\u5b9e\u9645\u4e0a\u4ee3\u7801\u5c42\u9762\u662f\u4e24\u4e2a\u72ec\u7acb\u7684\u8282\u70b9\uff1a<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/image.zhangxinxu.com\/image\/blog\/202211\/20221129-143239.png\" width=\"337\" height=\"108\" alt=\"\u72ec\u7acb\u6587\u672c\u8282\u70b9\u793a\u610f\" class=\"alignnone size-medium\" style=\"border:1px solid #ddd;\"  \/><\/p>\n<h4>2. \u6587\u672c\u8282\u70b9\u7684\u5185\u5bb9\u8bfb\u5199<\/h4>\n<p>\u6587\u672c\u8282\u70b9\u7684\u5185\u5bb9\u8bfb\u5199\u53ef\u4ee5\u4f7f\u7528 textContent \u5c5e\u6027\u5b8c\u6210\uff0c\u6ce8\u610f\uff0cinnerText \u662f\u65e0\u6548\u7684\uff0c\u56e0\u4e3a innerText \u662f HTMLElement \u65b9\u6cd5\uff0c\u4e0d\u662f Node \u65b9\u6cd5\u3002<\/p>\n<p>\u66f4\u591a\u533a\u522b\u53ef\u53c2\u89c1\u8fd9\u7bc7\u6587\u7ae0\uff1a\u201c<a href=\"https:\/\/www.zhangxinxu.com\/wordpress\/2019\/09\/js-dom-innertext-textcontent\/\">JS DOM innerText\u548ctextContent\u7684\u533a\u522b<\/a>\u201d\u3002<\/p>\n<p>\u4f7f\u7528\u793a\u610f\uff1a<\/p>\n<pre>span.lastChild.textContent = '\u786e\u5b9e\u4e0d\u9519';<\/pre>\n<p>\u5bf9\u4e8e\u6587\u672c\u8282\u70b9\uff0c\u4e5f\u53ef\u4ee5\u4f7f\u7528 nodeValue \u5c5e\u6027\u8fd4\u56de\u6587\u672c\u5185\u5bb9\u3002<\/p>\n<pre>Node.nodeValue;<\/pre>\n<p>\u7136\u800c\uff0c\u6709\u65f6\u5019\uff0c\u5f00\u53d1\u4eba\u5458\u5e0c\u671b\u83b7\u53d6\u7684\u662f\u6240\u6709\u76f8\u90bb\u7684\u6587\u672c\u5185\u5bb9\uff0c\u800c\u4e0d\u662f\u5f53\u524d\u6587\u672c\u8282\u70b9\uff0c\u53ef\u4ee5\u4f7f\u7528 wholeText \u5c5e\u6027\u8fdb\u884c\u83b7\u53d6\u3002<\/p>\n<p>\u4f8b\u5982\u4e0b\u56fe\u7684\u6f14\u793a\u6548\u679c\uff0c\u4e0a\u4e00\u4e2a\u6848\u4f8b\u4e2d\u7684 appendNode \u8282\u70b9\u5206\u522b\u6267\u884c textContent \u548c wholeText \u7684\u6548\u679c\uff0c\u53ef\u4ee5\u770b\u5230\uff0cwholeText\u5c06 SPAN \u5143\u7d20\u5185\u6240\u6709\u6587\u672c\u5185\u5bb9\u90fd\u8fd4\u56de\u4e86\u3002<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/image.zhangxinxu.com\/image\/blog\/202211\/20221129-152435(1).png\" width=\"174\" height=\"127\" alt=\"\u6587\u672c\u8282\u70b9\u5185\u5bb9\u83b7\u53d6\" class=\"alignnone size-medium\" style=\"border:1px solid #ddd;\" \/><\/p>\n<p>\u5c31\u7ed3\u679c\u800c\u8a00\uff0c\u7c7b\u4f3c\u4e8e\u5143\u7d20\u6267\u884c\u4e86 normalize() \u65b9\u6cd5\u540e\u7684\u6587\u672c\u503c\uff0c\u533a\u522b\u5728\u4e8e\uff0c\u6b64\u65f6\u7684\u6587\u672c\u8282\u70b9\u4f9d\u7136\u90fd\u662f\u72ec\u7acb\u7684\u8282\u70b9\uff0c\u800c normalize() \u4f1a\u8ba9\u6240\u6709\u7684\u6587\u672c\u8282\u70b9\u5408\u5e76\u4e3a\u4e00\u4e2a\u3002<\/p>\n<h4>3. \u8282\u70b9\u7684\u63d2\u5165<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/image.zhangxinxu.com\/image\/blog\/202211\/leisa.jpg\" width=\"200\" height=\"174\" alt=\"\u63d2\u5165\u5fc3\u810f\" class=\"alignleft size-medium\" \/> \u5916\u524d\u63d2\u4f7f\u7528 before() \u65b9\u6cd5\uff0c\u5916\u540e\u63d2\u4f7f\u7528 after() \u65b9\u6cd5\uff0c\u5185\u524d\u7f6e\u4f7f\u7528 prepend() \u65b9\u6cd5\uff0c\u5185\u540e\u7f6e\u4f7f\u7528 append() \u65b9\u6cd5\u3002<\/p>\n<p>\u76f8\u6bd4\u4f20\u7edf\u7684 insertBefore() \u548c appenChild() \u65b9\u6cd5\uff0c\u4e0a\u9762\u51e0\u4e2a\u65b9\u6cd5\u652f\u6301\u4e00\u6b21\u6027\u64cd\u4f5c\u591a\u4e2a\u5143\u7d20\uff0c\u8fd9\u5728\u591a\u8282\u70b9\u540c\u65f6\u5904\u7406\u7684\u65f6\u5019\u975e\u5e38\u6709\u7528\u3002<\/p>\n<p>\u4e3e\u4e2a\u4f8b\u5b50\uff0c\u6709\u5982\u4e0b HTML \u5143\u7d20\u5185\u5bb9\uff1a<\/p>\n<pre>&lt;p id=\"from\"&gt;&lt;strong&gt;\u300aCSS\u65b0\u4e16\u754c\u300b&lt;\/strong&gt;\u8fd9\u672c\u4e66\u662f\u771f\u7684\u4e0d\u9519\uff01&lt;\/p&gt;\r\n\r\n&lt;div id=\"to\"&gt;&lt;\/div&gt;<\/pre>\n<p>\u5e0c\u671b #from \u5143\u7d20\u4e2d\u7684\u6240\u6709\u8282\u70b9\u8f6c\u79fb\u5230 #to \u5143\u7d20\u4e2d\uff0c\u5728\u8fc7\u53bb\uff0c\u6211\u4eec\u9700\u8981\u4f7f\u7528\u5faa\u73af\u53bb\u5904\u7406\uff0c\u73b0\u5728\uff0c\u4e0d\u9700\u8981\u4e86\uff0c\u53ea\u9700\u8981\u4f7f\u7528 apply \u65b9\u6cd5\uff0c\u5c06 NodeList \u4f5c\u4e3a\u53c2\u6570\u4f20\u8fdb\u53bb\u5c31\u597d\u4e86\uff0c\u793a\u610f\u5982\u4e0b\uff1a<\/p>\n<pre>to.append.apply(to, [...from.childNodes]);<\/pre>\n<p>PS: \u5173\u4e8e\u4e0a\u9762\u56db\u4e2a\u65b9\u6cd5\uff0c\u6211\u4e4b\u524d\u6709\u8be6\u7ec6\u4ecb\u7ecd\u8fc7\uff0c\u53ef\u53c2\u89c1\u201c<a href=\"https:\/\/www.zhangxinxu.com\/wordpress\/2017\/09\/js-dom-before-after-replacewith-append-prepend\/\">before(),after(),prepend(),append()\u7b49\u65b0DOM\u65b9\u6cd5\u7b80\u4ecb<\/a>\u201d\u4e00\u6587\u3002<\/p>\n<h4>4. \u8282\u70b9\u7684\u66ff\u6362<\/h4>\n<p>\u5728\u8fc7\u53bb\uff0c\u8282\u70b9\u66ff\u6362\u90fd\u662f\u4f7f\u7528 replaceChild() \u65b9\u6cd5\uff0c\u8bed\u6cd5\u793a\u610f\uff1a<\/p>\n<pre>parentNode.replaceChild(newChild, oldChild)<\/pre>\n<p>\u5982\u4eca\uff0c\u53ea\u8981\u4f60\u7684\u9879\u76ee\u4e0d\u9700\u8981\u517c\u5bb9 IE \u6d4f\u89c8\u5668\uff0c\u5c31\u6ca1\u6709\u4efb\u4f55\u7406\u7531\u4f7f\u7528\u6b64\u65b9\u6cd5\u7684\uff0c\u8bf7\u4f7f\u7528 replaceWith() \u6216 replaceChildren() \u65b9\u6cd5\u4ee3\u66ff\uff0c\u8bed\u6cd5\u66f4\u7b80\u5355\u66f4\u7b26\u5408\u76f4\u89c2\u8ba4\u77e5\uff0c\u652f\u6301\u591a\u53c2\u6570\u3002<\/p>\n<pre>Node.replaceWith(node1, node2, \/* \u2026 ,*\/ nodeN);\r\nElement.replaceChildren(node1, node2, \/* \u2026 ,*\/ nodeN)<\/pre>\n<p>\u5176\u4e2d\uff0creplaceWith \u662f\u66ff\u6362\u5f53\u524d\u5143\u7d20\uff0creplaceChildren \u662f\u66ff\u6362\u5f53\u524d\u5143\u7d20\u7684\u6240\u6709\u5b50\u5143\u7d20\u3002<\/p>\n<p>\u6b64 API \u5728\u540e\u7eed\u7684\u6848\u4f8b\u4e2d\u4f1a\u6709\u4e0d\u592a\u9686\u91cd\u7684\u51fa\u573a\u3002<\/p>\n<h4>5. \u8282\u70b9\u7684\u5206\u5272\u4e0e\u5408\u5e76<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/image.zhangxinxu.com\/image\/blog\/202211\/dianjuren.jpg\" width=\"125\" height=\"82\" alt=\"\u7535\u952f\u5206\u5272\" class=\"alignleft size-medium\" \/> \u6709\u65f6\u5019\u6211\u4eec\u5e0c\u671b\u4e00\u4e2a\u6587\u5b57\u8282\u70b9\u5206\u6210\u4e24\u4e2a\u4e0d\u540c\u7684\u6587\u672c\u8282\u70b9\uff0c\u4ee5\u4fbf\u7ee7\u7eed\u4e4b\u540e\u7cbe\u7ec6\u7684\u63a7\u5236\u5904\u7406\uff0c\u4f8b\u5982\u66ff\u6362\uff0c\u88c5\u8f7d\uff0c\u5220\u9664\u7b49\u3002<\/p>\n<p>\u6b64\u65f6\u53ef\u4ee5\u4f7f\u7528 splitText() \u65b9\u6cd5\uff0c\u8bed\u6cd5\u5982\u4e0b\uff1a<\/p>\n<pre>newNode = textNode.splitText(offset)<\/pre>\n<p>\u4e3e\u4e2a\u4f8b\u5b50\uff0c\u6709HTML\u5982\u4e0b\uff1a<\/p>\n<pre>&lt;style&gt;\r\n.red {\r\n  color: red;\r\n}\r\n.blue {\r\n  color: blue;\r\n}\r\n&lt;\/style&gt;\r\n\r\n&lt;span class=\"red\"&gt;\u6211\u662f\u7ea2\u8272&lt;\/span&gt;\u6211\u662f\u9ed8\u8ba4\u8272<\/pre>\n<p>\u6b64\u65f6\uff0c\u7528\u6237\u4f7f\u7528\u9f20\u6807\u6846\u9009\u4e86\u201c\u7ea2\u8272\u201d\u52a0\u540e\u9762\u7684\u201c\u6211\u662f\u201d\uff0c\u7136\u540e\u5e0c\u671b\u8bbe\u7f6e\u4e3a\u84dd\u8272\uff0c\u6b64\u65f6\uff0csplitText() \u65b9\u6cd5\u5c31\u6d3e\u4e0a\u7528\u573a\u4e86\u3002<\/p>\n<p>\u4ee3\u7801\u793a\u610f\uff08\u975e\u5b9e\u9645\u4ee3\u7801\uff0c\u4ec5\u8003\u8651\u7406\u60f3\u573a\u666f\uff09\uff1a<\/p>\n<pre>const selection = document.getSelection();\r\nif (selection.rangeCount &amp;&amp; !selection.collapsed) {\r\n  const range = selection.getRangeAt(0);\r\n  const startNode = range.startContainer;\r\n  const endNode = range.endContainer;\r\n  \r\n  \/\/ \u5206\u5272\u5566\r\n  var eleSet = document.createElement('span');\r\n  eleSet.className = 'blue';\r\n  \r\n  eleSet.append(startNode.splitText(range.startOffset));\r\n  startNode.after(eleSet);\r\n  \r\n  endNode.splitText(range.endOffset);\r\n  eleSet.append(endNode);\r\n}<\/pre>\n<p>\u5b9e\u64cd\u6548\u679c\u5982\u4e0bGIF\u6240\u793a\uff1a<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/image.zhangxinxu.com\/image\/blog\/202211\/Nov-29-2022-16-33-57.gif\" width=\"252\" height=\"92\" alt=\"\u9009\u533a\u989c\u8272\u53d8\u84dd\" class=\"alignnone size-medium\" \/><\/p>\n<p><strong>\u5408\u5e76<\/strong><\/p>\n<p>\u5982\u679c\u5e0c\u671b\u591a\u4e2a\u72ec\u7acb\u7684\u6587\u672c\u8282\u70b9\u5408\u5e76\u4e3a\u540c\u4e00\u4e2a\uff08\u591a\u6587\u672c\u8282\u70b9\u5f88\u591a\u65f6\u5019\u4f1a\u589e\u52a0\u6211\u4eec\u7684\u5224\u65ad\u548c\u5b9e\u73b0\u6210\u672c\uff09\uff0c\u5219\u53ef\u4ee5\u4f7f\u7528 Node.normalize() \u65b9\u6cd5\u3002<\/p>\n<p>\u6211\u4eec\u6253\u5f00Chrome\u6d4f\u89c8\u5668\u63a7\u5236\u53f0\uff0c\u5982\u679c\u53d1\u73b0HTML\u5143\u7d20\u4e2d\u7684\u6587\u5b57\u90fd\u662f\u7ad6\u7740\u6392\u5217\u7684\uff0c\u800c\u4e14\u6bcf\u884c\u6587\u5b57\u5916\u9762\u8fd8\u6709\u5f15\u53f7\uff0c\u6b64\u65f6\u5c31\u53ef\u4ee5\u4f7f\u7528 Node.normalize() \u65b9\u6cd5\u8ba9\u8fd9\u4e9b\u6587\u672c\u8282\u70b9\u5408\u4f53\u3002<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/image.zhangxinxu.com\/image\/blog\/202211\/dianjuren2.jpg\" width=\"200\" height=\"147\" alt=\"\u5408\u4f53GIF\u793a\u610f\" class=\"alignnone size-medium\" \/><\/p>\n<h4>6. \u8282\u70b9\u7684\u4e0a\u4e0b\u6c42\u7d22<\/h4>\n<ul>\n<li>\u60f3\u8981\u83b7\u53d6\u8282\u70b9\u7684\u7236\u7ea7\u8282\u70b9\uff0c\u53ef\u4ee5\u4f7f\u7528 Node.parentNode\uff1b<\/li>\n<li>\u60f3\u8981\u83b7\u53d6\u8282\u70b9\u7684\u7236\u7ea7\u5143\u7d20\uff0c\u53ef\u4ee5\u4f7f\u7528 Node.parentElement\uff1b<\/li>\n<li>\u60f3\u8981\u83b7\u53d6\u67d0\u4e2a\u7956\u5148\u5143\u7d20\uff0c\u53ef\u4ee5\u4f7f\u7528 closest(selector) \u65b9\u6cd5\uff0c\u53c2\u6570\u662f\u8be5\u5143\u7d20\u5339\u914d\u7684\u9009\u62e9\u5668\uff0c\u4f7f\u7528\u793a\u610f\uff1a\n<pre>Node.parentElement.closest('h3, ol, ul');<\/pre>\n<\/li>\n<li>\u6587\u672c\u8282\u70b9\u662f\u6ca1\u6709\u5b50\u8282\u70b9\u7684\uff0c\u56e0\u6b64 TextNode.childNodes \u7684\u957f\u5ea6\u4e00\u5b9a\u662f 0\u3002\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/image.zhangxinxu.com\/image\/blog\/202211\/length-0(1).png\" width=\"281\" height=\"87\" alt=\"\u8282\u70b9\u957f\u5ea6\u662f0\" class=\"alignnone size-medium\" \/><\/li>\n<li>\u5143\u7d20\u8282\u70b9\u7684\u6240\u6709\u5b50\u5143\u7d20\uff0c\u4f7f\u7528 element.children\uff0c\u6240\u6709\u8282\u70b9\u4f7f\u7528 element.childNodes, \u8fd4\u56de\u503c\u90fd\u662f\u7c7b\u6570\u7ec4\uff0c\u4e0d\u652f\u6301 map, some\u7b49\u6570\u7ec4\u65b9\u6cd5\uff0c\u53ef\u4ee5\u4f7f\u7528 Array.from() \u65b9\u6cd5\uff0c\u6216\u8005 [&#8230;] \u8bed\u6cd5\u8f6c\u4e3a\u6570\u7ec4\u3002<\/li>\n<li>\u67e5\u627e\u67d0\u4e2a\u5bf9\u5e94\u9009\u62e9\u5668\u7684\u5143\u7d20\uff0c\u53ef\u4ee5\u4f7f\u7528 querySelector() \u6216\u8005 querySelectorAll() \u65b9\u6cd5\uff0c\u5982\u679c\u662f\u5bfb\u627e\u5339\u914d\u67d0\u9009\u62e9\u5668\u7684\u5b50\u5143\u7d20\uff0c\u53ef\u4ee5\u8f85\u52a9 :scope \u4f2a\u7c7b\uff0c\u4f8b\u5982\uff1a\n<pre>element.querySelector(':scope > .desc')<\/pre>\n<p>\u8868\u793a\u5339\u914d\u7b2c\u4e00\u4e2a\u7c7b\u540d\u662f .desc \u7684\u5b50\u5143\u7d20\u3002<\/li>\n<li>\u5bf9\u4e8e\u7b2c\u4e00\u4e2a\u5b50\u8282\u70b9\uff0c\u53ef\u4ee5\u4f7f\u7528 element.firstChild \u83b7\u53d6\uff0c\u7b2c\u4e00\u4e2a\u5b50\u5143\u7d20\u4f7f\u7528 element.firstElementChild\uff1b\u5bf9\u4e8e\u6700\u540e\u4e00\u4e2a\u5b50\u8282\u70b9\u53ef\u4ee5\u4f7f\u7528 element.lastChild \u83b7\u53d6\uff0c\u7b2c\u4e00\u4e2a\u5b50\u5143\u7d20\u4f7f\u7528 element.lastElementChild\uff1b<\/li>\n<li>\u524d\u4e00\u4e2a\u5144\u5f1f\u8282\u70b9\u53ef\u4ee5\u4f7f\u7528 Node.previousSibling \u83b7\u53d6\uff0c\u5982\u679c\u6ca1\u6709\uff0c\u8fd4\u56de\u503c\u4f1a\u662f null\uff0c\u524d\u4e00\u4e2a\u5144\u5f1f\u5143\u7d20\u4f7f\u7528 Node.previousElementSibling \u83b7\u53d6\u3002<\/li>\n<li>\u540e\u4e00\u4e2a\u5144\u5f1f\u8282\u70b9\u53ef\u4ee5\u4f7f\u7528 Node.nextSibling \u83b7\u53d6\uff0c\u540e\u4e00\u4e2a\u5144\u5f1f\u5143\u7d20\u4f7f\u7528 Node.nextElementSibling \u83b7\u53d6\u3002<\/li>\n<\/ul>\n<h4>7. \u8282\u70b9\u7684\u5339\u914d\u5224\u65ad<\/h4>\n<p>\u8981\u5224\u65adA\u8282\u70b9\u662f\u5426\u7b49\u4e8eB\u8282\u70b9\uff0c\u7b80\u5355\u70b9\u7684\u505a\u6cd5\u76f4\u63a5 == \u5224\u65ad\u3002<\/p>\n<pre>nodeA == nodeB<\/pre>\n<p>\u4e5f\u53ef\u4ee5\u4f7f\u7528 Node.isSameNode() \u65b9\u6cd5\u8fdb\u884c\u5224\u65ad\uff1a<\/p>\n<pre>const isSame = nodeA.isSameNode(nodeB)<\/pre>\n<p>\u5982\u679c\u5e0c\u671b\u5224\u65ad\u4e24\u4e2a\u8282\u70b9\u662f\u5426\u4e00\u81f4\uff0c\u6240\u8c13\u4e00\u81f4\u5c31\u662f\u6807\u7b7e\u4e00\u6837\uff0c\u5c5e\u6027\u4e00\u6837\uff0c\u5185\u5bb9\u4e00\u6837\uff0c\u53ef\u4ee5\u4f7f\u7528 Node.isEqualNode \u65b9\u6cd5\u3002<\/p>\n<p>\u4f8b\u5982\u4e0b\u9762\u7684\u8fd4\u56de\u503c\u5c31\u662f true\uff0c\u867d\u7136 nodeA \u548c nodeB \u662f\u4e24\u4e2a\u4e0d\u540c\u7684\u6587\u672c\u8282\u70b9\u3002<\/p>\n<pre>nodeA = new Text('zhangxinxu');\r\nnodeB = document.createTextNode('zhangxinxu');\r\n\/\/ \u6253\u5370\u5185\u5bb9\u662f true\r\nconsole.log(nodeA.isEqualNode(nodeB));<\/pre>\n<p>\u5982\u679c\u8282\u70b9\u662f\u5143\u7d20\uff0c\u4e14\u5224\u65ad\u5176\u662f\u5426\u5339\u914d\u67d0\u79cd\u7279\u6027\uff0c\u53ef\u4ee5\u4f7f\u7528 matches \u65b9\u6cd5\u8fdb\u884c\u5224\u65ad\u3002<\/p>\n<p>\u4f8b\u5982\uff1a<\/p>\n<pre>\/\/ \u662f\u5426\u662f li \u6807\u7b7e\u5143\u7d20\r\nelement.matches('li')\r\n\/\/ \u662f\u5426\u5305\u542b\u5c5e\u6027 data-id\r\nelement.matches('[data-id]')<\/pre>\n<p>\u5982\u679c\u5e0c\u671b\u5224\u65ad\u4e00\u4e2a Node \u8282\u70b9\u662f\u5426\u5728\u6587\u6863\u4e2d\uff0c\u800c\u4e0d\u662f\u5728\u5185\u5b58\u4e2d\uff08\u6267\u884c Node.remove() \u5220\u9664\uff0c\u6216\u8005 replaceWidth() \u66ff\u6362\u540e\uff09\uff0c\u53ef\u4ee5\u4f7f\u7528 Node.isConnected \u5224\u65ad\u3002<\/p>\n<p>\u8fd4\u56de true \u5219\u8868\u793a\u5728DOM\u6811\u4e2d\uff0c\u5728\u6587\u6863\u6d41\u4e2d\u3002<\/p>\n<h4>8. \u8282\u70b9\u7684\u7c7b\u578b\u5224\u65ad<\/h4>\n<p>\u5b9e\u9645\u5f00\u53d1\u4e4b\u4e2d\uff0c\u7ecf\u5e38\u9700\u8981\u5224\u65ad\u5f53\u524d\u8282\u70b9\u662f\u6587\u672c\u7c7b\u578b\uff0c\u8fd8\u662f\u5143\u7d20\u7c7b\u578b\u3002<\/p>\n<p>\u6b64\u65f6\uff0c\u6211\u90fd\u662f\u4f7f\u7528 nodeType \u5c5e\u6027\u8fdb\u884c\u5224\u65ad\u7684\u3002<\/p>\n<ul>\n<li>\u5982\u679c node.nodeType == 1\uff0c\u5219\u5f53\u524d\u8282\u70b9\u662f\u5143\u7d20\uff1b<\/li>\n<li>\u5982\u679c node.nodeType == 3\uff0c\u5219\u5f53\u524d\u8282\u70b9\u662f\u6587\u672c\uff1b<\/li>\n<\/ul>\n<p>nodeType\u5c5e\u6027\u503c\u8fd8\u6709\u5176\u4ed6\u7c7b\u578b\uff0c\u4f8b\u5982\u8bc4\u8bba\u3001\u6587\u6863\u7c7b\u578b\u7b49\uff0c\u4e0d\u8fc7\u5e73\u5e38\u7528\u7684\u4e0d\u591a\uff0c\u53ea\u9700\u8981\u8bb0\u4f4f1\u548c3\u8fd9\u4e24\u4e2a\u503c\u5c31\u53ef\u4ee5\u4e86\u3002<\/p>\n<p>\u5982\u679c1\u548c3\u603b\u662f\u8bb0\u4e0d\u4f4f\uff0c\u4e5f\u53ef\u4ee5\u4f7f\u7528Node\u5e38\u91cf\u8868\u793a\u3002<\/p>\n<p>\u5176\u4e2d\uff0cNode.ELEMENT_NODE\u8868\u793a\u5143\u7d20\u8282\u70b9\uff0cNode.TEXT_NODE\u8868\u793a\u6587\u672c\u8282\u70b9\u3002<\/p>\n<pre>\/\/ \u662f\u6587\u672c\u8282\u70b9\r\nif (node.nodeType == Node.TEXT_NODE) {}<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/image.zhangxinxu.com\/image\/blog\/202211\/pawa.jpg\" width=\"140\" height=\"136\" alt=\"\u5e15\u74e6\" class=\"alignleft size-medium\" \/> \u5728\u6709\u4e9b\u573a\u666f\u4e0b\uff0c\u6211\u4e5f\u4f1a\u4f7f\u7528 nodeName \u8fdb\u884c\u5224\u65ad\uff0c\u5c31\u662f\u5f53\u6211\u5e0c\u671b\u77e5\u9053\u67d0\u4e2a\u8282\u70b9\u662f\u4e0d\u662f\u6211\u8ba4\u4e3a\u7684\u5143\u7d20\u7684\u65f6\u5019\u3002<\/p>\n<p>\u4f8b\u5982\uff0c\u5728\u5bcc\u6587\u672c\u7f16\u8f91\u5668\u4e2d\uff0c\u6bb5\u843d\u5185\u5bb9\u7684\u6700\u540e\u4e00\u4e2a\u8282\u70b9\u5f88\u53ef\u80fd\u662f <code>&lt;br&gt;<\/code> \u5143\u7d20\uff0c\u5982\u679c\u662f\u8fd9\u4e2a\u5143\u7d20\uff0c\u7c7b\u4f3c\u4e8e\u6587\u672c\u63d2\u5165\u8fd9\u6837\u7684\u64cd\u4f5c\u5c31\u4e0d\u5408\u9002\uff08br\u6807\u7b7e\u5185\u7684\u4efb\u610f\u5185\u5bb9\u90fd\u4e0d\u663e\u793a\uff09\uff0c\u9700\u8981\u7279\u6b8a\u5904\u7406\uff0c\u6b64\u65f6\uff0c\u4f7f\u7528 nodeName \u5224\u65ad\u6700\u5408\u9002\uff1a<\/p>\n<pre>if (node.nodeName == 'BR') {\r\n  \/\/ \u7279\u6b8a\u5904\u7406\r\n}<\/pre>\n<p>\u548c tagName \u5c5e\u6027\u7684\u533a\u522b\u5728\u4e8e\uff0ctagName \u53ea\u6709\u5143\u7d20\u8282\u70b9\u624d\u6709\uff0c\u6587\u672c\u8282\u70b9\u8c03\u7528 tagName \u5c5e\u6027\u8fd4\u56de\u7684\u662f undefined\uff0c\u800c\u8c03\u7528 nodeName \u8fd4\u56de\u7684\u5c31\u662f &#8216;#text&#8217;\u3002<\/p>\n<h4>9. \u8282\u70b9\u7684\u4f4d\u7f6e\u6bd4\u8f83<\/h4>\n<p>\u8fd9\u4e2a\u6211\u4e5f\u7528\u5230\u4e86\uff0c\u4f7f\u7528\u7684\u662f compareDocumentPosition \u8fd9\u4e2a API\uff0c\u4e4b\u524d\u6709\u6df1\u5165\u4ecb\u7ecd\u8fc7\uff0c\u53c2\u89c1\u201c<a href=\"https:\/\/www.zhangxinxu.com\/wordpress\/2019\/03\/node-comparedocumentposition-api\/\">\u6df1\u5165Node.compareDocumentPosition API<\/a>\u201d\u4e00\u6587\uff0c\u8fd9\u91cc\u4e0d\u518d\u8d58\u8ff0\u3002<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/image.zhangxinxu.com\/image\/blog\/202211\/20221129-185059(1).png\" width=\"701\" height=\"200\" alt=\"\u9879\u76ee\u4ee3\u7801\u4e2d\u4f7f\u7528\u793a\u610f\" class=\"alignnone size-medium\" \/><\/p>\n<h3>\u4e8c\u3001\u5e38\u89c1\u6848\u4f8b<\/h3>\n<p>\u867d\u7136\u8282\u70b9\u76f8\u5173\u7684\u5c5e\u6027\u548c\u65b9\u6cd5\u5f88\u591a\uff0c\u4f46\u4f9d\u7136\u65e0\u6cd5\u6ee1\u8db3\u6240\u6709\u7684\u573a\u666f\u9700\u6c42\uff0c\u9700\u8981\u914d\u5408\u8bed\u8a00\u5c42\u9762\u7684\u8bed\u6cd5\u5b9e\u73b0\u3002<\/p>\n<p>\u8fd9\u91cc\u5c55\u793a\u82e5\u5e72\u4e2a\u6211\u9879\u76ee\u4e2d\u7528\u5230\u7684\u5904\u7406\u573a\u666f\uff0c\u5982\u679c\u4f60\u4e5f\u6709\u7c7b\u4f3c\u9700\u6c42\uff0c\u76f4\u63a5\u590d\u5236\u4ee3\u7801\u5373\u53ef\uff0c\u522b\u5ba2\u6c14\u3002<\/p>\n<p>\u4e0b\u9762\u6240\u6709\u6848\u4f8b\u6548\u679c\uff0c\u60a8\u5747\u53ef\u4ee5\u72e0\u72e0\u5730\u70b9\u51fb\u8fd9\u91cc\u4f53\u9a8c\uff1a<a href=\"https:\/\/www.zhangxinxu.com\/study\/202211\/js-text-node-run.html\" rel=\"noopener\" target=\"_textnode\">\u6587\u672c\u8282\u70b9\u4ea4\u4e92\u5904\u7406\u5408\u96c6demo <\/a><\/p>\n<h4>1. \u6700\u7956\u5148\u7684\u5339\u914d\u5143\u7d20<\/h4>\n<p><code>Element.closest()<\/code> \u65b9\u6cd5\u867d\u7136\u4e5f\u53ef\u4ee5\u5411\u4e0a\u5339\u914d\uff0c\u4f46\u662f\u5339\u914d\u7684\u662f\u6700\u8fd1\u7684\u7956\u5148\u5143\u7d20\uff0c\u5982\u679c\u6211\u60f3\u5339\u914d\u6700\u8fdc\u7684\u7956\u5148\u5143\u7d20\u5462\uff1f<\/p>\n<p>\u90a3\u5c31\u5f97\u9012\u5f52\u5bfb\u627e\u4e86\u3002<\/p>\n<pre>Element.prototype.farthest = function (selector) {\r\n  if (typeof selector != 'string') {\r\n    return null;\r\n  }\r\n  \r\n  let eleMatch = this.closest(selector);\r\n  let eleReturn = null;\r\n  while (eleMatch) {\r\n    eleReturn = eleMatch;\r\n    eleMatch = eleMatch.parentElement.closest(selector);\r\n  }\r\n  \r\n  return eleReturn;\r\n};<\/pre>\n<p>\u4f7f\u7528\u793a\u610f\uff0c\u5df2\u77e5 HTML \u5982\u4e0b\uff1a<\/p>\n<pre>&lt;div id=\"a\"&gt;\r\n  &lt;div id=\"b\"&gt;\r\n    &lt;button id=\"button\"&gt;\u70b9\u51fb\u6211&lt;\/button&gt;\r\n  &lt;\/div&gt;\r\n&lt;\/div&gt;<\/pre>\n<p>\u5219 <code>button.farthest('div').id<\/code> \u7684\u8fd4\u56de\u662f\u5c31\u662f &#8216;a&#8217;\uff0c\u662f\u6700\u5916\u5c42\u90a3\u4e2a DIV \u5143\u7d20\u7684 id \u5c5e\u6027\u503c\u3002<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/image.zhangxinxu.com\/image\/blog\/202211\/20221129-191005-min.png\" width=\"258\" height=\"86\" alt=\"\u8f93\u51fa\u7ed3\u679c\u662f'a'\" class=\"alignnone size-medium\" \/><\/p>\n<h4>2. \u6700\u6df1\u7684\u9996\uff08\u5c3e\uff09\u8282\u70b9\uff08\u5143\u7d20\uff09<\/h4>\n<p>\u6211\u4eec\u6709\u65f6\u5019\u9700\u8981\u77e5\u9053\u67d0\u4e2a\u5143\u7d20\u6700\u6df1\u7684\u5c3e\u8282\u70b9\uff0c\u6216\u8005\u5c3e\u5143\u7d20\uff0c\u6bd4\u65b9\u8bf4\u60f3\u8981\u77e5\u9053\u628a\u5149\u6807\u805a\u7126\u7684\u4f4d\u7f6e\u662f\u4e0d\u662f\u6700\u540e\u4e00\u4e2a\u5b50\u5143\u7d20\u7684\u65f6\u5019\u3002<\/p>\n<p>\u4ee5\u4e0b\u5c31\u662f\u4ee3\u7801\u5b9e\u73b0\u793a\u610f\uff0c\u5bf9\u4e8e\u6587\u672c\u8282\u70b9\uff0c\u7279\u610f\u8fc7\u6ee4\u4e86\u7a7a\u767d\u8282\u70b9\uff0c\u5982\u679c\u4f60\u5e0c\u671b\u7a7a\u767d\u6587\u672c\u8282\u70b9\u4e5f\u88ab\u91c7\u7eb3\uff0c\u8fc7\u6ee4\u5bf9\u5e94\u7684 if \u5904\u7406\u8bed\u53e5\u5373\u53ef\uff01<\/p>\n<p>\u8282\u70b9\u83b7\u53d6\u7684JS\u4ee3\u7801\uff1a<\/p>\n<pre>Object.defineProperties(Node.prototype, {\r\n  \/\/ \u83b7\u53d6\u6700\u6df1\u7684\u7b2c\u4e00\u4e2a\u8282\u70b9\r\n  \/\/ \u8fc7\u6ee4\u7a7a\u767d\u8282\u70b9\r\n  firstNode: {\r\n    get: function () {\r\n      if (!this.childNodes.length) {\r\n        return null;\r\n      }\r\n\r\n      let nodeReturn = null;\r\n      const step = function (node) {\r\n        let nodeMatch = node.firstChild;\r\n        \/\/ \u7a7a\u767d\u8282\u70b9\u4e0d\u5904\u7406\r\n        if (nodeMatch &amp;&amp; nodeMatch.nodeType == 3 &amp;&amp; nodeMatch.nodeValue.trimStart() == '') {\r\n          nodeMatch = nodeMatch.nextSibling;\r\n        }\r\n        if (nodeMatch) {\r\n          nodeReturn = nodeMatch;\r\n          step(nodeMatch);\r\n        }\r\n      }\r\n\r\n      step(this);\r\n      \r\n      return nodeReturn;\r\n    }\r\n  },\r\n  lastNode: {\r\n    get: function () {\r\n      if (!this.childNodes.length) {\r\n        return null;\r\n      }\r\n\r\n      let nodeReturn = null;\r\n      const step = function (node) {\r\n        let nodeMatch = node.lastChild;\r\n        \/\/ \u7a7a\u767d\u8282\u70b9\u4e0d\u5904\u7406\r\n        if (nodeMatch &amp;&amp; nodeMatch.nodeType == 3 &amp;&amp; nodeMatch.nodeValue.trimEnd() == '') {\r\n          nodeMatch = nodeMatch.previousSibling;\r\n        }\r\n        if (nodeMatch) {\r\n          nodeReturn = nodeMatch;\r\n          step(nodeMatch);\r\n        }\r\n      }\r\n\r\n      step(this);\r\n      \r\n      return nodeReturn;\r\n    }\r\n  }\r\n});<\/pre>\n<p>\u5143\u7d20\u83b7\u53d6\u7684JS\u4ee3\u7801\uff1a<\/p>\n<pre>Object.defineProperties(Element.prototype, {\r\n  \/\/ \u83b7\u53d6\u6700\u6df1\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\r\n  firstElement: {\r\n    get: function () {\r\n      if (!this.children.length) {\r\n        return null;\r\n      }\r\n\r\n      let eleMatch = this.firstElementChild;\r\n      let eleReturn = null;\r\n\r\n      while (eleMatch) {\r\n        eleReturn = eleMatch;\r\n        eleMatch = eleMatch.firstElementChild;\r\n      }\r\n      \r\n      return eleReturn;\r\n    }\r\n  },\r\n  lastElement: {\r\n    \/\/ \u83b7\u53d6\u6700\u6df1\u7684\u6700\u540e\u4e00\u4e2a\u5143\u7d20\r\n    get: function () {\r\n      if (!this.children.length) {\r\n        return null;\r\n      }\r\n\r\n      let eleMatch = this.lastElementChild;\r\n      let eleReturn = null;\r\n\r\n      while (eleMatch) {\r\n        eleReturn = eleMatch;\r\n        eleMatch = eleMatch.lastElementChild;\r\n      }\r\n      \r\n      return eleReturn;\r\n    }\r\n  }\r\n});<\/pre>\n<p><strong>\u8bed\u6cd5\uff1a<\/strong><\/p>\n<pre>element.firstNode;\r\nelement.lastNode;\r\nelement.firstElement;\r\nelement.lastElement;<\/pre>\n<p>\u5982\u679c\u6ca1\u6709\u5bf9\u5e94\u7684\u8282\u70b9\u5143\u7d20\uff0c\u8fd4\u56de\u7684\u662f null\u3002<\/p>\n<h4>3. \u83b7\u53d6\u6240\u6709\u6587\u672c\u8282\u70b9<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/image.zhangxinxu.com\/image\/blog\/202211\/maqima.jpg\" width=\"145\" height=\"80\" alt=\"\u739b\u5947\u739b\" class=\"alignleft size-medium\" \/> \u6709\u65f6\u5019\u6211\u4eec\u5e0c\u671b\u6307\u5b9a\u5143\u7d20\u5185\u7684\u6240\u6709\u6587\u672c\u8282\u70b9\uff0c\u65b9\u6cd5\u5f88\u591a\uff0c\u6211\u4e2a\u4eba\u89c9\u5f97\u6bd4\u8f83\u597d\u7684\u5b9e\u73b0\u662f\u4f7f\u7528\u8282\u70b9\u8fed\u4ee3\u5668 createNodeIterator() \u65b9\u6cd5\u3002<\/p>\n<p>\u5b9e\u73b0\u4ee3\u7801\uff1a<\/p>\n<pre>\/\/ \u83b7\u53d6\u6240\u6709\u7684\u6587\u672c\u8282\u70b9\r\nObject.defineProperty(Element.prototype, 'childTextNodes', {\r\n  get: function () {\r\n    \/\/ \u83b7\u53d6\u6240\u6709\u7684\u6587\u672c\u8282\u70b9\r\n    const nodeIterator = document.createNodeIterator(this, NodeFilter.SHOW_TEXT, (node) =&gt; {\r\n      return node.textContent.trim() ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;\r\n    });\r\n\r\n    \/\/ \u8282\u70b9\u8fed\u4ee3\u5668\u8f6c\u4e3a\u6570\u7ec4\u5e76\u8fd4\u56de\r\n    const arrNodes = [];\r\n    let node = nodeIterator.nextNode();\r\n    while (node) {\r\n      arrNodes.push(node);\r\n      node = nodeIterator.nextNode();\r\n    }\r\n\r\n    return arrNodes;\r\n  }\r\n});<\/pre>\n<p><strong>\u8bed\u6cd5\uff1a<\/strong><\/p>\n<pre>const arrTextNode = element.childTextNodes;<\/pre>\n<p>\u5f53\u524dDOM\u5143\u7d20\u8c03\u7528\u5c5e\u6027 childTextNodes\uff0c\u4f1a\u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u6240\u6709\u6587\u672c\u8282\u70b9\u7684\u6570\u7ec4\uff0c\u5982\u679c\u6ca1\u6709\u5339\u914d\u7684\u9879\u76ee\uff0c\u8fd4\u56de\u7684\u662f\u7a7a\u6570\u7ec4\u3002<\/p>\n<h4>4. \u83b7\u53d6\u9009\u533a\u5185\u6240\u6709\u8282\u70b9<\/h4>\n<p>\u7528\u6237\u5728\u9875\u9762\u4e0a\u8de8\u9009\u4e86\u4e00\u6bb5\u6587\u5b57\uff0c\u5e0c\u671b\u77e5\u9053\u8fd9\u90e8\u5206\u9009\u533a\u90fd\u5305\u542b\u4e86\u54ea\u4e9b\u8282\u70b9\u5143\u7d20\uff0c\u53ef\u4ee5\u8bd5\u8bd5\u4e0b\u9762\u7684\u4ee3\u7801\uff1a<\/p>\n<pre>const getNodesInRange = function (range) {\r\n  var start = range.startContainer;\r\n  var end = range.endContainer;\r\n  var commonAncestor = range.commonAncestorContainer;\r\n  var nodes = [];\r\n  var node;\r\n  \/\/ \u4f7f\u7528\u516c\u7528\u7684\u7956\u5148\u8fdb\u884c\u8282\u70b9\u904d\u5386\r\n  for (node = start.parentNode; node; node = node.parentNode) {\r\n    nodes.push(node);\r\n    if (node == commonAncestor) {\r\n      break;\r\n    }\r\n  }\r\n  nodes.reverse();\r\n\r\n  const getNextNode = function (node) {\r\n    if (node.firstChild) {\r\n      return node.firstChild;\r\n    }\r\n    while (node) {\r\n      if (node.nextSibling) {\r\n        return node.nextSibling;\r\n      }\r\n      node = node.parentNode;\r\n    }\r\n  }\r\n\r\n  \/\/ \u904d\u5386\u5b50\u5143\u7d20\u548c\u5144\u5f1f\u5143\u7d20\r\n  for (node = start; node; node = getNextNode(node)) {\r\n    nodes.push(node);\r\n    if (node == end) {\r\n      break;\r\n    }\r\n  }\r\n  return nodes;\r\n}<\/pre>\n<p>\u5982\u679c\u5e0c\u671b\u53ea\u8fd4\u56de\u6587\u672c\u8282\u70b9\uff0c\u53ef\u4ee5\u518d\u8fc7\u6ee4\u4e0b\uff0cJavaScript \u4ee3\u7801\u793a\u610f\uff1a<\/p>\n<pre>\/\/ \u83b7\u53d6\u9009\u533a\u5185\u7684\u6240\u6709\u6587\u672c\u8282\u70b9\r\nconst getTextNodesInRange = function (range) {\r\n  return getNodesInRange(range).filter(node =&gt; node.nodeType == 3 &amp;&amp; node.textContent.trim());\r\n};<\/pre>\n<p>\u5176\u4e2d\uff0c\u53c2\u6570 range \u5c31\u662f\u5f53\u524d\u9875\u9762\uff08\u83b7\u53d6\u65b9\u6cd5\u89c1\u4e0b\u9762\u4ee3\u7801\u793a\u610f\uff09\uff0c\u6216\u8005\u81ea\u5df1\u521b\u5efa\uff08\u4f7f\u7528 <code>document.createRange()<\/code> \u65b9\u6cd5\uff09\u7684\u9009\u533a\u3002<\/p>\n<pre>\/\/ \u8fd4\u56de\u5f53\u524d\u9875\u9762 range \u5e38\u7528\u65b9\u6cd5\r\nconst range = document.getSelection().getRangeAt(0);<\/pre>\n<p>\u4e0b\u9762\u662f<a href=\"https:\/\/www.zhangxinxu.com\/study\/202211\/js-text-node-run.html\" rel=\"noopener\" target=\"_textnode\">demo\u9875\u9762<\/a>\u7684\u4f7f\u7528\u793a\u610f\u4ee3\u7801\uff0c\u5f53\u70b9\u51fb\u62ac\u8d77\u7684\u65f6\u5019\uff0c\u4f1a\u8f93\u51fa\u5f53\u524d\u9009\u533a\u6240\u5305\u542b\u7684\u6240\u6709\u6587\u672c\u8282\u70b9\u5185\u5bb9\uff1a<\/p>\n<pre>\/\/ \u9009\u533a\u5185\u6587\u672c\u8282\u70b9\u663e\u793a\r\ndocument.addEventListener('mouseup', function () {\r\n  const selection = document.getSelection();\r\n  output.innerHTML = getTextNodesInRange(selection.getRangeAt(0))\r\n    .map(node =&gt; node.textContent)\r\n    .join('');\r\n});<\/pre>\n<h4>5. \u5143\u7d20TAG\u6807\u7b7e\u53d8\u5316<\/h4>\n<p>\u4e3e\u4e2a\u4f8b\u5b50\uff0c\u6709\u6bb5\u6587\u5b57\u662f\u4f7f\u7528 <code>&lt;b&gt;<\/code> \u5143\u7d20\u52a0\u7c97\u7684\uff0c\u73b0\u5728\u5e0c\u671b\u7edf\u4e00\u4e3a <code>&lt;strong&gt;<\/code> \u5143\u7d20\uff0c\u8bf7\u95ee\u8be5\u600e\u4e48\u5904\u7406\uff1f<\/p>\n<pre>&lt;!-- \u8bf7\u628a b \u6362\u6210 strong \u4f46\u4e0d\u5f71\u54cd\u91cc\u9762\u7684\u8282\u70b9 --&gt;\r\n&lt;b&gt;\u9493\u9c7c\u53ef\u5426\uff1f&lt;a href=\"https:\/\/item.jd.com\/13356308.html\"&gt;\u300aCSS\u65b0\u4e16\u754c\u300b&lt;\/a&gt;&lt;\/b&gt;<\/pre>\n<p>\u6b64\u65f6\u5c31\u9700\u8981 replaceWidth \u548c append \u65b9\u6cd5\u51fa\u9a6c\u4e86\uff0c\u4e0b\u9762\u662f\u6211\u7684\u5b9e\u73b0\uff0c\u8ba9\u5143\u7d20\u7684 tagName \u5c5e\u6027\u53d8\u5f97\u53ef\u5199\u3002<\/p>\n<pre>\/\/ \u6539\u53d8\u5143\u7d20\u7684\u6807\u7b7e\u65b9\u6cd5\r\nconst propsTagName= Object.getOwnPropertyDescriptor(Element.prototype, 'tagName');\r\nObject.defineProperty(Element.prototype, 'tagName', {\r\n  ...propsTagName,\r\n  set: function (name) {\r\n    if (typeof name != 'string' || name.toUpperCase() == this.tagName) {\r\n      return;\r\n    }\r\n\r\n    const eleNew = document.createElement(name.toLowerCase());\r\n    eleNew.append.apply(eleNew, [...this.childNodes]);\r\n\r\n    this.replaceWith(eleNew);\r\n\r\n    return name;\r\n  }\r\n});<\/pre>\n<p>\u6b64\u65f6\uff0c\u4efb\u610f\u5143\u7d20\u6267\u884c\u4e0b\u9762\u7684\u8bed\u6cd5\uff0c\u5c31\u53ef\u4ee5\u6539\u53d8\u81ea\u8eab\u7684\u6807\u7b7e\u4e86\u3002<\/p>\n<pre>element.tagName = 'newTagName'<\/pre>\n<p>\u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u5f53\u6b64\u8bed\u53e5\u6267\u884c\u540e\uff0celement\u5bf9\u8c61\u5c31\u4e0d\u5728\u6587\u6863\u4e2d\u4e86\uff0c\u800c\u662f\u5728\u5185\u5b58\u4e2d\uff0c\u5982\u679c\u4f60\u7ee7\u7eed\u505a\u4e00\u4e9bDOM\u5904\u7406\uff08\u5982\u83b7\u53d6\u7236\u5143\u7d20\uff09\uff0c\u7ed3\u679c\u4f1a\u662f null\u3002<\/p>\n<p>\u4e0b\u56fe\u662f<a href=\"https:\/\/www.zhangxinxu.com\/study\/202211\/js-text-node-run.html\" rel=\"noopener\" target=\"_textnode\">demo\u9875\u9762<\/a>\u4ea4\u4e92\u64cd\u4f5c\u540e\u7684GIF\u5f55\u5c4f\u793a\u610f\uff0c\u53ef\u4ee5\u770b\u5230\u5143\u7d20\u7684\u6807\u7b7e\u4eceb\u8f6c\u4e3astrong\u4e86\uff1a<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/image.zhangxinxu.com\/image\/blog\/202211\/b2strong-s.gif\" width=\"583\" height=\"293\" alt=\"\u6807\u7b7e\u8f6c\u6362\u52a8\u56fe\" class=\"alignnone size-medium\" style=\"border:1px solid #ddd;\" \/><\/p>\n<h4>6. \u90e8\u5206\u6587\u5b57\u53d8\u6210 HTML \u5143\u7d20<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/image.zhangxinxu.com\/image\/blog\/202211\/maqima2.jpg\" width=\"112\" height=\"114\" alt=\"\u739b\u5947\u739b2\" class=\"alignleft size-medium\" \/> \u6709\u65f6\u5019\uff0c\u6211\u4eec\u5e0c\u671b\u4e00\u6bb5\u6587\u5b57\u4e2d\u7684\u67d0\u51e0\u4e2a\u5b57\u53d8\u6210 HTML \u5143\u7d20\uff0c\u6709\u4e00\u79cd\u7b80\u5355\u7684\u65b9\u6cd5\u5c31\u662f innerHTML \u76f4\u63a5\u6b63\u5219\u66ff\u6362\u3002<\/p>\n<p>\u4f46\uff0c\u5982\u679c\u8fd9\u6bb5\u6587\u5b57\u4e2d\u7684\u67d0\u4e2a HTML \u5143\u7d20\u7ed1\u5b9a\u4e86\u4e8b\u4ef6\uff0c\u6216\u8005\u5149\u6807\u6b63\u5728\u5728\u8fd9\u6bb5\u6587\u5b57\u4e2d\uff0c\u8fd9\u4e48\u5904\u7406\u5c31\u4f1a\u4e22\u5931\u4e8b\u4ef6\uff0c\u6216\u8005\u4e22\u5931\u5149\u6807\u3002<\/p>\n<p>\u6709\u4e00\u79cd\u4f4e\u4fb5\u5165\u7684\u5b9e\u73b0\u65b9\u6cd5\uff0c\u5c31\u662f\u501f\u52a9 Range \u9009\u533a\u5bf9\u8c61\u7684 <code>surroundContents<\/code> \u65b9\u6cd5\u3002<\/p>\n<p>\u4ee3\u7801\u793a\u610f\uff1a<\/p>\n<pre>\/\/ \u90e8\u5206\u6587\u5b57\u4f7f\u7528 HTML \u5305\u88c5\r\n\/\/ selector \u8868\u793a\u5e0c\u671b\u5305\u88f9\u7684HTML\u5143\u7d20\u9009\u62e9\u5668\r\n\/\/ \u4ec5\u652f\u6301\u6807\u7b7e\u548c\u7c7b\u540d\u9009\u62e9\u5668\r\n\/\/ text \u8868\u793a\u5e0c\u671b\u5305\u88f9\u7684\u5b57\u7b26\uff0c\u4e0d\u8bbe\u7f6e\u8868\u793a\u6574\u4e2a\u6587\u672c\u8282\u70b9\r\nText.prototype.surround = function (selector, text) {\r\n  const textContent = this.nodeValue;\r\n  if (!textContent || !selector) {\r\n    return null;\r\n  }\r\n\r\n  text = text || textContent;\r\n\r\n  \/\/ \u5305\u88c5\u7684\u5143\u7d20\u6807\u7b7e\u548c\u7c7b\u540d\r\n  const arrClass = selector.split('.');\r\n  const tagName = arrClass[0] || 'span';\r\n  const className = arrClass.slice(1).join(' ');\r\n\r\n  \/\/ \u7d22\u5f15\u8303\u56f4\r\n  const startIndex = textContent.indexOf(text);\r\n\r\n  if (startIndex == -1) {\r\n    return null;\r\n  }\r\n\r\n  const range = document.createRange();\r\n  range.setStart(this, startIndex);\r\n  range.setEnd(this, startIndex + text.length);\r\n\r\n  \/\/ \u5143\u7d20\u521b\u5efa\r\n  const eleSurround = document.createElement(tagName);\r\n  if (className) {\r\n    eleSurround.className = className;\r\n  }\r\n\r\n  \/\/ \u6267\u884c\u6700\u540e\u4e00\u51fb\r\n  range.surroundContents(eleSurround);\r\n\r\n  return eleSurround;\r\n};<\/pre>\n<p>\u5047\u8bbe\u6709 HTML \u4ee3\u7801\u5982\u4e0b\uff1a<\/p>\n<pre>&lt;p id=\"wrap\"&gt;\u4fdd\u4f51\u4eca\u5929\u9493\u9c7c\u7206\u62a4\uff01&lt;\/p&gt;<\/pre>\n<p>\u6211\u4eec\u5e0c\u671b\u201c\u9493\u9c7c\u201d\u4e24\u4e2a\u5b57\u52a0\u7c97\uff0c\u5219\u4e00\u53e5\u8bdd\u7684\u4e8b\u60c5\uff1a<\/p>\n<pre>wrap.firstChild.surround('strong', '\u9493\u9c7c');<\/pre>\n<p>\u6b64\u65f6\u8be5\u5143\u7d20\u7684 outerHTML \u5b57\u7b26\u5185\u5bb9\u4e3a\uff1a<\/p>\n<pre>&lt;p id=\"wrap\"&gt;\u4fdd\u4f51\u4eca\u5929&lt;strong&gt;\u9493\u9c7c&lt;\/strong&gt;\u7206\u62a4\uff01&lt;\/p&gt;<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/image.zhangxinxu.com\/image\/blog\/202211\/2022-11-30_181441.png\" width=\"253\" height=\"115\" alt=\"\u9493\u9c7cstrong\u5143\u7d20\" class=\"alignnone size-medium\" \/><\/p>\n<h4>7. \u76f8\u540c\u72b6\u6001\u5143\u7d20\u7684\u5408\u5e76<\/h4>\n<p>\u6709\u65f6\u5019\u4e3a\u4e86\u8ba9\u6211\u4eec\u7684 HTML \u4ee3\u7801\u66f4\u52a0\u5e72\u51c0\uff0c\u9700\u8981\u5bf9\u6807\u7b7e\u8fdb\u884c\u5408\u5e76\uff0c\u4ee5\u65b9\u4fbf\u540e\u7eed\u7684\u5904\u7406\u3002<\/p>\n<p>\u4f8b\u5982\u4e0b\u9762\u7684HTML\u6709\u4e24\u4e2a\u8fde\u7eed\u7684 <code>&lt;strong&gt;<\/code> \u5143\u7d20\uff0c\u5176\u5b9e\u53ef\u4ee5\u5408\u4e8c\u4e3a\u4e00\u3002<\/p>\n<pre>\u4fdd\u4f51\u4eca\u5929&lt;strong&gt;\u9493\u9c7c&lt;\/strong&gt;&lt;strong&gt;\u7206\u62a4&lt;\/strong&gt;\uff01<\/pre>\n<p>\u53c8\u6bd4\u5982\u5728\u7f16\u8f91\u5668\u4e2d\u7684\u8fde\u7eed\u4e24\u4e2a ol \u6709\u5e8f\u5217\u8868\uff0c\u5176\u5b9e\u5e94\u8be5\u5408\u5e76\u4e3a\u4e00\u4e2a\u3002<\/p>\n<p>\u4e0b\u9762\u5c31\u662f\u81ea\u5df1\u7684\u5b9e\u73b0\u4ee3\u7801\uff1a<\/p>\n<pre>\/\/ \u5408\u5e76\u7b49\u540c\u5143\u7d20\r\nElement.prototype.merge = function (selector) {\r\n  if (!selector) {\r\n    return;\r\n  }\r\n\r\n  [...this.querySelectorAll(selector)].some(ele =&gt; {\r\n    \/\/ \u5982\u679c\u548c\u524d\u9762\u7684\u8282\u70b9\u7c7b\u578b\u4e00\u81f4\uff0c\u5408\u5e76\r\n    let nodePrev = ele.previousSibling;\r\n    let elePrev = ele.previousElementSibling;\r\n\r\n    if (!nodePrev || !elePrev) {\r\n      return false;\r\n    }\r\n\r\n    \/\/ \u975e\u5185\u8054\u5143\u7d20\u6362\u884c\u7b26\u5ffd\u7565\r\n    const display = getComputedStyle(ele).display;\r\n    if (nodePrev.nodeType == 3 &amp;&amp; (nodePrev.nodeValue === '' || (!\/inline\/.test(display) &amp;&amp; !nodePrev.nodeValue.trim()))) {\r\n      nodePrev.remove();\r\n      \/\/ \u9012\u5f52\u5904\u7406\r\n      this.merge(selector);\r\n\r\n      return true;\r\n    }\r\n\r\n    \/\/ \u5982\u679c\u524d\u9762\u7684\u8282\u70b9\u4e5f\u662f\u5143\u7d20\uff0c\u540c\u65f6\u7c7b\u540d\u4e00\u81f4\r\n    if (nodePrev &amp;&amp; nodePrev == elePrev &amp;&amp; ele.cloneNode().isEqualNode(nodePrev.cloneNode())) {\r\n      elePrev.append.apply(elePrev, [...ele.childNodes]);\r\n      ele.remove();\r\n      \/\/ \u9012\u5f52\u5904\u7406\r\n      this.merge(selector);\r\n\r\n      return true;\r\n    }\r\n  });\r\n};<\/pre>\n<p>\u8bed\u6cd5\u5982\u4e0b\uff1a<\/p>\n<pre>element.merge(selector);<\/pre>\n<p>\u6b64\u65f6\uff0celement\u5143\u7d20\u4e2d\u5339\u914d\u9009\u62e9\u5668 selector \u7684\u76f8\u90bb\u4e24\u4e2a\u7c7b\u4f3c\uff08\u6807\u7b7e\u548c\u5c5e\u6027\u4e00\u6837\uff09\u7684\u5143\u7d20\u4f1a\u5408\u4e8c\u4e3a\u4e00\u3002<\/p>\n<p>\u4f8b\u5982\uff1a<\/p>\n<pre>document.body.merge('ol');<\/pre>\n<p>\u4f1a\u8ba9\u9875\u9762\u4e2d\u4e24\u4e2a\u76f8\u90bb\u7684\u6709\u5e8f\u5217\u8868\u5408\u4e8c\u4e3a\u4e00\u3002<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/image.zhangxinxu.com\/image\/blog\/202211\/list-merge.gif\" width=\"191\" height=\"248\" alt=\"\u5217\u8868\u5408\u5e76\u793a\u610f\" class=\"alignnone size-medium\" \/><\/p>\n<p>\u773c\u89c1\u4e3a\u5b9e\uff0c\u4ee5\u4e0a\u6240\u6709\u6848\u4f8b\u5747\u53ef\u4ee5\u8bbf\u95ee<a href=\"https:\/\/www.zhangxinxu.com\/study\/202211\/js-text-node-run.html\" rel=\"noopener\" target=\"_textnode\">\u6b64\u9875\u9762<\/a>\u8fdb\u884c\u4f53\u9a8c\u3002<\/p>\n<h3>\u4e09\u3001\u6253\u9053\u56de\u5e9c<\/h3>\n<p>\u597d\u4e86\uff0c\u5c31\u6682\u65f6\u8fd9\u4e48\u591a\u3002<\/p>\n<p>\u5b9e\u9645\u5f00\u53d1\u4e2d\uff0c\u80af\u5b9a\u8fd8\u6709\u5f88\u591a\u5176\u4ed6\u4e0e\u6587\u672c\u8282\u70b9\u76f8\u5173\u7684\u9700\u6c42\u3002<\/p>\n<p>\u5982\u679c\u60a8\u6709\u9047\u5230\uff0c\u4e14\u81ea\u5df1\u53c8\u4e0d\u4f1a\u5199\u7684\uff0c\u8bc4\u8bba\u7559\u8a00\uff0c\u6211\u4f1a\u628a\u4ee3\u7801\u5199\u7ed9\u4f60\uff0c\u653e\u5fc3\uff0c\u6211\u73b0\u5728\u53ef\u662f\u6587\u672c\u8282\u70b9\u5904\u7406\u5927\u5e08\u3002<\/p>\n<p><img decoding=\"async\" src=\"\/\/mat1.gtimg.com\/www\/mb\/images\/face\/4.gif\" align=\"absmiddle\"><\/p>\n<p>\u672c\u6587\u4e3a\u539f\u521b\u6587\u7ae0\uff0c\u6b22\u8fce\u5206\u4eab\uff0c\u52ff\u5168\u6587\u8f6c\u8f7d\uff0c\u5982\u679c\u5b9e\u5728\u559c\u6b22\uff0c\u53ef\u6536\u85cf\uff0c\u6c38\u4e0d\u8fc7\u671f\uff0c\u4e14\u4f1a\u53ca\u65f6\u66f4\u65b0\u77e5\u8bc6\u70b9\u53ca\u4fee\u6b63\u9519\u8bef\uff0c\u9605\u8bfb\u4f53\u9a8c\u4e5f\u66f4\u597d\u3002<br \/>\n\u672c\u6587\u5730\u5740\uff1a<a href=\"https:\/\/www.zhangxinxu.com\/wordpress\/?p=10635\">https:\/\/www.zhangxinxu.com\/wordpress\/?p=10635<\/a><\/p>\n<p>\uff08\u672c\u7bc7\u5b8c\uff09<\/p>\n","protected":false},"excerpt":{"rendered":"<p><img decoding=\"async\" src=\"https:\/\/image.zhangxinxu.com\/image\/blog\/202211\/node-cover.jpg\" width=\"160\" height=\"104\" alt=\"\u5c01\u9762\u56fe node\u8282\u70b9\" class=\"alignright size-medium\" loading=\"lazy\" \/><\/p>\n<p>\u4f60\u6240\u60f3\u5230\u7684\uff0c\u6240\u9700\u8981\u7684JS\u6587\u672c\u8282\u70b9\u5904\u7406\u65b9\u6cd5\u3001\u601d\u8def\u548c\u4ee3\u7801\uff0c\u8fd9\u91cc\u5e94\u8be5\u90fd\u6709\uff0c\u67e5\u627e\u3001\u5206\u5272\u3001\u5408\u5e76\u3001\u9009\u533a\u904d\u5386\uff0c\u6807\u7b7e\u66ff\u6362\u2026\u2026<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1284,180],"tags":[77,1727,812,1882,1795,1701,1307,1881,1880,773,1877,1171,1878,1170,1879,1876,207],"_links":{"self":[{"href":"https:\/\/www.zhangxinxu.com\/wordpress\/wp-json\/wp\/v2\/posts\/10635"}],"collection":[{"href":"https:\/\/www.zhangxinxu.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.zhangxinxu.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.zhangxinxu.com\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.zhangxinxu.com\/wordpress\/wp-json\/wp\/v2\/comments?post=10635"}],"version-history":[{"count":0,"href":"https:\/\/www.zhangxinxu.com\/wordpress\/wp-json\/wp\/v2\/posts\/10635\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.zhangxinxu.com\/wordpress\/wp-json\/wp\/v2\/media?parent=10635"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.zhangxinxu.com\/wordpress\/wp-json\/wp\/v2\/categories?post=10635"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.zhangxinxu.com\/wordpress\/wp-json\/wp\/v2\/tags?post=10635"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}