2012-07-31 9 views
7

En los navegadores modernos, jQuery utiliza document.querySelectorAll() para aumentar el rendimiento cuando se usan selectores CSS válidos. Se recurre a Sizzle si un navegador no admite el selector o el método document.querySelectorAll().¿Puedo forzar a jQuery a utilizar Sizzle para evaluar un selector sin usar selectores no estándar?

Sin embargo, siempre me gustaría utilizar Sizzle en lugar de la implementación nativa al depurar un selector personalizado. A saber, estoy tratando de llegar a una implementación de :nth-last-child(), one of the CSS3 selectors that are not supported by jQuery. Dado que este selector es compatible de forma nativa con los navegadores modernos, funciona como se describe en la pregunta vinculada. Sin embargo, es precisamente este comportamiento el que interfiere con la depuración de mi selector personalizado, así que me gustaría evitarlo.

Un truco barato que puedo usar es introducir un jQuery selector extension no estándar, lo que "invalida" el selector por así decirlo. Por ejemplo, suponiendo que todos los li:nth-last-child(2) es visible, puedo caer simplemente en que, convirtiendo esto:

$('li:nth-last-child(2)').css('color', 'red'); 

En esto:

$('li:nth-last-child(2):visible').css('color', 'red'); 

Esto hace que sea evaluada siempre por chisporroteo. Excepto, esto requiere que haga una suposición de mis elementos de página que pueden o no ser cierta. Y realmente no me gusta eso. Sin mencionar, no me gusta usar selectores no estándar en general a menos que sea absolutamente necesario.

¿Hay una manera de saltarse el document.querySelectorAll() método nativo en los navegadores que lo soportan y la fuerza jQuery para usar chisporroteo para evaluar un selector de cambio, que preferentemente no emplean el uso de selectores no estándar? Probablemente, esto implica llamar a otro método en lugar de $(), pero es mucho mejor que un selector de hackeo de IMO.

+0

Si se trata de depurar, podría tratar de sobrescribir o eliminar la función document.querySelectorAll() tal vez. – jholloman

+0

+1 por intentar esto. Awesome :) – Spudley

+0

No lo intenté: https://github.com/cowboy/jquery-misc/blob/master/jquery.ba-nth-last-child.js – thirtydot

Respuesta

9

Se podía ponerlo en null antes de cargar jQuery por lo que piensa que no es soportada:

document.querySelectorAll = null; 
//load jquery, will trigger not supported branch 
//Optionally restore QSA here (save a reference) if needed 

Esto se supone que hace this evaluar a false

Demostración: http://jsbin.com/asipil/2/edit

comentario a cabo la línea null y vuelva a ejecutar, y verá que se volverá roja.

+0

Otro caso de algo tan obvio que * alguien más * tiene que señalarlo a mí. No puedo creer que lo haya echado de menos :) Me olvidé de mencionar que preferiría dejar también la implementación nativa sola, pero si no hay otra solución, entonces creo que esto tendrá que ver. – BoltClock

+0

¿Funciona? ¿Los navegadores permiten anular esta propiedad y, en caso afirmativo, todos? * editar: * Parece que funciona en Chrome al menos. –

+0

@FelixKling sí, he usado este truco para algunos casos extremos – Esailija

0

Parece ser que jQuery.find está predeterminado para chisporrotear. Esto le evitará destruir su entorno al establecer una función nativa en nulo.

https://github.com/jquery/jquery/blob/master/src/sizzle-jquery.js#L3

Por lo que debe ser capaz de hacer lo siguiente y siempre pasará por chisporroteo.

$.find('li:nth-last-child(2)') 
+0

Si la prueba 'document.querySelectorAll' se evalúa como' verdadera', 'Sizzle' tiene ha sido sobrescrito antes de esta asignación. Ver view-source: http: //code.jquery.com/jquery-1.7.2.js línea 5093 – Esailija

+0

El método 'Sizzle' al que se hace referencia en esa línea contiene las llamadas nativas antes de volver a su implementación interna (I ' Supongo que esta es la implementación sobrescrita @Esailija se refiere a). Comience [aquí] (https://github.com/jquery/sizzle/blob/master/sizzle.js#L185). Hice un [violín] (http://jsfiddle.net/BoltClock/mPJge) y, de hecho, muestra ': nth-last-child()' trabajando por lo que todavía está usando el método nativo. – BoltClock

+0

¿Puedes señalar dónde exactamente está haciendo la distinción? La única referencia a 'querySelectorAll' es desde 1316 hacia abajo, y no veo nada que le indique que use' querySelectorAll' si falla una afirmación. https://github.com/jquery/sizzle/blob/master/sizzle.js#L1316 – travis

3

Como usted mismo está desarrollando el código para el selector, ¿no podría simplemente darle un nombre personalizado para la duración del ciclo de desarrollo? Tal vez darle su propio prefijo de proveedor o algo así? -bolt-nth-last-child()

De esta manera, sabrá que el navegador definitivamente no lo soportará, por lo que siempre debería caer en el uso de Sizzle.

Cuando haya terminado con el ciclo de desarrollo, puede soltar el prefijo -bolt-.

Sé que es más una solución alternativa que una respuesta a la pregunta, pero parece ser la solución más simple para mí.

+1

+1 para la creatividad! – BoltClock

Cuestiones relacionadas