for - getelementsbytagname javascript ejemplo
¿Averiguar en qué número de línea aparece un elemento en el dom en Javascript? (4)
Aunque nunca he oído hablar de esto, ¿es posible recuperar un nodo desde el DOM utilizando JS y luego averiguar en qué línea del archivo ocurrió ese nodo?
Estoy abierto a cualquier cosa, complementos / complementos de navegadores alternativos, etc. No es necesario que sea un navegador cruzado por voz.
Supongo que esto sería posible de alguna manera considerando 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.
¿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 puede hacerse. Comience por obtener el nodo más alto en el documento como este:
var htmlNode = document.getElementsByTagName(''html'')[0];
var node = htmlNode;
while (node.previousSibling !== null) {
node = node.previousSibling;
}
var firstNode = node;
(este código se probó y recuperó tanto el nodo doctype como los comentarios sobre el nodo html)
Luego, recorres todos los nodos (hermanos e hijos). En IE, solo verás los elementos y los comentarios (no los nodos de texto), por lo que será mejor usar FF o Chrome o algo así (dijiste que no tendría que ser un navegador cruzado).
Cuando llegue a cada nodo de texto , analícelo para buscar retornos de carro.
Ok, perdóname por lo grande que es esto. Pensé que esta era una pregunta muy interesante, pero mientras jugaba con ella, rápidamente me di cuenta de que innerHTML y su tipo no son muy fiables, ya que mantienen espacios en blanco, comentarios, etc. fuente para que pudiera estar absolutamente seguro de que obtuve la fuente completa. Luego utilicé jquery y algunas expresiones regulares (relativamente pequeñas) para encontrar la ubicación de cada nodo. Parece funcionar bien, aunque estoy seguro de que me he perdido algunos casos. Y, sí, sí, expresiones regulares y dos problemas, bla bla bla.
Edición: Como ejercicio para crear complementos de jQuery, modifiqué mi código para que funcione razonablemente bien como plugin independiente con un example similar al html que se encuentra a continuación (que dejaré aquí para la posteridad). He intentado hacer que el código sea un poco más robusto (como ahora manejar etiquetas dentro de cadenas entre comillas, como onclick), pero el error más grande que queda es que no puede dar cuenta de ninguna modificación a la página, como elementos añadidos. Probablemente necesitaría usar 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, ''<'').replace(/>/g, ''>''), ''</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>
Tu podrías 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.
Publique el código una vez que lo vuelva loco porque esa es una buena pregunta :)