javascript - 使用 treewalker 格式化 HTML
问题描述
我无法让这段代码充分发挥作用。我注意到,当一个人从下到上突出显示文本而不是从上到下突出显示时,结果是不同的。
当我从下到上突出显示时,我已经能够让它工作(即在第 4 行到第 2 行的中间开始突出显示,所以你有 2.5 行突出显示)
我的目标是使我的编辑器能够格式化突出显示的文本,无论它是粗体、下划线、颜色等等。
以下是可编辑 div 中的 HTML:
<div contenteditable="false" parentdiv="container" id="someID" style="z-index: 50; width: 207px; height: 124px; top: 285px; left: 151.99px; position: absolute; outline-color: rgb(255, 0, 0);" placeholder="double click to type">
<div class="divContent" contenteditable="false" placeholder="Type here" style="position: absolute; width: 100%; height: 100%; color: rgb(0, 0, 0); cursor: move; z-index: 2; outline-color: rgb(170, 170, 170); opacity: 1; border: 2px solid rgb(255, 0, 0);" haserror="1">
<span class="fontFormatContainer" style="font-family: Lato; font-size: 12pt; line-height: 1.3;">First line of text</span><br>
<span class="fontFormatContainer" style="font-family: Lato; font-size: 8pt; line-height: 1.3;">Developer</span><br>
<span class="fontFormatContainer" style="font-family: Lato; font-size: 10pt; line-height: 1.3;">Cell: (941) 405-8180</span><br>
<span class="fontFormatContainer" style="font-family: Lato; font-size: 10pt; line-height: 1.3;">Cell: (941) 405-1111</span><br>
<span class="fontFormatContainer" style="font-family: Lato; font-size: 10pt; line-height: 1.3;">Another line of text</span><br>
<span class="fontFormatContainer" style="font-family: Lato; font-size: 10pt; line-height: 1.3;">https://Some.URL.com/Registration.asp</span>
</div>
</div>
下面是我的代码:
var selection = window.getSelection();
if (!selection.isCollapsed) { // we have a non-zero length selection
var endNode = selection.focusNode;
var endOffset = selection.focusOffset;
if (endNode instanceof Text) { // if an element then offset = child node idx
endNode.splitText(endOffset);
}
var startNode = selection.anchorNode;
var startOffset = selection.anchorOffset;
if (startNode instanceof Text) {
startNode.splitText(startOffset);
startNode = startNode.nextSibling;
}
}
function filterFunction(node) {
if (node.id === 'ignore')
return NodeFilter.FILTER_REJECT;
return NodeFilter.FILTER_ACCEPT;
}
var nodeTypes = NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT;
var root = range.commonAncestorContainer;
var walker = document.createTreeWalker(root, nodeTypes, { acceptNode: filterFunction }, false);
walker.currentNode = startNode;
var nextNode = walker.currentNode;
//var html = [];
if (startOffset < endOffset) {
while (nextNode && nextNode !== endNode) {
if (nextNode.nodeType === Node.TEXT_NODE) {
if (nextNode.nodeValue.trim() !== '') {
switch (objStyle.val) {
case 'bold':
$(nextNode.parentElement).css(objStyle.attr).indexOf('700') !== -1 ? objStyle.val = 'normal' : objStyle.val = '700';
break;
case 'italic':
$(nextNode.parentElement).css(objStyle.attr).indexOf('italic') !== -1 ? objStyle.val = 'normal' : objStyle.val = objStyle.val;
break;
case 'underline':
$(nextNode.parentElement).css(objStyle.attr).indexOf('underline') !== -1 ? objStyle.val = 'none' : objStyle.val = objStyle.val;
break;
case 'line-through':
$(nextNode.parentElement).css(objStyle.attr).indexOf('line-through') !== -1 ? objStyle.val = 'none' : objStyle.val = objStyle.val;
break;
}
if (nextNode.nodeValue === nextNode.parentElement.innerText)
$(nextNode.parentElement).css(objStyle.attr, objStyle.val);
else {
var baseHTML = nextNode.parentElement.innerHTML;
baseHTML = baseHTML.replace(nextNode.nodeValue, '<span style="' + objStyle.attr + ':' + objStyle.val + '">' + nextNode.nodeValue + '</span>');
nextNode.parentElement.innerHTML = baseHTML; //nextNode.parentElement.innerHTML.replace(html[i], '');
}
}
}
nextNode = walker.nextNode();
}
} else {
while (nextNode && nextNode !== endNode) {
if (nextNode.nodeType === Node.TEXT_NODE) {
if (nextNode.nodeValue.trim() !== '') {
switch (objStyle.val) {
case 'bold':
$(nextNode.parentElement).css(objStyle.attr).indexOf('700') !== -1 ? objStyle.val = 'normal' : objStyle.val = '700';
break;
case 'italic':
$(nextNode.parentElement).css(objStyle.attr).indexOf('italic') !== -1 ? objStyle.val = 'normal' : objStyle.val = objStyle.val;
break;
case 'underline':
$(nextNode.parentElement).css(objStyle.attr).indexOf('underline') !== -1 ? objStyle.val = 'none' : objStyle.val = objStyle.val;
break;
case 'line-through':
$(nextNode.parentElement).css(objStyle.attr).indexOf('line-through') !== -1 ? objStyle.val = 'none' : objStyle.val = objStyle.val;
break;
}
if (nextNode.nodeValue === nextNode.parentElement.innerText)
$(nextNode.parentElement).css(objStyle.attr, objStyle.val);
else {
var baseHTML = nextNode.parentElement.innerHTML;
baseHTML = baseHTML.replace(nextNode.nodeValue, '<span style="' + objStyle.attr + ':' + objStyle.val + '">' + nextNode.nodeValue + '</span>');
nextNode.parentElement.innerHTML = baseHTML;
}
}
}
nextNode = walker.previousNode();
}
}
解决方案
推荐阅读
- c - C TCP 无法检测到断开的连接
- postgresql - postgresql:逻辑复制是否包括回滚事务?
- sql - 如何在不同的存储过程 (SQL) 中使用来自一个存储过程的变量
- python - Python Kivy 使用 Matplotlib 绘制实时图形(尺寸太小)
- php - Laravel 路由发布与获取
- java - 如何在 MAC OSX 上使用 java 启动 appium 服务器
- function - 运行 python/pyspark 函数时需要更多参数
- mysql - 使用 JOIN 时 SQL 语法不正确
- swift - 如何使用 Xcode 对象库为 Cocoa Swift 构建插入删除表单?
- android - 如何填充RelativeLayout中两个视图之间的布局?