在Javascript中找出dom中的一个元素的行号? [英] Finding out what line number an element in the dom occurs on in Javascript?

查看:109
本文介绍了在Javascript中找出dom中的一个元素的行号?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

虽然我从来没有听说过这个,但是是否可以使用JS从DOM中检索一个节点,然后找出节点发生的文件的哪一行?



我打开任何东西,替代浏览器插件/附加组件等...它不需要是跨浏览器的说。



我会假设这可能以某种方式考虑到一些JS调试器能够在脚本标签中找到行号,但我不完全确定。

解决方案

好的,请原谅我这么大。我认为这是一个非常有趣的问题,但是在玩它的时候,我很快就意识到innerHTML和它的ilk是相当不可靠的,保持空白,评论等等。考虑到这一点,我回到了实际上把全部副本来源,所以我可以绝对肯定我得到了完整的来源。然后我使用jquery和一些(相对较小的)正则表达式来查找每个节点的位置。这似乎很好,尽管我确信我错过了一些边缘案例。而且,是的,是的,正则表达式和两个问题,blah blah blah。



编辑:作为构建jquery插件的一个练习,修改了我的代码,作为独立的插件示例类似于下面找到的html(我将在此留下后代)。我试图使代码稍微更强大(例如现在处理引用的字符串中的标签,例如onclick),但最大的剩余错误是它不能解释对页面的任何修改,例如添加元素。我可能需要使用iframe而不是ajax调用来处理这种情况。

 < html> 
< head id =node0>
<! - 第一个评论 - >
< script src =http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js>< / script>
< style id =node1>
/ * div {border:1px solid black; } * /
pre {border:1px solid black; }
< / style>
<! - 第二个评论 - >
< script>
$(function(){

// fetch and display source
var source;
$ .ajax({
url:location.href,
type:'get',
dataType:'text',
success:function(data){
source = data;


var lines = data.split(/ \r?\\\
/);
var html = $ .map(lines,function(line,i){
return ['< span id =line_number_,i,'>< strong>',i,':< / strong>',line.replace(/< / g,'& ; / g,'& gt;'),'< / span>']。join('');
})join('\\\
');

//现在清理原始的html,所以你不会在代码或评论中获得错误的命中
var inside = false;
var tag ='';
var closing = {
xmp:'< \\ / \\s * xmp\\s *>',
脚本:'< \\ / \\s * script \\s *>',
'! - ':' - >'
};
var clean_source = $ .map(lines,function(line){
if(inside&& line.match(closing [tag])){
var re = new RegExp '。*('+ closing [tag] +')','i');
line = line.replace(re,$ 1);
inside = false;
} else if(inside){
line ='';
}

if(line.match(/<(script |! - )/)){
tag = RegExp。$ 1;
line = line.replace(/<(script | xmp |! - )[^>] *。*(<(\ /(script | xmp) | $)
var re = new RegExp(closing [tag],'i');
inside =!(re ).test(line);
}
回程线
});

//我们正在寻找的
var nodes = $ .map([1,2,3,4,5,6,7,8,9,10],函数(num){return $('#node'+ num)});

//现在在DOM和源中找到每个所需的节点
var line_numbers = $ .map(nodes,function(node){
var tag = node.attr ('tagName');
var tags = $(tag);
var index = tags.index(node)+ 1;

var count = 0;
for(var i = 0; i< clean_source.length; i ++){
var re = new RegExp('<'+ tag,'gi');
var matches = clean_source [i ] .match(re);
if(matches&& matches.length){
count + = matches.length;
if(count> = index){
console.debug(node,tag,index,count,i);
回来我
}
}
}


返回计数;
});

//保存到结束,以避免影响源html
$('#source_pretty')。html(html);
$('#source_raw')。text(source);
$('#source_clean')。text(clean_source.join('\\\
'));

$ .each(line_numbers,function(){$('#line_number_'+ this).css('background-color','orange');});
},
});

var false_matches = [
< div>,
< div>,
< / div>,
< / DIV> 中
] .join('');

});
< / script>
< / head>
<! - 第三个评论 - >
< body id =node2>
< div>
< pre id =source_pretty>
< / pre>
< pre id =source_raw>
< / pre>
< pre id =source_clean>
< / pre>
< / div>

< div id =node3>
< xmp>
< code>
//< xmp>已被弃用,您应该将其放在< code>而是
< / code>
< / xmp>
< / div>

<! - 第四个评论 - >
< div>< div>< div>< div>< div>< div>< span>< div id =node4>< span>< span> < b取代;< EM>
< strong>< pre>< / pre>< / strong>< / i>< div>< div id =node5>< div>< ; / DIV>< / DIV>< / DIV>< / EM>
< / b>< / span>< span>< span id =node6>< / span>< / span>< / span>< / div>< /跨度>< / DIV>< / DIV>< / DIV>< / DIV>< / DIV>< / DIV>


< div>
< div>
< div id =node7>
< div>
< div>
< div id =node8>
< span>
<! - 第五评论 - >
< div>
< span>
< span>
< b>
< em id =node9>
< i>
< strong>
< pre>
< / pre>
< / strong>
< / i>
< div>
< div>
< div>
< / div>
< / div>
< / div>
< / em>
< / b>
< / span>
< span>
< span id =node10>
< / span>
< / span>
< / span>
< / div>
< / span>
< / div>
< / div>
< / div>
< / div>
< / div>
< / div>
< / body>
< / html>


Though I've never heard of this but, is it possible to retrieve a node from the DOM using JS, and then find out on what line of the file that node occurred on?

I'm open to anything, alternative browsers plugins/add-ons etc...it doesn't need to be cross-browser per say.

I would assume that this would be possible somehow considering that some JS debuggers are capable of finding the line number within a script tag, but I'm not entirely sure.

解决方案

Ok, forgive me for how large this is. I thought this was a very interesting question but while playing with it, I quickly realized that innerHTML and its ilk are quite unreliable wrt maintaining whitespace, comments, etc. With that in mind, I fell back to actually pulling down a full copy of the source so that I could be absolutely sure I got the full source. I then used jquery and a few (relatively small) regexes to find the location of each node. It seems to work well although I'm sure I've missed some edge cases. And, yeah, yeah, regexes and two problems, blah blah blah.

Edit: As an exercise in building jquery plugins, I've modified my code to function reasonably well as a standalone plugin with an example similar to the html found below (which I will leave here for posterity). I've tried to make the code slightly more robust (such as now handling tags inside quoted strings, such as onclick), but the biggest remaining bug is that it can't account for any modifications to the page, such as appending elements. I would need probably need to use an iframe instead of an ajax call to handle that case.

<html>
    <head id="node0">
    <!-- first comment -->
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
        <style id="node1">
/*          div { border: 1px solid black; } */
            pre { border: 1px solid black; }
        </style>
    <!-- second comment -->
        <script>
            $(function() {

                // fetch and display source
                var source;
                $.ajax({
                    url: location.href,
                    type: 'get',
                    dataType: 'text',
                    success: function(data) {
                        source = data;


                        var lines = data.split(/\r?\n/);
                        var html = $.map(lines, function(line, i) {
                            return ['<span id="line_number_', i, '"><strong>', i, ':</strong> ', line.replace(/</g, '&lt;').replace(/>/g, '&gt;'), '</span>'].join('');
                        }).join('\n');

                        // now sanitize the raw html so you don't get false hits in code or comments
                        var inside = false;
                        var tag = '';
                        var closing = {
                            xmp: '<\\/\\s*xmp\\s*>',
                            script: '<\\/\\s*script\\s*>',
                            '!--': '-->'
                        };
                        var clean_source = $.map(lines, function(line) {
                            if (inside && line.match(closing[tag])) {
                                var re = new RegExp('.*(' + closing[tag] + ')', 'i');
                                line = line.replace(re, "$1");
                                inside = false;
                            } else if (inside) {
                                line = '';
                            }

                            if (line.match(/<(script|!--)/)) {
                                tag = RegExp.$1;
                                line = line.replace(/<(script|xmp|!--)[^>]*.*(<(\/(script|xmp)|--)?>)/i, "<$1>$2");
                                var re = new RegExp(closing[tag], 'i');
                                inside = ! (re).test(line);
                            }
                            return line;
                        });

                        // nodes we're looking for
                        var nodes = $.map([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(num) { return $('#node' + num) });

                        // now find each desired node in both the DOM and the source
                        var line_numbers = $.map(nodes, function(node) {
                            var tag = node.attr('tagName');
                            var tags = $(tag);
                            var index = tags.index(node) + 1;

                            var count = 0;
                            for (var i = 0; i < clean_source.length; i++) {
                                var re = new RegExp('<' + tag, 'gi');
                                var matches = clean_source[i].match(re);
                                if (matches && matches.length) {
                                    count += matches.length;
                                    if (count >= index) {
                                        console.debug(node, tag, index, count, i);
                                        return i;
                                    }
                                }
                            }


                            return count;
                        });

                        // saved till end to avoid affecting source html
                        $('#source_pretty').html(html);
                        $('#source_raw').text(source);
                        $('#source_clean').text(clean_source.join('\n'));

                        $.each(line_numbers, function() { $('#line_number_' + this).css('background-color', 'orange'); });
                    },
                });

                var false_matches = [
                    "<div>",
                    "<div>",
                    "</div>",
                    "</div>"
                ].join('');

            });
        </script>
    </head>
    <!-- third comment -->
    <body id="node2">
        <div>
            <pre id="source_pretty">
            </pre>
            <pre id="source_raw">
            </pre>
            <pre id="source_clean">
            </pre>
        </div>

        <div id="node3">
            <xmp>
                <code>
                // <xmp> is deprecated, you should put it in <code> instead
                </code>
            </xmp>
        </div>

    <!-- fourth comment -->
<div><div><div><div><div><div><span><div id="node4"><span><span><b><em>
<i><strong><pre></pre></strong></i><div><div id="node5"><div></div></div></div></em>
</b></span><span><span id="node6"></span></span></span></div></span></div></div></div></div></div></div>


        <div>
            <div>
                <div id="node7">
                    <div>
                        <div>
                            <div id="node8">
                                <span>
    <!-- fifth comment -->
                                    <div>
                                        <span>
                                            <span>
                                                <b>
                                                    <em id="node9">
                                                        <i>
                                                            <strong>
                                                                <pre>
                                                                </pre>
                                                            </strong>
                                                        </i>
                                                        <div>
                                                            <div>
                                                                <div>
                                                                </div>
                                                            </div>
                                                        </div>
                                                    </em>
                                                </b>
                                            </span>
                                            <span>
                                                <span id="node10">
                                                </span>
                                            </span>
                                        </span>
                                    </div>
                                </span>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </body>
</html>

这篇关于在Javascript中找出dom中的一个元素的行号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆