ds390s
ds390s

Reputation: 597

jQuery Escaping Special Characters Fails

I am trying to make a jQuery selector to select, by an arbitrary id, an html element. The ids may contains special characters that need to be escaped. An example is test_E///_AAAAA

I am basically doing exactly what is going on in this working fiddle (which uses v 1.11.0, where I am using v 1.11.3 and have also tested with 2.1.3)

However, in my scaled up environment, it doesn't work. I get Syntax error, unrecognized expression: #test_E\\/\\/\\/_AAAAA

There must be some obscure factoid about jQuery that is the difference between this working and not working. I, being a novice, have no hope of identifying it.

I notice that I am not alone though. A commentator on this thread had the same issue.

The code files are thousands of lines long, and I'm probably prohibited from posting more than a couple lines by my employer. I'm just looking for a hint, a clue, a shot in the dark about what would cause a perfectly reasonable selection string to be rejected.

Upvotes: 1

Views: 1169

Answers (2)

Guffa
Guffa

Reputation: 700840

The code in the fiddle doesn't work either. I have tried it in IE, Firefox and Chrome, and neither of them finds the element.

You need to escape a slash to use it in a # selector. If you use a backslash, you have to escape it twice, once to put it in a string, and once for the selector.

To match the id test\A you need the selector #test\\A which as a string is "#test\\\\A".

To match the id test/A you need the selector #test\/A which as a string is "#test\\/A".

To match the id test_E\\/\\/\\/_AAAAA you need the selector #test_E\\\\\/\\\\\/\\\\\/_AAAAA which as a string is "#test_E\\\\\\\\\\/\\\\\\\\\\/\\\\\\\\\\/_AAAAA".

Demo: https://jsfiddle.net/Guffa/463849xj/4/

Generally you should avoid unusual characters in an identity. Even if you can make it work, there is still a risk that some browser handles it differently.

Update:

The error message is shown with the selector unescaped, so as the error message shows the selector #test_E\\/\\/\\/_AAAAA it means that you actually use the string "#test_E\\\\/\\\\/\\\\/_AAAAA". That leaves the slashes unescaped, which causes the syntax error.

Upvotes: 1

tom
tom

Reputation: 22989

You just need enough backslashes :)

ID: The ID of the element is test_E\\/\\/\\/_AAAAA. Note that backslashes don't have any special meaning in HTML, so there really are six backslashes in the ID.

jQuery selector: Backslashes, forward slashes, and several other characters have special meaning in jQuery selectors, so we need to escape them with a backslash. The selector therefore needs to be #test_E\\\\\/\\\\\/\\\\\/_AAAAA. This tells jQuery to look for an element whose ID contains test_E, then two backslashes, then one forward slash, and so on.

JavaScript string literal: To represent that selector using a JavaScript string literal, each backslash needs to be escaped. So the string literal would be "#test_E\\\\\\\\\\/\\\\\\\\\\/\\\\\\\\\\/_AAAAA".

var selectionString = "#test_E\\\\\\\\\\/\\\\\\\\\\/\\\\\\\\\\/_AAAAA";
snippet.log("actual id: " + $("p")[0].id);
snippet.log("selection string given to jQuery: " + selectionString);
snippet.log("text: " + $(selectionString).text());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

<p id="test_E\\/\\/\\/_AAAAA">This is a test :)</p>

As you can see, this is extremely ugly, hard to understand, and hard to get right. I highly recommend avoiding such IDs. Another option is to use good old document.getElementById(), which only requires the string literal escapes:

$(document.getElementById('test_E\\\\/\\\\/\\\\/_AAAAA')).text()

Upvotes: 1

Related Questions