tag solucionar name ejemplo como javascript internet-explorer-8 shim dom4

javascript - solucionar - title css



navegador cruz comparar posiciĆ³n del documento (2)

DOM4 compareDocumentPosition

Quiero implementar compareDocumentPosition. Resig ha tenido un gran comienzo al hacer esto . He tomado su código y lo he ordenado

function compareDocumentPosition(other) { var ret = 0; if (this.contains) { if (this !== other && this.contains(other)) { ret += 16; } if (this !== other && other.contains(this)) { ret += 8; } if (this.sourceIndex >= 0 && other.sourceIndex >= 0) { if (this.sourceIndex < other.sourceIndex) { ret += 4; } if (this.sourceIndex > other.sourceIndex) { ret += 2; } } else { ret += 1; } } return ret; }

Esto funciona para Element pero no para Text o DocumentFragment . Esto se debe a que IE8 no da .sourceIndex en esos nodos. (No da .contains tampoco, pero ya he solucionado ese problema)

¿Cómo se escriben eficientemente los bits +=4 y +=2 que corresponden a DOCUMENT_POSITION_FOLLOWING y DOCUMENT_POSITION_PRECEDING ?

Para una referencia adicional, esos dos están definidos por orden de árbol, que DOM4 define como

Un objeto A está precediendo a un objeto B si A y B están en el mismo árbol y A aparece antes que B en orden de árbol.

Un objeto A está siguiendo a un objeto B si A y B están en el mismo árbol y A viene después de B en orden de árbol.

El orden de árbol es preordenar, recorrido transversal en profundidad.

La mayoría de los navegadores modernos implementan esto (incluido IE9). Así que solo necesitas algo que funcione en IE8 (no me importa IE6 / 7, ¡pero si funciona genial!)


function recursivelyWalk(nodes, cb) { for (var i = 0, len = nodes.length; i < len; i++) { var node = nodes[i]; var ret = cb(node); if (ret) { return ret; } if (node.childNodes && node.childNodes.length) { var ret = recursivelyWalk(node.childNodes, cb); if (ret) { return ret; } } } } function testNodeForComparePosition(node, other) { if (node === other) { return true; } } function compareDocumentPosition(other) { function identifyWhichIsFirst(node) { if (node === other) { return "other"; } else if (node === reference) { return "reference"; } } var reference = this, referenceTop = this, otherTop = other; if (this === other) { return 0; } while (referenceTop.parentNode) { referenceTop = referenceTop.parentNode; } while (otherTop.parentNode) { otherTop = otherTop.parentNode; } if (referenceTop !== otherTop) { return Node.DOCUMENT_POSITION_DISCONNECTED; } var children = reference.childNodes; var ret = recursivelyWalk( children, testNodeForComparePosition.bind(null, other) ); if (ret) { return Node.DOCUMENT_POSITION_CONTAINED_BY + Node.DOCUMENT_POSITION_FOLLOWING; } var children = other.childNodes; var ret = recursivelyWalk( children, testNodeForComparePosition.bind(null, reference) ); if (ret) { return Node.DOCUMENT_POSITION_CONTAINS + Node.DOCUMENT_POSITION_PRECEDING; } var ret = recursivelyWalk( [referenceTop], identifyWhichIsFirst ); if (ret === "other") { return Node.DOCUMENT_POSITION_PRECEDING; } else { return Node.DOCUMENT_POSITION_FOLLOWING; } }

Lo escribí yo mismo. Pensé que esta implementación tenía errores, pero era un error en algún otro código mío. Parece bastante sólido.


La respuesta de Raynos es un buen comienzo, pero no se puede ejecutar de forma inmediata. Node.* No se puede encontrar y .bind no está disponible en IE8.

Aquí está el código listo para usar en Internet Explorer 8:

function recursivelyWalk(nodes, cb) { for (var i = 0, len = nodes.length; i < len; i++) { var node = nodes[i]; var ret = cb(node); if (ret) { return ret; } if (node.childNodes && node.childNodes.length) { var ret = recursivelyWalk(node.childNodes, cb); if (ret) { return ret; } } } } function testNodeForComparePosition(node, other) { if (node === other) { return true; } } var DOCUMENT_POSITION_DISCONNECTED = 1; var DOCUMENT_POSITION_PRECEDING = 2; var DOCUMENT_POSITION_FOLLOWING = 4; var DOCUMENT_POSITION_CONTAINS = 8; var DOCUMENT_POSITION_CONTAINED_BY = 16; function compareDocumentPosition(thisNode, other) { function identifyWhichIsFirst(node) { if (node === other) { return "other"; } else if (node === reference) { return "reference"; } } var reference = thisNode, referenceTop = thisNode, otherTop = other; if (this === other) { return 0; } while (referenceTop.parentNode) { referenceTop = referenceTop.parentNode; } while (otherTop.parentNode) { otherTop = otherTop.parentNode; } if (referenceTop !== otherTop) { return DOCUMENT_POSITION_DISCONNECTED; } var children = reference.childNodes; var ret = recursivelyWalk( children, function(p) { (function() { var localOther = other; return testNodeForComparePosition(localOther, p); })(); } ); if (ret) { return DOCUMENT_POSITION_CONTAINED_BY + DOCUMENT_POSITION_FOLLOWING; } var children = other.childNodes; var ret = recursivelyWalk( children, function(p) { (function() { var localOther = reference; return testNodeForComparePosition(localOther, p); })(); } ); if (ret) { return DOCUMENT_POSITION_CONTAINS + DOCUMENT_POSITION_PRECEDING; } var ret = recursivelyWalk( [referenceTop], identifyWhichIsFirst ); if (ret === "other") { return DOCUMENT_POSITION_PRECEDING; } else { return DOCUMENT_POSITION_FOLLOWING; } }

Lo llamas así:

compareDocumentPosition(sourceElement, elementToTest)

(Es como llamar a sourceElement.compareDocumentPosition(elementToTest) )