5

I wonder why jQuery doesn't allow "+" sign. Here is an example of how it works with "1" and "3" but not with "2+". Just mouse-over the text above every div.

<div id="div-2+"></div>

JSFiddle

$('a.hover').mouseover(function() {

    dataI = $(this).data('i');

 $('div#div-' + dataI).addClass('h');

});

$('a.hover').mouseout(function() {

    dataI = $(this).data('i');

 $('div#div-' + dataI).removeClass('h');

});
a {
    display: inline-block;
    width: 100px;
    margin: 60px 20px 60px 0;
    text-align: center;
}

div {
    display: inline-block;
    width: 100px;
    height: 100px;
    margin-right: 20px;
    background-color: #ddd;
}

div.h {
    background-color: #f00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<a class="hover" data-i="1">DIV 1</a>

<a class="hover" data-i="2+">DIV 2+</a>

<a class="hover" data-i="3">DIV 3</a>

<br />

<div id="div-1"></div>

<div id="div-2+"></div>

<div id="div-3"></div>
Alexander O'Mara
  • 58,688
  • 18
  • 163
  • 171
medk
  • 9,233
  • 18
  • 57
  • 79
  • 1
    I haven't lost too much sleep over this yet – garryp May 11 '15 at 22:26
  • 1
    Please bring the reproducing code here. An off-site link is insufficient. Also, tag JavaScript as such. – Lightness Races in Orbit May 11 '15 at 22:29
  • 1
    See [How do I get jQuery to select elements with a . (period) in their ID?](http://stackoverflow.com/q/350292/218196) – Felix Kling May 11 '15 at 22:38
  • 1
    It sounds like a Very Bad Idea to use the option name to create the option id. What if your user enters the same option name twice? If you save each option to a database, try using `id="id-{{database-id}}"` : it will be both unique and a good value to use as an id. – JK. May 11 '15 at 22:56
  • @JK. I know but here I use one row with 3 fields for option titles and option values: poll-id / "Option 1|-|Option 2|-|Option 3" / "0-0-0" – medk May 11 '15 at 23:20

3 Answers3

10

Most-likely because the plus sign is the adjacent CSS selector, which causes the Sizzle selector library jQuery uses to assume you mean an adjacent selector.

One way around this would be to use an attribute selector, that selects the id attribute. Although many people would argue putting a plus sign in the id is a bad idea.

Working Example:

$('a.hover').mouseover(function() {

    dataI = $(this).data('i');

 $('div[id="div-' + dataI + '"]').addClass('h');

});

$('a.hover').mouseout(function() {

    dataI = $(this).data('i');

 $('div[id="div-' + dataI + '"]').removeClass('h');

});
a {
    display: inline-block;
    width: 100px;
    margin: 60px 20px 60px 0;
    text-align: center;
}

div {
    display: inline-block;
    width: 100px;
    height: 100px;
    margin-right: 20px;
    background-color: #ddd;
}

div.h {
    background-color: #f00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<a class="hover" data-i="1">DIV 1</a>

<a class="hover" data-i="2+">DIV 2+</a>

<a class="hover" data-i="3">DIV 3</a>

<br />

<div id="div-1"></div>

<div id="div-2+"></div>

<div id="div-3"></div>
Alexander O'Mara
  • 58,688
  • 18
  • 163
  • 171
  • Thanks a lot for the answer and for the "+" in the id I know it's bad practice but in my case it's a polls app where people create their own polls with some options to chose from and the id will be the lowercase version of the option. everything goes well until I made a poll asking for the favorite IDE or editor where I put "Notepad++" and got the problem. And even the other options after it are gone from the form submit. It's very hard to discuss that exact point here. – medk May 11 '15 at 22:36
2

Note, "workaround"

Try utilizing css

a {
  display: inline-block;
  width: 100px;
  margin: 60px 20px 60px 0;
  text-align: center;
}

div {
  display: inline-block;
  width: 100px;
  height: 100px;
  margin-right: 20px;
  background-color: #ddd;
}

a.hover[data-i="1"]:hover ~ div[id$="1"],
a.hover[data-i="2+"]:hover ~ div[id$="2+"],
a.hover[data-i="3"]:hover ~ div[id$="3"] {
  background-color: #f00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<a class="hover" data-i="1">DIV 1</a>

<a class="hover" data-i="2+">DIV 2+</a>

<a class="hover" data-i="3">DIV 3</a>

<br />

<div id="div-1" class="hover"></div>

<div id="div-2+" class="hover"></div>

<div id="div-3" class="hover"></div>
guest271314
  • 1
  • 15
  • 104
  • 177
1

@Alexander O'Mara does a nice job of explaining why it doesn't work and shows a decent work-around.

Another work-around is to escape the plus sign by preceding it with a backslash.

dataI = dataI.replace('+', '\\+');

jsfiddle

From the jQuery documentation for Selectors:

To use any of the meta-characters ( such as !"#$%&'()*+,./:;<=>?@[]^`{|}~ ) as a literal part of a name, it must be escaped with with two backslashes: \\. For example, an element with id="foo.bar", can use the selector $("#foo\\.bar"). The W3C CSS specification contains the complete set of rules regarding valid CSS selectors. Also useful is the blog entry by Mathias Bynens on CSS character escape sequences for identifiers.

Also note that document.querySelector() throws the following error when given the selector #div-2+:

SyntaxError: An invalid or illegal string was specified.

jsfiddle

John S
  • 21,212
  • 8
  • 46
  • 56