2013-03-11 13 views
17

Perché ottengo questo errore e come posso testarlo in modo che non si rompa, ho provato a verificare nulla, ma ovviamente non funzionerà, grazie.Errore di sintassi di Jquery, espressione non riconosciuta:

Per favore non consiglio di non scrivere l'ID come questo, so che è sbagliato ma è una possibilità.

var jsonTest = [ 
    { 
    "myId": "''''''\"\"\"\"'''''''''''''\"#####$'''''", 
    } 
]; 

alert(jsonTest[0].myId); 
// Works - alerts the myId 

$('#' + jsonTest[0].myId).length; 
// Error: Syntax error, unrecognized expression: 
// #''''''""""'''''''''''''"#####$''''' 

risposta

35

jQuery utilizza questo codice per rilevare un selettore basato id:

characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+" 
... 
"ID": new RegExp("^#(" + characterEncoding + ")"), 

Questa regex riesce per "''''''\"\"\"\"'''''''''''''\"#####$'''''" o più semplicemente per "'".

Il motore di query è limitato, il che non è molto sorprendente per un linguaggio così conciso e le regole di validità dell'ID così lassiste. non può gestire alcun ID valido.

Se si ha realmente bisogno di essere in grado di gestire qualsiasi tipo di documento d'identità valido, utilizzare

$(document.getElementById(jsonTest[0].myId)) 

In realtà, non si dovrebbe mai usare $('#'+id) come si aggiunge semplicemente un inutile (e un po 'pericoloso) strato di parsing per la stessa operazione.

+1

Anche i tentativi di fuga potrebbero aiutare. – VisioN

+0

@VisioN Non sarebbe abbastanza. –

+1

Grazie a dystroy questa è una soluzione fantastica –

8

Se ho capito la tua domanda, hai un ID che contiene caratteri speciali. Che, fondamentalmente, need to escape them in modo che siano trattati come caratteri letterali piuttosto che selettori di query:!.

Per utilizzare uno dei meta-caratteri (come "# $% & '() * +,/:; < =>? @ []^`{|} ~) Come parte letterale di un nome, deve essere preceduto da con due backslash: \. Ad esempio, un elemento con id =" foo.bar ", può utilizzare il selettore $ ("# foo \ .bar").

... e in questo caso è anche necessario un livello fuga aggiuntivo per il delimitatore di stringa, ". e 'pazzesco, ma th è opere:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head><title></title> 
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> 
<script type="text/javascript"><!-- 
jQuery(function($){ 
    console.log($("#" + "\\'\\'\\'\\'\\'\\'\\\"\\\"\\\"\\\"\\'\\'\\'\\'\\'\\'\\'\\'\\'\\'\\'\\'\\'\\\"\\#\\#\\#\\#\\#\\$\\'\\'\\'\\'\\'").length); 
}); 
//--></script> 
</head> 
<body> 

<div id="''''''&quot;&quot;&quot;&quot;'''''''''''''&quot;#####$'''''">Foo</div> 

</body> 
</html> 

Edit: Naturalmente, la risposta di dystroy -omit motore di selezione jQuery e utilizzare getElementByID() - è il modo più pratico. manuale jQuery links an interesting blog entry che copre questa e di altre tecniche correlate:

document.getElementById() e funzioni simili come document.getElementsByClassName() può semplicemente utilizzare il valore dell'attributo escape , il modo in cui è usato nel codice HTML. Ovviamente, dovresti sfuggire a qualsiasi virgolette in modo da finire con una stringa JavaScript valida .

1

W3C ha definito una nuova funzione per questo: CSS.escape().Nel codice esempio, sarebbe simile a questa:

var jsonTest = [ 
    { 
    "myId": "''''''\"\"\"\"'''''''''''''\"#####$'''''", 
    } 
]; 

$('#' + CSS.escape(jsonTest[0].myId)).length; // Works 

browser non supportano ancora, ma c'è una biblioteca polyfill che è possibile utilizzare nel frattempo: https://github.com/mathiasbynens/CSS.escape

ho l'ho usato con successo nel mio progetto.

Problemi correlati