Averiguar lo que el número de línea de un elemento en el DOM se produce en en Javascript?

StackOverflow https://stackoverflow.com/questions/2044642

  •  20-09-2019
  •  | 
  •  

Pregunta

A pesar de que nunca he oído hablar de esto, pero, ¿es posible recuperar un nodo del DOM utilizando JS, y luego averiguar en qué línea del archivo que se produjo el nodo?

Estoy abierto a cualquier cosa, navegadores alternativos plugins / add-ons, etc ... No tiene por qué ser multi-navegador por la opinión.

Me supongo que esto sería posible alguna manera teniendo en cuenta que algunos depuradores JS son capaces de encontrar el número de línea dentro de una etiqueta de script, pero no estoy del todo seguro.

¿Fue útil?

Solución

Bueno, perdóname por lo grande que es esto. Pensé que esto era una pregunta muy interesante, pero mientras juega con él, me di cuenta rápidamente de que innerHTML y su clase son bastante poco fiable espacios en blanco manteniendo WRT, comentarios, etc. Con esto en mente, me quedé de nuevo a realidad tirando hacia abajo una copia completa de la fuente para que yo pudiera estar absolutamente seguro de que tengo la fuente completa. Luego utiliza jQuery y unos pocos (relativamente pequeño) expresiones regulares para encontrar la ubicación de cada nodo. Parece que funciona bien aunque estoy seguro de que me he perdido algunos casos extremos. Y, sí, sí, expresiones regulares y dos problemas, bla, bla, bla.

Editar Como un ejercicio de plugins jQuery construcción, he modificado mi código para funcionar razonablemente bien como un independiente plugin con un ejemplo similar a la html encontrar a continuación (que voy a salir de aquí para la posteridad). He tratado de hacer que el código ligeramente más robusto (como ahora el manejo de las etiquetas dentro de cadenas entre comillas, como onclick), pero el mayor error que queda es que no puede dar cuenta de cualquier modificación a la página, tales como elementos adjuntas. Yo necesitaría probablemente necesitará utilizar un iframe en lugar de una llamada AJAX para manejar ese caso.

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

Otros consejos

Algo como esto?

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

Esto se puede hacer. Empezar por conseguir el nodo más alto en el documento de la siguiente manera:

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

(este código fue probado y recuperada tanto el nodo DOCTYPE así como los comentarios anteriores el nodo html)

A continuación, recorrer todos los nodos (ambos hermanos e hijos). En IE, sólo verá los elementos y los comentarios (no nodos de texto), por lo que será mejor usar FF o cromo o algo (que dijo que no tendría que ser transversal navegador).

Al llegar a cada texto del nodo , analizarlo en busca de retornos de carro.

Usted podría intentar: -

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

Publicar el código una vez que Nut fuera coz esa es una buena pregunta:)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top