Questo è in realtà un bug, non c'è motivo per cui Sizzle debba rimanere nel nodo di contesto, lo fa solo perché non si sta pulendo dopo aver impostato una variabile temporanea. Ho archiviato uno issue for it, risolto, eseguito tutti i test Sizzle e fatto una richiesta di pull.
Se si vuole correggere la vostra copia esistente di jQuery o Sizzle:
Aprire il jQuery o Sizzle file di
Cercare il matcherFromTokens
funzione di
Trova questo codice al suo interno (vicino alla cima):
matchers = [ function(elem, context, xml) {
return (!leadingRelative && (xml || context !== outermostContext)) || (
(checkContext = context).nodeType ?
matchContext(elem, context, xml) :
matchAnyContext(elem, context, xml));
} ];
Modificare il return
-var rv =
, e aggiungere checkContext = undefined;
e poi return rv;
alla fine della funzione anonima, ad es .:
matchers = [ function(elem, context, xml) {
var ret = (!leadingRelative && (xml || context !== outermostContext)) || (
(checkContext = context).nodeType ?
matchContext(elem, context, xml) :
matchAnyContext(elem, context, xml));
// Release the context node (issue #299)
checkContext = null;
return ret;
} ];
Nota: Questo codice assegna null
per checkContext
perché a quanto pare questo è il loro stile. Se fossi in me, avrei assegnato lo undefined
.
Se c'è qualche problema con la correzione sollevata durante il processo di richiesta/fusione, aggiornerò la risposta.
È meglio continuare a lasciare selettori di cache Sizzle, perché jQuery usa il selettore compilato con la delega degli eventi e non si vuole davvero che debba ripetere e ricostruire le funzioni di matcher ogni volta che si verifica un evento rilevante in modo che possa capire se gli elementi corrispondono.
Questo non è l'unico posto che jQuery conserva sugli elementi nei selettori compilati, sfortunatamente. Ogni posto che fa è probabilmente un bug che potrebbe usare il fixing.Ho solo avuto il tempo di rintracciare un altro, che ho anche segnalato e risolto (in attesa della richiesta di pull essere atterrato):
Se si cerca "pseudos potenzialmente complesse" troverete questo per la :not
pseudo-selettore:
pseudos: {
// Potentially complex pseudos
"not": markFunction(function(selector) {
// Trim the selector passed to compile
// to avoid treating leading and trailing
// spaces as combinators
var input = [],
results = [],
matcher = compile(selector.replace(rtrim, "$1"));
return matcher[ expando ] ?
markFunction(function(seed, matches, context, xml) {
var elem,
unmatched = matcher(seed, null, xml, []),
i = seed.length;
// Match elements unmatched by `matcher`
while (i--) {
if ((elem = unmatched[i])) {
seed[i] = !(matches[i] = elem);
}
}
}) :
function(elem, context, xml) {
input[0] = elem;
matcher(input, null, xml, results);
return !results.pop();
};
}),
il problema è in funzione, dopo l':
nell'operatore condizionale:
function(elem, context, xml) {
input[0] = elem;
matcher(input, null, xml, results);
return !results.pop();
};
noti che non cancella input[0]
. Ecco la soluzione:
function(elem, context, xml) {
input[0] = elem;
matcher(input, null, xml, results);
// Don't keep the element (issue #299)
input[0] = null;
return !results.pop();
};
Questo è tutto quello che ho il tempo di rintracciare al momento.
Quindi, stai dicendo che solo la funzione matcher doveva essere memorizzata nella cache? Non l'intero risultato? Questo è il motivo per cui non l'ho segnalato, ho pensato che Sizzle stia memorizzando nella cache i nodi DOM di proposito. –
@KonradDzwinel: Giusto. L'array di funzioni è la parte che deve essere riusabile. Per quanto ne so, 'checkContext' è solo una variabile temporanea, usata in modo che' matchContext' e 'matchAnyContext' abbiano accesso ad essa quando la funzione anonima sopra li chiama (suppongo che non possa passarli a loro per alcuni ragionare). Non è necessario mantenere l'elemento di contesto dopo che la corrispondenza è stata eseguita (e ogni esigenza * non * a). Ero davvero sorpreso che la soluzione fosse così semplice, pensavo che avremmo dovuto aspettare e chiarirlo molto dopo. Ma tutti i test passano, quindi vedremo se sopravviverà alla revisione ... –
Questo è enorme per le app SPA che usano jQuery puro (jQlite non usa Sizzle)! Ottimo lavoro e grazie! –