可以使用 execCommand 或类似函数来设置而不是切换像粗体这样的简单样式吗?
Can execCommand or a similar function be used to set, rather than to toggle, a simple style like bold?
如果 contenteditable div 的内容已经是粗体,则 execCommand("bold") 将删除粗体样式。
这在正常情况下很好,但我有一种情况,我想遍历一堆内容可编辑的 divs 并将任何非粗体文本设置为粗体,这是一种设置样式的方式一次使用多个富文本元素,使用适当的或 'font-weight' execCommand 使用的任何内容。
我可以通过单独检查每个 div 中的每个节点来实现这一点,但我想首先确保没有更简单的方法。
好吧,我找不到简单的方法,所以我用了困难的方法。
我已经有了一个函数,它可以将单个元素的内容复制到工作 space div 中,并且干净 CSS,然后通过该工作中的每个节点递归 space。对于每个文本节点,它会遍历我正在寻找的每种样式并查看是否设置了该样式。如果不是,它将清除在其 运行 之前设置的 "every node has this style" 标志。所以我最终得到了每个节点的每个样式集的列表。
当前任务的第一步是确定哪些样式应用于所有选定元素。所以我采用了该函数并创建了一个修改版本,首先将每个元素的内容添加到工作 space div。然后 运行 正常递归遍历工作 space,基本上将每个单独的元素视为同一个复杂的富文本字符串的一部分。
这给了我每种样式的状态,比如是否所有内容都是粗体,因此粗体按钮是否应显示为已按下。
我还为每种样式添加了一个数组。当我遍历元素,跟踪它们的 individual "every node has this style" 值时,我会想出一个元素列表,其中每个节点都有样式,因此 execcommand("bold") 会切换该元素。
现在,对于每种样式(如粗体按钮),我知道它会切换任何元素还是所有元素。如果它会切换所有元素,或者没有元素,那很好,因为行为是一致的。但是如果它切换了元素的子集(如果样式的 "elements_that_would_toggle" 数组长度大于零但小于 total_elements 计数),那么我会在第一次单击按钮时忽略那些可切换的元素.
在点击处理结束时,我会清空每种样式的数组,从而将整个行为恢复为切换状态,因为现在每个元素都已设置为相同的状态。
这是一种令人厌恶的方法,但它是可控的和一致的,而且效果非常好。
而且只用了一天就开始工作了。
这取决于您制作的编辑器的复杂程度。如果您不想在粗体区域内使用普通文本,则只测试最深的可编辑文本容器就足够了,因此每个可编辑 div 一个元素。
举个例子,
function bold(node) {
var selection = window.getSelection();
var range = document.createRange();
range.selectNodeContents(node);
selection.removeAllRanges();
selection.addRange(range);
if (!isBold(getDeepestContainer(selection.anchorNode)))
document.execCommand("bold");
selection.removeAllRanges();
node.blur();
}
function getDeepestContainer(node) {
var result = node;
while (result.childNodes.length === 1) {
result = result.firstChild;
}
if (result instanceof Element)
return result;
return result.parentElement;
}
如果 contenteditable div 的内容已经是粗体,则 execCommand("bold") 将删除粗体样式。
这在正常情况下很好,但我有一种情况,我想遍历一堆内容可编辑的 divs 并将任何非粗体文本设置为粗体,这是一种设置样式的方式一次使用多个富文本元素,使用适当的或 'font-weight' execCommand 使用的任何内容。
我可以通过单独检查每个 div 中的每个节点来实现这一点,但我想首先确保没有更简单的方法。
好吧,我找不到简单的方法,所以我用了困难的方法。
我已经有了一个函数,它可以将单个元素的内容复制到工作 space div 中,并且干净 CSS,然后通过该工作中的每个节点递归 space。对于每个文本节点,它会遍历我正在寻找的每种样式并查看是否设置了该样式。如果不是,它将清除在其 运行 之前设置的 "every node has this style" 标志。所以我最终得到了每个节点的每个样式集的列表。
当前任务的第一步是确定哪些样式应用于所有选定元素。所以我采用了该函数并创建了一个修改版本,首先将每个元素的内容添加到工作 space div。然后 运行 正常递归遍历工作 space,基本上将每个单独的元素视为同一个复杂的富文本字符串的一部分。
这给了我每种样式的状态,比如是否所有内容都是粗体,因此粗体按钮是否应显示为已按下。
我还为每种样式添加了一个数组。当我遍历元素,跟踪它们的 individual "every node has this style" 值时,我会想出一个元素列表,其中每个节点都有样式,因此 execcommand("bold") 会切换该元素。
现在,对于每种样式(如粗体按钮),我知道它会切换任何元素还是所有元素。如果它会切换所有元素,或者没有元素,那很好,因为行为是一致的。但是如果它切换了元素的子集(如果样式的 "elements_that_would_toggle" 数组长度大于零但小于 total_elements 计数),那么我会在第一次单击按钮时忽略那些可切换的元素.
在点击处理结束时,我会清空每种样式的数组,从而将整个行为恢复为切换状态,因为现在每个元素都已设置为相同的状态。
这是一种令人厌恶的方法,但它是可控的和一致的,而且效果非常好。
而且只用了一天就开始工作了。
这取决于您制作的编辑器的复杂程度。如果您不想在粗体区域内使用普通文本,则只测试最深的可编辑文本容器就足够了,因此每个可编辑 div 一个元素。
举个例子,
function bold(node) {
var selection = window.getSelection();
var range = document.createRange();
range.selectNodeContents(node);
selection.removeAllRanges();
selection.addRange(range);
if (!isBold(getDeepestContainer(selection.anchorNode)))
document.execCommand("bold");
selection.removeAllRanges();
node.blur();
}
function getDeepestContainer(node) {
var result = node;
while (result.childNodes.length === 1) {
result = result.firstChild;
}
if (result instanceof Element)
return result;
return result.parentElement;
}