Javascript 获取已单击元素的HTML源代码中的插入符号[start,end]位置
这是一个相当具有挑战性的问题。我还没有看到它在堆栈溢出的任何地方得到解决。所以我决定把它贴出来Javascript 获取已单击元素的HTML源代码中的插入符号[start,end]位置,javascript,html,dom,Javascript,Html,Dom,这是一个相当具有挑战性的问题。我还没有看到它在堆栈溢出的任何地方得到解决。所以我决定把它贴出来 0 ----17----+ +---30--- | | | +----47 | | | | <div>ABC<b>B Elem<i>Italic</i>ent<
0 ----17----+ +---30---
| | | +----47
| | | |
<div>ABC<b>B Elem<i>Italic</i>ent</b> DEF</div>
| |
+---8--- ---37--+
0----17---++-30---
| | | +----47
| | | |
ABCB电子许可证DEF
| |
+---8--- ---37--+
操作:假设单击了元素标记
问题:创建一个返回坐标的函数[17,30]
注意:坐标是原始HTML源代码中的插入符号位置,表示为基于0的索引,仅包含单击的元素。可以假定标准化的HTML节点在id=”“中变为id=”“。(但如果没有额外的学分)
示例2:如果单击了标记。脚本应该返回[8,37],因为它是包含B标记的开始/结束插入符号位置
<强>实例3:< /强>如果ABC文本或DEF文本被点击,返回值为[0,44]
走父链,直到你击中你认为是容器的任何标签(在你的情况下,显然是代码> <代码>)。 如果您有两个或两个以上相同的孩子,请使用家长的孩子来定位您来自的特定孩子,如
从2到2到2
这将为您提供父对象内的子对象偏移量。然后,您可以累积偏移量,直到到达
div
标记或任何其他容器元素。结束位置就是这个偏移量加上点击的元素长度。解决这个问题两天后,我发布了我自己的解决方案 起初,我试图解析DOM并手动计数字符。但这比必须要复杂得多 信用:感谢kuroi neko,他建议结束插入符号位置只是开始位置+包含单击标记的HTML长度 注意:在计算插入符号值之前,我正在手动删除标记。这是因为,即使原始HTML不包含它们,在规范化过程中(在innerHTML或outerHTML调用期间发生),它们也会自动插入。如果您正在构建一个需要此功能的文本编辑器,那么这是一个个人偏好——让它们单独运行并更新原始HTML
另一方面,如果您更喜欢纯的方法,并且想考虑原始HTML的完整性,因为它是由HTML的作者编写的,那么您可能需要手动删除。这还假设您负责处理所有其他案例,类似于这些案例。不管是什么。(不包括在下面的解决方案中。)
解决方案:考虑到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);
});
});
$(文档).ready(函数(){
//规范化源代码
var normalized_html=document.getElementById(“预览”).innerHTML;
//删除所有TBODY标记(它们是自动插入的,即使在原始HTML中不存在)
normalized_html=normalized_html.replace(//g',);
$(“#textarea”).html(标准化的#html);
$(“#预览”)。在(“单击”)上,函数(事件){
//点击标签HTML
var tag=event.target.outerHTML;
//在插入拆分字符之前获取原始HTML
var orig_html=document.getElementById(“预览”).innerHTML;//.replace(//g',).replace(//g',);
//在单击的标记之前插入唯一分隔符,以标记开始
$(event.target).before(“[*-*]”);
//获取预览源代码
var html=document.getElementById(“预览”).innerHTML;
//删除换行符
html=html.replace(/\r |\n/g');
//删除原始HTML中不存在的本机规范化过程自动插入的标记。
html=html.replace(//g',);
分割前的var=html;
//在单击的标记处拆分HTML
html=html.split(“[*-*]”[0];
//将预览还原为原始HTML
$(“#预览”)[0];
//获取源代码中插入符号的开始和结束
var caret_start=html.length;
变量插入符号结束=插入符号开始+标记长度;
console.log(“插入符号开始=“+caret\u开始+”结束=“+caret\u结束”);
});
});
您只需使用库即可实现这一点
//获取目标文档的源html代码
var html=yourFunctionToGetHTML();
//获取目标文档本身
var dom=yourFunctionToGetDocument();
//获取要在源代码中找到的元素
var元素=document.getElementById(“目标元素”);
//创建一个Descop实例
var descop=新的descop();
//连接文档
描述连接文档(dom);
//连接源代码
descop.connectSource(html);
//获取元素在源代码中的位置
变量位置=描述getElementPosition(元素);
//例如,位置=>{开始:320,结束:480}
我们可以问一下你为什么要这样做吗?@TimBiegeleisen,我就知道这会发生。通过从可视化UI中单击源代码来拾取源代码:-)dom除外!=源代码,例如:空格、
vs
等。要映射回字符串源代码将需要相当多的工作。@dandavis,是的,此问题假定为。如果想要获得准确的结果,可能需要编写自定义工具。它仍然可以通过DOM提供的功能来实现,但结果可能是一个或几个字符。可以是自定义代码和DOM的组合。