这是一个非常具有挑战性的问题。我还没有看到它在Stack Overflow上的任何地方都能解决。所以我决定发布它。
0 ----17----+ +---30---
| | | +----47
| | | |
<div>ABC<b>B Elem<i>Italic</i>ent</b> DEF</div>
| |
+---8--- ---37--+
操作:让我们点击元素&lt; i&gt; 标记。
问题:创建一个返回坐标[17,30]
的函数注意:坐标为 开始 和 结束 插入位置,代表作为基于0的索引,在原始HTML源代码中,仅包含被单击的元素。可以假设规范化的HTML节点,如id =&#34;&#34;成为id =&#34;&#34;。 (但是,如果它没有额外的功劳,那么。)
示例2:如果&lt; b&gt;标签被点击了。该脚本应返回[8,37],因为它是包含B标记的开始/结束插入符号位置。
示例3:如果单击了ABC文本或DEF文本,则返回值为[0,47]
答案 0 :(得分:0)
走父链,直到你点击你认为是容器的任何标记(显然你的情况为<div>
)。
如果您有两个或更多相同的孩子,请使用父母的孩子找到您来自的特定孩子,例如from <i>two</i> to <i>two</i> to <i>two</i> <i>two</i>
。
这应该给你父母的子偏移。然后,您可以累计偏移量,直到您点击div
标记或其他任何容器元素
结束位置只是这个偏移加上点击的元素长度。
答案 1 :(得分:0)
经过两天的解决,我发布了自己的解决方案。
我首先尝试解析DOM并手动计算字符数。但这比以前更加复杂。
信用:感谢kuroi neko,他建议最终插入位置只是包含点击标记的HTML的起始位置+长度。
注意:我手动删除&lt; tbody&gt;标签,在计算插入符号值之前。这是因为,即使原始HTML不包含它们,在规范化过程中(在innerHTML或outerHTML调用期间发生),它们也会自动插入。如果您正在构建需要此功能的文本编辑器,那么这是个人偏好 - 让他们独自一人并更新原始HTML。
另一方面,如果您更喜欢纯粹主义方法,并且想要完整地考虑原始HTML,因为它是由所述HTML的作者编写的,那么您可能希望删除&lt; tbody&gt;手动。这也假设您负责处理所有其他类似的案件。无论他们是什么。 (未包含在以下解决方案中。)
解决方案:考虑 textarea (HTML源代码编辑器)和 #preview 是表示相同HTML的两个独立元素。
$(document).ready(function() {
// Normalize source code
var normalized_html = document.getElementById("preview").innerHTML;
// Remove all TBODY tags (they are auto-inserted, even if not present in original HTML)
normalized_html = normalized_html.replace(/<tbody>/g, '');
$("#textarea").html(normalized_html);
$("#preview").on("click", function(event) {
// Get clicked tag HTML
var tag = event.target.outerHTML;
// Get original HTML before split character is inserted
var orig_html = document.getElementById("preview").innerHTML;//.replace(/<preview>/g, '').replace(/<\/preview>/g, '');
// Insert unique separator just before the tag that was clicked, to mark beginning
$(event.target).before("[*-*]");
// Get preview source code
var html = document.getElementById("preview").innerHTML;
// Remove line breaks
html = html.replace(/\r|\n/g, '');
// Remove tags that were auto-inserted by native normalization process that did not exist in original HTML.
html = html.replace(/<tbody>/g, '');
var before_split = html;
// Split HTML at the tag that was clicked
html = html.split("[*-*]")[0];
// Restore preview to original HTML
$("#preview")[0].innerHTML = orig_html;
// Get start and end of caret in source code
var caret_start = html.length;
var caret_end = caret_start + tag.length;
console.log("caret start = " + caret_start + " end = " + caret_end);
});
});
答案 2 :(得分:0)
只需使用Descop库就可以实现这一目标。
// Get the source html code of target document
var html = yourFunctionToGetHTML();
// Get the target document itself
var dom = yourFunctionToGetDocument();
// Get the element you want to found in source code
var element = document.getElementById("target-element");
// Create an instance of Descop
var descop = new Descop();
// Connect document
descop.connectDocument(dom);
// Connect source code
descop.connectSource(html);
// Get element position in source code
var position = descop.getElementPosition(element);
// eg. position => { start: 320, end: 480 }