2

So, I am trying to create a game with blocks in the level being send from the server.

I have loop cycling through the blocks each time it recieves an update from the server. It will then if the block is solid, append the block to the html document if it is not already existing.

if(blocks[blockCount].solid === true){
            if($("#" + blocks[blockCount].posX.toString() + "," + blocks[blockCount].posY.toString()).length > 0){
               alert("Block already exists");
            }else{
                $("body").append("<div style='height: " + blockSize + "px;width:  " + blockSize + "px;background-color: blue;position: absolute;display: inline;margin-left: " + blocks[blockCount].posX * blockSize + "px;margin-top: " + blocks[blockCount].posY * blockSize + "px;' id='" + blocks[blockCount].posX.toString() + "," + blocks[blockCount].posY.toString() + "'> </div>");
            }
        }

blocks[blockCount].posX and Y should both equal to 4. But for some reason they keep being created, the if statement does for some reason not work. Can you please explain me why? or post the correct code. Thanks a lot for your help. :)

I learned here: How to check if element exists in the visible DOM?

that the jquery .length would allow me to see if the element already existed.

Community
  • 1
  • 1
Benjadahl
  • 80
  • 1
  • 10

2 Answers2

4

You can't have a , in an ID (or class for that matter) [see comment, you can, but why make life hard for yourself] - because a , is used as a separator in CSS .. i.e

#id1,div would select an element with id="id1" AND any div

you're creating elements with id's like "123,456" - which as a CSS selector would be #123,456

solution: try using _ instead of ,

also, I'm not sure if an id is allowed to begin with numbers, but don't quite me on that, if not, just prepend your id's with x or whatever

note: the HTML5 spec allows ID's to begin with numbers, however, that too does not work in CSS selectors (for CSS at least, not tested with jQuery or querySelector[All] )

you'll end up with id's like x123_456 - which is OK

Jaromanda X
  • 53,868
  • 5
  • 73
  • 87
  • Thanks a lot, this was the problem. If I could give you rep I would. Dosent seem to work though :/ – Benjadahl Aug 02 '15 at 14:59
  • Giving you reputation, the answer was totally fine :) – Benjadahl Aug 02 '15 at 15:04
  • My answer isn't really correct. there are no restrictions on ID's except "space characters" - however, as in my comment on another answer, for ease of use, if possible, just use characters that have no special meaning in CSS selectors, and (my personal restriction) don't need to be escaped in a RegExp - makes life so much easier – Jaromanda X Aug 02 '15 at 15:28
  • Yes, in response to your previous (now deleted) comment, HTML5 allows for more flexibility in `ID` values than HTML4 did. Here's a quick review: http://stackoverflow.com/a/31773673/3597276 – Michael Benjamin Aug 02 '15 at 16:02
1

Since , has a special meaning in CSS, you'd have to escape in in your selector. To write a CSS selector targeting an element with id="foo,bar", you have to write #foo\,bar. In jQuery selector allow you to do the same, but you need to remember about JS syntax and write $("#foo\\,bar") to achieve what you want (the first backslash is to escape the second one in JS string).

Also, as Jaromanda X pointed out, IDs can't start with numbers so you'll have to prepend it with a letter.

To sum up, your code may look like this:

if(blocks[blockCount].solid === true){
    if($("#x" + blocks[blockCount].posX.toString() + "\\," + blocks[blockCount].posY.toString()).length > 0){
       alert("Block already exists");
    } else {
        $("body").append("<div style='height: " + blockSize + "px;width:  " + blockSize + "px;background-color: blue;position: absolute;display: inline;margin-left: " + blocks[blockCount].posX * blockSize + "px;margin-top: " + blocks[blockCount].posY * blockSize + "px;' id='x" + blocks[blockCount].posX.toString() + "," + blocks[blockCount].posY.toString() + "'> </div>");
    }
}
Michał Dudak
  • 4,923
  • 2
  • 21
  • 28
  • actually I'm sort of wrong, the only restriction on ID's in HTML5 is no space characters - `There are no other restrictions on what form an ID can take; in particular, IDs can consist of just digits, start with a digit, start with an underscore, consist of just punctuation, etc.` - http://www.w3.org/TR/html5/dom.html#the-id-attribute ... however, for ease of use, I'd stick to alphanumeric and some punctuation, but not anything that can confuse css selectors (# . , : > and anything else I can't think of right now) - I'd also stay away from characters that have to be escaped in RegExp – Jaromanda X Aug 02 '15 at 15:25
  • Starting an ID with a digit seems not to work (at least in Chrome): http://jsbin.com/xukabisevu/edit?html,css,output – Michał Dudak Aug 02 '15 at 15:29
  • I wouldn't be surprised, however as you can see, the HTML5 spec does allow it (doesn't mean every browser will - firefox also fails your redfoo test) – Jaromanda X Aug 02 '15 at 15:30
  • As we all know the spec may sometimes be very far from what's implemented in the browsers :) – Michał Dudak Aug 02 '15 at 15:32
  • In my case starting with a number didnt create any problems so far. – Benjadahl Aug 02 '15 at 15:34
  • That's interesting, jQuery handles digit-prefixed IDs well. CSS does not. – Michał Dudak Aug 02 '15 at 15:38
  • the fact that it doesn't work with CSS, but `document.getElementById` works, and `document.querySelector` does NOT - so, is that a fail or pass? – Jaromanda X Aug 02 '15 at 15:38
  • For me it's a clear hint not to have IDs starting with digits to potentially avoid spending some time in the future trying to figure out why my styles are broken, – Michał Dudak Aug 02 '15 at 15:44
  • Well, thanks anyways for letting me know that you can add "," anyways. But in a special way :) – Benjadahl Aug 02 '15 at 20:12
  • I did try to upvote it. But I dont have 15 reputation yet. Have 13 now, will do when I get to 15 :) – Benjadahl Aug 03 '15 at 10:36