【发布时间】:2011-09-20 14:07:20
【问题描述】:
目前我在为 Mozilla 和基于 Webkit 的浏览器编写抽象层以使用 DOM-range 对象(获取和处理用户选择)时遇到了一些麻烦。
我也尝试过看看像 Rangy 这样的框架,但这对于我的任务来说似乎太复杂了(我不知道在代码中的确切位置可以找到我需要的信息。如果有人能给我提示,我将不胜感激!)。
我想要的只是这个:
- 取回对选择开始的文本节点的引用及其偏移量
- 取回对选择结束的文本节点的引用及其偏移量
到目前为止,我的图层如下所示:
var SEL_ABSTR = {
get_selection: function(window_object) {
return window_object.getSelection();
},
get_range: function(selection) {
return (selection.getRangeAt) ? selection.getRangeAt(0) : selection.createRange();
},
get_range_info: function(range, div_ele) {
var first_node, start_offset;
var last_node, end_offset;
if (range.startContainer == div_ele) {
// selections affects the containing div
first_node = div_ele.childNodes[0];
last_node = first_node;
start_offset = 0;
end_offset = first_node.nodeValue.length;
} else if (range.startOffset == range.startContainer.nodeValue.length && range.endOffset == 0) {
// known bug in Firefox
alert('firefox bug');
first_node = range.startContainer.nextSibling.childNodes[0];
last_node = first_node;
start_offset = 0;
end_offset = first_node.nodeValue.length;
} else {
first_node = range.startContainer;
last_node = range.endContainer;
start_offset = range.startOffset;
end_offset = range.endOffset;
}
return {
first_node: first_node,
start_offset: start_offset,
last_node: last_node,
end_offset: end_offset,
orig_diff: end_offset - start_offset
};
},
};
我现在发现了两个 Mozilla 错误:
有时,当在包含的 div 中选择整个(如果它是唯一的)文本节点时,我会返回对此 div 的引用,而不是对文本节点的引用。现在我可以处理它并返回对 div 子节点的引用,即文本节点
有时我会返回对前一个兄弟的引用,偏移量 == prevSibling.length 和对 nextSibling 的引用,偏移量 == 0。但正确的引用会在中间。这个我也能搞定。
那么 Mozilla 还有什么? Webkit 工作正常!
应该假设 DOM-range 对象是标准的(我不是在说 IE,这是另一项任务......)
你好!
这里有更具体的细节:
这并不是对 Rangy 的批评。所以我很抱歉,如果它听起来像那样。我可以想象,处理这些不同的 API 本身并不容易。
你说得对,我没有具体说明我要完成的任务。我的结构相当简单:我有一个 div(属性 contenteditable=true)和该 div 中的文本(开头有一个文本节点)。
从这个结构开始,现在可以用鼠标选择文本并为其添加属性;然后,此属性由包含选定文本的跨度和分配给该跨度的表示选定属性的类表示。现在可以再次选择一些文本和属性。如果它是相同的文本和另一个属性,则另一个类将分配给该跨度,如果该属性已存在,则将其删除。如果选择包含多个跨度的文本,它们将被拆分以表达该结构(也许您还记得我 7 月份的帖子)。
<div contenteditable="true">
hello I am
<span class="red">text but I am also <span class="underline">underlined</span></span>
<span class="underline"> also without color</span>
</div>
该算法现在适用于“对称”情况:我可以构建一个复杂的结构,然后向后撤消它。它适用于 Safari 和 Chrome。现在我当然要进一步开发算法。
但现在我对 Mozilla 有问题,因为我不了解 DOM 范围对象的系统:startContainer、endContainer、startOffset、endOffset
根据我对仅包含文本节点和跨度的 div 的具体情况的看法,我假设:
- startContainer 和 endContainer 始终指向受鼠标选择影响的文本节点(没有空跨度,它们始终包含其他跨度或文本节点),标记整个选择的开始和结束
- startOffset 和 endOffset 指示所选内容在 textnode 中开头和结尾的位置
在上面发布的代码中,我确定了 Mozilla 与 webkit 的行为不同的两种情况。
因此,如果我知道 Mozilla DOM-range 的规则,我可以将其整合到我的层中,这样 webkit 和 Mozilla 的行为将是相同的。
非常感谢您的回答。
【问题讨论】:
标签: javascript webkit range mozilla