[英]js TreeWalker and/or document.createRange() not picking up single element
我有一個帶有單個內部節點的 div:
<section id="Source" class="source">
<div>
test
</div>
</section>
我正在嘗試使用document.createRange()
和document.createTreeWalker()
獲取其內容,如下所示:
function findEndNode(source, maxHeight) {
const range = document.createRange();
range.selectNodeContents(source);
var nodes = document.createTreeWalker(
source,
NodeFilter.SHOW_ELEMENT,
null,
null
);
while (node = nodes.nextNode()) {
range.setEndBefore(nodes.currentNode);
const {
height
} = range.getBoundingClientRect();
const rangeHeight = height;
if (maxHeight <= rangeHeight) {
console.log('out of bounds');
const newNode = nodes.previousNode();
range.setEndBefore(nodes.currentNode);
break;
} else {
console.log('within bounds');
continue;
}
}
return range;
};
但是在此過程中,最里面的節點丟失了。
正如您在完整代碼(包含在代碼段中)中看到的那樣,“測試”跨度保留在源中,而應將其移至克隆。
const source = document.getElementById('Source'); const target = document.getElementById('Target'); const wrapper = document.getElementById('Wrapper'); wordWrap(source); splitContent(source, target, wrapper); //splitContent(source, target, wrapper); function splitContent(source, target, wrapper) { const { height } = target.getBoundingClientRect(); const maxHeight = height; const range = document.createRange(); const endNode = findEndNode(source, maxHeight); range.setStart(source, 0); range.setEnd(endNode.endContainer, endNode.endOffset); const content = range.extractContents(); const clone = target.cloneNode(false); clone.id = 'Clone'; clone.appendChild(content); wrapper.appendChild(clone); const hasChildren = source.hasChildNodes(); }; function findEndNode(source, maxHeight) { const range = document.createRange(); range.selectNodeContents(source); var nodes = document.createTreeWalker( source, NodeFilter.SHOW_ELEMENT, null, null ); while (node = nodes.nextNode()) { range.setEndBefore(nodes.currentNode); const { height } = range.getBoundingClientRect(); const rangeHeight = height; if (maxHeight <= rangeHeight) { console.log('out of bounds'); const newNode = nodes.previousNode(); range.setEndBefore(nodes.currentNode); break; } else { console.log('within bounds'); continue; } } return range; }; function wordWrap(element) { var nodes = document.createTreeWalker( element, NodeFilter.SHOW_TEXT, null, null ); var node; while (node = nodes.nextNode()) { var p = node.parentNode; var text = node.nodeValue; var m; while (m = text.match(/^(\\s*)(\\S+)/)) { text = text.slice(m[0].length); p.insertBefore(document.createTextNode(m[1]), node); var word = p.insertBefore(document.createElement('span'), node); word.appendChild(document.createTextNode(m[2])); word.className = 'word'; } node.nodeValue = text; } }
section { font-family: arial; font-size: 11pt; } .target { height: 400px; width: 400px; border: 2px dashed green; margin: 20px; } .source { border: 2px dashed blue; width: 400px; margin: 20px; } #Clone { border-color: red; }
<section id="Source" class="source"> <div> test </div> </section> <div id="Target" class="target"> </div> <section id="Wrapper"> </section>
您的端偏移已關閉。 在findEndNodes
當您找到節點時,您當前的代碼假定偏移量比所需的數量少 1,這是因為您在使用 setEndBefore 時應該使用 setEndAfter。
const source = document.getElementById('Source'); const target = document.getElementById('Target'); const wrapper = document.getElementById('Wrapper'); wordWrap(source); splitContent(source, target, wrapper); //splitContent(source, target, wrapper); function splitContent(source, target, wrapper) { const { height } = target.getBoundingClientRect(); const maxHeight = height; const range = document.createRange(); const endNode = findEndNode(source, maxHeight); range.setStart(source, 0); range.setEnd(endNode.endContainer, endNode.endOffset); const content = range.extractContents(); const clone = target.cloneNode(false); clone.id = 'Clone'; clone.appendChild(content); wrapper.appendChild(clone); const hasChildren = source.hasChildNodes(); }; function findEndNode(source, maxHeight) { const range = document.createRange(); range.selectNodeContents(source); var nodes = document.createTreeWalker( source, NodeFilter.SHOW_ELEMENT, null, null ); while (node = nodes.nextNode()) { range.setEndAfter(nodes.currentNode); const { height } = range.getBoundingClientRect(); const rangeHeight = height; if (maxHeight <= rangeHeight) { console.log('out of bounds'); const newNode = nodes.previousNode(); range.setEndAfter(nodes.currentNode); break; } else { console.log('within bounds'); continue; } } return range; }; function wordWrap(element) { var nodes = document.createTreeWalker( element, NodeFilter.SHOW_TEXT, null, null ); var node; while (node = nodes.nextNode()) { var p = node.parentNode; var text = node.nodeValue; var m; while (m = text.match(/^(\\s*)(\\S+)/)) { text = text.slice(m[0].length); p.insertBefore(document.createTextNode(m[1]), node); var word = p.insertBefore(document.createElement('span'), node); word.appendChild(document.createTextNode(m[2])); word.className = 'word'; } node.nodeValue = text; } }
section { font-family: arial; font-size: 11pt; } .target { height: 400px; width: 400px; border: 2px dashed green; margin: 20px; } .source { border: 2px dashed blue; width: 400px; margin: 20px; } #Clone { border-color: red; }
<section id="Source" class="source"> <div> test </div> </section> <div id="Target" class="target"> </div> <section id="Wrapper"> </section>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.