Frage

Obwohl ich habe noch nie davon gehört, aber ist es möglich, einen Knoten aus dem DOM mit JS, abrufen und dann auf herauszufinden, welche Zeile der Datei, dass der Knoten aufgetreten auf?

Ich bin offen für alles, alternativen Browser-Plugins / Add-ons etc ... es muss nicht Cross-Browser pro sagen sein.

Ich würde davon ausgehen, dass dies möglich wäre, irgendwie man bedenkt, dass einige JS Debugger sind in der Lage die Zeilennummer in einem Script-Tag zu finden, aber ich bin nicht ganz sicher.

War es hilfreich?

Lösung

Ok, verzeihen Sie mir, wie groß dieser ist. Ich dachte, das eine sehr interessante Frage war aber, während sie mit ihm spielen, habe ich schnell erkannt, dass innerHTML- und seine ilk sind ziemlich unzuverlässig WRT Aufrechterhaltung Leerzeichen, Kommentare usw. Vor diesem Hintergrund fiel ich zurück, um tatsächlich eine vollständige Kopie der nach unten ziehen Quelle so, dass ich absolut sicher sein konnte, habe ich die volle Quelle. Ich habe dann jquery und ein paar (relativ kleinen) Regexes verwendet, um die Position jedes Knotens zu finden. Es scheint gut zu funktionieren, obwohl ich bin sicher, dass ich ein paar Grenzfälle verpasst haben. Und, ja, ja, reguläre Ausdrücke und zwei Probleme, bla bla bla.

Edit: Als eine Übung jquery plugins in den Aufbau, ich meinen Code Funktion recht gut als eigenständiges geändert haben Plugin mit einem Beispiel ähnlich dem html gefunden unten (was ich hier für die Nachwelt hinterlassen). Ich habe versucht, den Code etwas robusten (wie jetzt Umgang mit Tags in Anführungszeichen, wie Onclick) zu machen, aber der größte verbleibende Fehler ist, dass es nicht für Änderungen an der Seite, wie Anfügen Elemente ausmachen können. Ich müsste wahrscheinlich brauchen einen Iframe anstelle eines Ajax-Aufruf verwenden, diesen Fall zu behandeln.

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

Andere Tipps

So etwas wie das?

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

Dies kann durchgeführt werden. Beginnen Sie, indem sie den obersten Knoten in dem Dokument wie folgt aus:

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

(Dieser Code wurde getestet und abgerufen sowohl die Doctype Knoten sowie Kommentare über dem HTML-Knoten)

Dann Sie eine Schleife durch alle Knoten (beide Geschwister und Kinder). In IE, sehen Sie nur die Elemente und Kommentare (nicht Textknoten), so ist es am besten sein werde FF oder Chrom oder etwas zu verwenden (sagte man, es wäre nicht Cross-Browser sein müssen).

Wenn Sie erhalten jeweils an Textnode , analysieren sie für Zeilenumbrüche zu suchen.

Sie könnten versuchen: -

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

Nach dem Code, wenn Sie es aus Coz, das ist eine gute Frage Mutter:)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top