Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/431.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 获取已单击元素的HTML源代码中的插入符号[start,end]位置_Javascript_Html_Dom - Fatal编程技术网

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的组合。