JavaScript 知识量:26 - 101 - 483
DOM2在Document类型上定义的createRange()方法用于创建一个Range对象。Range对象表示文档中的一段范围。使用Range对象,可以精确地控制文档中需要操作的范围,实现更加灵活和高效的操作。
createRange()方法没有参数,返回一个Range对象。
Range对象可以用于多种操作,例如选择文本、剪切/粘贴文本、插入文本等。Range对象有两个重要的方法:
startContainer和endContainer:这两个方法分别返回Range的起始节点和结束节点。
startOffset和endOffset:这两个方法分别返回Range的起始偏移量和结束偏移量。
以下是一个使用DOM2的createRange()方法的应用示例:
// 创建一个DOM文档 const xml = ` <root> <element1>Text1</element1> <element2 attribute1="value1">Text2</element2> <element3 attribute2="value2">Text3</element3> </root> `; // 解析XML文档 const parser = new DOMParser(); const doc = parser.parseFromString(xml, 'text/xml'); // 创建TreeWalker对象 const treeWalker = doc.createTreeWalker( doc.documentElement, NodeFilter.SHOW_ELEMENT, null, false ); // 遍历DOM树,找到第一个元素节点 let node; while (node = treeWalker.nextNode()) { if (node.nodeType === Node.ELEMENT_NODE) { break; } } // 创建一个Range对象,范围包括第一个元素节点及其全部内容 const range = doc.createRange(); range.setStart(node, 0); range.setEnd(node, node.childNodes.length); // 输出Range的起始节点、结束节点、起始偏移量和结束偏移量 console.log(`Start Node: ${range.startContainer}, Offset: ${range.startOffset}`); console.log(`End Node: ${range.endContainer}, Offset: ${range.endOffset}`);
这个示例使用DOM2的createTreeWalker()方法遍历DOM树,找到第一个元素节点。然后使用createRange()方法创建一个Range对象,范围包括第一个元素节点及其全部内容。最后输出Range的起始节点、结束节点、起始偏移量和结束偏移量。
要通过范围选择文档中的某个部分,最简单的方式是使用selectNode()或selectNodeContents()方法。这两个方法都接受一个参数,即一个DOM节点。
selectNode()方法会将传入的节点的整个节点作为范围。这意味着它将选择指定的节点,以及该节点的所有子节点。
selectNodeContents()方法只会将传入的节点的所有子节点作为范围。它不会包括节点本身。
这两个方法都返回一个Range对象,该对象表示文档中的一段范围。可以使用这个Range对象进行各种操作,比如选择文本、剪切/粘贴文本、插入文本等。
为了创建文档片段,范围内容的格式必须正确有效。可以使用deleteContents()方法来删除范围中的内容。
以下是一个使用selectNode()方法的应用示例:
// 创建一个DOM文档 const xml = ` <root> <element1>Text1</element1> <element2 attribute1="value1">Text2</element2> <element3 attribute2="value2">Text3</element3> </root> `; // 解析XML文档 const parser = new DOMParser(); const doc = parser.parseFromString(xml, 'text/xml'); // 创建TreeWalker对象 const treeWalker = doc.createTreeWalker( doc.documentElement, NodeFilter.SHOW_ELEMENT, null, false ); // 遍历DOM树,找到第一个元素节点 let node; while (node = treeWalker.nextNode()) { if (node.nodeType === Node.ELEMENT_NODE) { break; } } // 使用selectNode()方法选择第一个元素节点及其全部内容 const range = doc.createRange(); range.selectNode(node); // 输出Range的起始节点、结束节点、起始偏移量和结束偏移量 console.log(`Start Node: ${range.startContainer}, Offset: ${range.startOffset}`); console.log(`End Node: ${range.endContainer}, Offset: ${range.endOffset}`);
在这个示例中,首先遍历DOM树,找到第一个元素节点。然后,使用selectNode()方法选择该元素节点及其全部内容。最后,输出Range的起始节点、结束节点、起始偏移量和结束偏移量。
要创建复杂的范围,需要使用setStart()和setEnd()方法。这两个方法都接受两个参数:一个是一个节点引用,另一个是偏移量值。
setStart()方法接受一个参照节点和一个偏移量值。参照节点会变成Range对象的起始容器(startContainer),而偏移量值会变成起始偏移量(startOffset)。
setEnd()方法同样接受一个参照节点和一个偏移量值。参照节点会变成Range对象的结束容器(endContainer),而偏移量值会变成结束偏移量(endOffset)。
这两个方法可以用来模拟selectNode()和selectNodeContents()。通过使用setStart()和setEnd(),可以更精确地控制Range的范围,从而实现更复杂的操作。
以下是一个使用setStart()和setEnd()方法的应用示例:
// 创建一个DOM文档 const xml = ` <root> <element1>Text1</element1> <element2 attribute1="value1">Text2</element2> <element3 attribute2="value2">Text3</element3> </root> `; // 解析XML文档 const parser = new DOMParser(); const doc = parser.parseFromString(xml, 'text/xml'); // 创建TreeWalker对象 const treeWalker = doc.createTreeWalker( doc.documentElement, NodeFilter.SHOW_ELEMENT, null, false ); // 遍历DOM树,找到第一个元素节点 let node; while (node = treeWalker.nextNode()) { if (node.nodeType === Node.ELEMENT_NODE) { break; } } // 使用setStart()和setEnd()方法创建一个范围,包括第一个元素节点及其第二个子节点的内容 const range = doc.createRange(); range.setStart(node, 0); range.setEnd(node.childNodes[1], node.childNodes[1].childNodes.length); // 输出Range的起始节点、结束节点、起始偏移量和结束偏移量 console.log(`Start Node: ${range.startContainer}, Offset: ${range.startOffset}`); console.log(`End Node: ${range.endContainer}, Offset: ${range.endOffset}`);
在这个示例中,首先遍历DOM树,找到第一个元素节点。然后,使用setStart()和setEnd()方法创建一个范围,包括第一个元素节点及其第二个子节点的内容。最后,输出Range的起始节点、结束节点、起始偏移量和结束偏移量。
当创建一个范围时,浏览器会在内部创建一个文档片段节点(DocumentFragment)来包含该范围选区中的节点。文档片段是一个轻量级的容器,它不会引起页面重排(reflow),因此对文档片段的操作不会影响页面的性能。
在对范围的内容进行操作时,确保选区中的内容格式完好是很重要的。这意味着选区中的节点应该处于正常的文档结构中,并且没有断裂或不完整的情况。这样可以确保操作的正确性和预期的结果。
以下是一些与范围和文档片段操作相关的关键点:
创建范围:使用Range接口的createRange()方法创建一个范围。可以选择起始和结束节点,并使用setStart()和setEnd()方法设置范围的边界。
文档片段:在创建范围时,浏览器会隐式地创建一个文档片段节点来包含选区中的节点。可以通过调用Range对象的cloneContents()方法显式地获取该文档片段。
操作范围内容:要对范围的内容进行操作,可以使用Range对象的deleteContents()方法删除选区中的内容,或使用insertNode()方法在选区中插入节点。
保持范围完好:在进行操作之前,确保选区中的内容格式完好。这可以通过使用normalize()方法来清理相邻的文本节点或断裂的节点。
应用更改:在对范围的内容进行更改后,需要将这些更改应用到文档中。可以通过调用Document对象的insertBefore()或appendChild()方法来插入或添加新的节点,或使用removeChild()方法删除节点。
总之,通过使用文档片段和正确的操作方法,可以更轻松地在不影响性能的情况下处理和修改范围选区中的内容。
insertNode()方法可以在Range对象的开始位置插入一个节点。该方法接受一个参数,即要插入的节点。
在插入节点之前,需要确保Range对象是有效的,并且开始位置是在文档中的有效位置。插入节点后,Range对象的起始容器和起始偏移量会相应地更新。
以下是一个使用insertNode()方法的示例:
// 创建一个DOM文档 const xml = ` <root> <element1>Text1</element1> <element2 attribute1="value1">Text2</element2> <element3 attribute2="value2">Text3</element3> </root> `; // 解析XML文档 const parser = new DOMParser(); const doc = parser.parseFromString(xml, 'text/xml'); // 创建TreeWalker对象 const treeWalker = doc.createTreeWalker( doc.documentElement, NodeFilter.SHOW_ELEMENT, null, false ); // 遍历DOM树,找到第一个元素节点 let node; while (node = treeWalker.nextNode()) { if (node.nodeType === Node.ELEMENT_NODE) { break; } } // 创建一个新的元素节点 const newNode = doc.createElement('newElement'); newNode.textContent = 'New Text'; // 使用insertNode()方法在Range的开始位置插入新节点 const range = doc.createRange(); range.selectNode(node); range.insertNode(newNode);
在这个示例中,首先遍历DOM树,找到第一个元素节点。然后,创建一个新的元素节点,并使用insertNode()方法将其插入Range的开始位置。插入节点后,Range对象的起始容器和起始偏移量会相应地更新。
当Range对象没有选择文档的任何部分时,它被称为折叠(collapsed)。折叠的范围只有一个边界,即它的起始位置和结束位置是相同的。这意味着如果尝试在折叠的范围中插入节点或内容,将不会有任何效果,因为范围的起始位置和结束位置没有任何节点或内容。
折叠的范围主要用于文档编辑和处理中的特定操作,例如创建、移动或删除范围。在处理折叠的范围时,需要特别注意确保操作的正确性和有效性。
compareBoundaryPoints() 是 Range 接口的一个方法,它用于比较两个 Range 对象的边界点。这个方法可以用来确定两个范围之间是否存在公共的边界(起点或终点)。
该方法接受一个参数,这个参数是 RangeComparisonAlgorithm 枚举类型的一个值,用于指定比较的方法。其中,有以下几种比较算法可以选择:
START_TO_START:比较两个范围的起始点。
START_TO_END:比较两个范围的起始点与结束点。
END_TO_END:比较两个范围的结束点。
END_TO_START:比较两个范围的结束点与起始点。
compareBoundaryPoints() 方法返回一个整数,这个整数表示两个范围的边界点比较的结果。如果返回值为 0,表示两个范围的边界点相同;如果返回值为 -1 或 1,表示一个范围的边界点在另一个范围的边界点之前或之后。
这个方法在处理多个 Range 对象时非常有用,可以通过比较它们的边界点来确定这些范围之间的关系,例如确定哪些范围相交、哪些范围相邻等。
cloneRange() 是 Range 接口的一个方法,用于复制一个 Range 对象。这个方法返回一个新的 Range 对象,它是原始 Range 对象的深拷贝,包括起始和结束节点以及它们的子节点。
使用 cloneRange() 方法可以避免对原始 Range 对象的修改影响其他代码。通过复制 Range 对象,可以在不改变原始数据的情况下进行修改和操作。这在处理 DOM 操作和文档编辑时非常有用,因为这些操作可能会影响到文档的结构和内容。
以下是一个使用 cloneRange() 方法的示例:
// 创建一个DOM文档 const xml = ` <root> <element1>Text1</element1> <element2 attribute1="value1">Text2</element2> <element3 attribute2="value2">Text3</element3> </root> `; // 解析XML文档 const parser = new DOMParser(); const doc = parser.parseFromString(xml, 'text/xml'); // 创建TreeWalker对象 const treeWalker = doc.createTreeWalker( doc.documentElement, NodeFilter.SHOW_ELEMENT, null, false ); // 遍历DOM树,找到第一个元素节点 let node; while (node = treeWalker.nextNode()) { if (node.nodeType === Node.ELEMENT_NODE) { break; } } // 创建一个Range对象,选择第一个元素节点的内容 const range = doc.createRange(); range.selectNodeContents(node); // 调用cloneRange()方法复制Range对象 const clonedRange = range.cloneRange(); // 在复制的范围中插入一个新的文本节点 const newText = doc.createTextNode('New Text'); clonedRange.insertNode(newText);
在这个示例中,首先遍历DOM树,找到第一个元素节点。然后,创建一个 Range 对象,并使用 selectNodeContents() 方法选择第一个元素节点的内容。接下来,调用 cloneRange() 方法复制这个 Range 对象,并在复制的范围中插入一个新的文本节点。最后,可以根据需要使用复制的范围进行其他操作。
detach() 方法是 Range 接口的一个方法,用于从创建它的文档中剥离一个范围。当使用完一个范围后,最好调用 detach() 方法来释放与该范围相关联的资源,以避免内存泄漏。
调用 detach() 方法会将范围与文档分离,这意味着范围不再引用或关联到文档中的任何节点或内容。这样做可以确保范围不再占用任何文档资源,并且可以安全地被垃圾回收机制回收,从而释放内存空间。
在调用 detach() 方法之后,范围将不再可用或可访问。因此,确保在调用 detach() 方法之前已经完成了对范围的所有必要操作。
以下是一个使用 detach() 方法的示例:
// 创建一个DOM文档 const xml = ` <root> <element1>Text1</element1> <element2 attribute1="value1">Text2</element2> <element3 attribute2="value2">Text3</element3> </root> `; // 解析XML文档 const parser = new DOMParser(); const doc = parser.parseFromString(xml, 'text/xml'); // 创建TreeWalker对象 const treeWalker = doc.createTreeWalker( doc.documentElement, NodeFilter.SHOW_ELEMENT, null, false ); // 遍历DOM树,找到第一个元素节点 let node; while (node = treeWalker.nextNode()) { if (node.nodeType === Node.ELEMENT_NODE) { break; } } // 创建一个Range对象,选择第一个元素节点的内容 const range = doc.createRange(); range.selectNodeContents(node); // 在需要使用范围的操作完成后,调用detach()方法剥离范围 range.detach();
在这个示例中,首先遍历DOM树,找到第一个元素节点。然后,创建一个 Range 对象,并使用 selectNodeContents() 方法选择第一个元素节点的内容。在进行完必要的操作后,调用 detach() 方法剥离该范围,确保释放与该范围相关的资源。
Copyright © 2017-Now pnotes.cn. All Rights Reserved.
编程学习笔记 保留所有权利
MARK:3.0.0.20240214.P35
From 2017.2.6