Question

Bien que je ne l'ai jamais entendu parler de cela, mais, est-il possible de récupérer un nœud du DOM en utilisant JS, puis savoir sur quelle ligne du fichier ce nœud a eu lieu le?

Je suis ouvert à tout, plugins navigateurs alternatifs / add-ons, etc ... il n'a pas besoin d'être contre-navigateur par exemple.

Je suppose que ce serait possible, compte tenu d'une certaine manière que certains débogueurs JS sont capables de trouver le numéro de ligne dans une balise de script, mais je ne suis pas tout à fait sûr.

Était-ce utile?

La solution

Ok, pardonnez-moi la taille c'est. Je pensais que c'était une question très intéressante, mais tout en jouant avec elle, je suis vite rendu compte que innerHTML et son acabit sont assez peu fiables espaces blancs maintenant wrt, commentaires, etc. Dans cet esprit, je suis retombé à tirer en fait vers le bas une copie complète de la source afin que je puisse être absolument sûr que je suis la source complète. J'ai ensuite utilisé jquery et quelques (relativement faible) Regexes pour trouver l'emplacement de chaque nœud. Il semble bien fonctionner même si je suis sûr que je l'ai raté quelques cas de pointe. Et, ouais, ouais, Regexes et deux problèmes, bla bla bla.

Modifier comme un exercice de construction plugins jquery, j'ai modifié mon code pour fonctionner raisonnablement bien comme autonome plug-in avec un exemple similaire à la html trouve ci-dessous (que je laisserai ici pour la postérité). J'ai essayé de rendre le code un peu plus robuste (comme la manipulation maintenant des balises dans les chaînes entre guillemets, comme onclick), mais le plus gros bug restant est qu'il ne peut pas tenir compte de toute modification de la page, tels que des éléments annexées. Je aurais besoin probablement besoin d'utiliser un iframe au lieu d'un appel ajax pour gérer ce cas.

<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>

Autres conseils

Quelque chose comme ça?

var wholeDocument = document.getElementsByTagName('html')[0]
var findNode = document.getElementById('whatever')
var documentUpToFindNode = wholeDocument.substr(0, wholeDocument.indexOf(findNode.outerHTML))
var nlsUpToFindNode = documentUpToFindNode.match(/\n/g).length

Cela peut être fait. Commencez par obtenir le plus haut nœud dans le document comme celui-ci:

var htmlNode = document.getElementsByTagName('html')[0];
var node = htmlNode;
while (node.previousSibling !== null) {
    node = node.previousSibling;
}
var firstNode = node;

(ce code a été testé et récupéré à la fois le nœud DOCTYPE ainsi que des commentaires au-dessus du nœud html)

Ensuite, on boucle tous les noeuds (les deux frères et sœurs et enfants). Dans IE, vous ne verrez que les éléments et commentaires (pas de nœuds de texte), donc il sera préférable d'utiliser FF ou chrome ou quelque chose (vous avez dit qu'il ne devait pas être navigateur croix).

Lorsque vous arrivez à chaque noeud texte , l'analyser pour rechercher des retours chariot.

Vous pouvez essayer: -

 - start at the 'whatever' node, 
 - traverse to each previous node back to the doc begining while concatenating the html of each node, 
 - then count the new lines in your collected HTML.

Publier le code une fois que vous NUT dehors coz des thats une bonne question:)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top