Can't select div with id=“:1”

2020-05-07 02:46发布

问题:

Kind of a noob to web stuff, but I have a div which has this tag:

<div class="" id=":1" role="treeitem" aria-selected="false" aria-expanded="false" aria-level="1" aria-labelledby=":1.label" aria-setsize="10" aria-posinset="1">

I've tested that my jQuery is working (currently using version 2.1.3). I've tested the recommended selectors from the numerous other SO posts about colons in selectors and then some others. I've tried each of the jQuery calls below separately, and none have actually hidden the element I'm trying to get.

$(function() {
  $("#\\:1").hide();
  $("#\:1").hide();
  $(":1").hide();
  $("\3A1").hide();
  $("\3a1").hide();
  $("\3A 1").hide();
  $("\3a 1").hide();
  $('[aria-labelledby="\\:1.label"]').hide();
  $('[aria-labelledby="\\:1.label"] *').hide();

  $(document.getElementById(":1")).hide();
  $(document.getElementById("\:1")).hide();
});

Either nothing happens or I get a syntax error for the above calls.

Chrome says the CSS path is '#\3a 1' by the way.

EDIT This works:

$(function() {
  setTimeout(function() {
    $("#\\:1").hide();
  }, 1000);
});

I guess the problem is that the div isn't actually loaded or something. This is still a problem because the solution above is flawed for obvious reasons. I will ask the Google Group for this API (it's blockly), and maybe there is a callback for when this has loaded or something.

EDIT

Total noob mistake--the content I was looking for is actually inserted in an init function. That's why it's not there at the time I normally called my jQuery; I instead needed to put it here:

init = function() {

  Blockly.inject(document.getElementById('blocklyDiv'),
      {toolbox: document.getElementById('toolbox')});
  Blockly.Xml.domToWorkspace(Blockly.mainWorkspace,
      document.getElementById('startBlocks'));
  $("#\\:1").hide();
}

回答1:

:1 is a completely valid id attribute in HTML5:

The id attribute specifies its element's unique identifier (ID).

The value must be unique amongst all the IDs in the element's home subtree and must contain at least one character. The value must not contain any space characters.

However, it may need some escaping.

CSS - CSS ID selector

In CSS, to get an element by its ID, use the ID selector:

The ID attribute of a document language allows authors to assign an identifier to one element instance in the document tree. CSS ID selectors match an element instance based on its identifier. A CSS ID selector contains a "#" immediately followed by the ID value, which must be an identifier.

However, :1 is not a valid identifier:

In CSS, identifiers (including element names, classes, and IDs in selectors) can contain only the characters [a-zA-Z0-9] and ISO 10646 characters U+00A0 and higher, plus the hyphen (-) and the underscore (_); they cannot start with a digit, two hyphens, or a hyphen followed by a digit. Identifiers can also contain escaped characters and any ISO 10646 character as a numeric code (see next item). For instance, the identifier "B&W?" may be written as "B\&W\?" or "B\26 W\3F".

Therefore, you can't use the selector #:1, but you can escape it as #\:1.

#\:1 {
    /* CSS styles */
}

JavaScript - CSS ID selector

In JavaScript, you can use document.querySelector to get the (first) element that matches a CSS selector. The same applies to jQuery.

You can use CSS.escape [warning - experimental technology] to escape the string to make it a valid CSS identifier:

document.querySelector("#" + CSS.escape(":1"));

Alternatively, you can use #\:1 directly. However, note that in JavaScript string literals, the character \ escapes characters, so "#\:1" becomes "#:1". Therefore, you must escape \ with another \:

document.querySelector("#\\:1");

Note that, even if you use CSS.escape, if the ID contained \ or quotes, you would have to escape them in the string literal too.

JavaScript - ID

But JavaScript also has document.getElementById, a faster and simpler way than CSS selectors.

It gets an element directly by its ID, not a CSS escaped version:

document.getElementById(":1");

Note that if the ID contained \ or quotes, you would have to escape them in the string literal.



回答2:

Quote from the official documentation for HTML4:

ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".").

An ID starting with : is invalid. Some browser MAY be able to use it, but you shouldn't count on it. Start your ID with letters only.

In HTML5 this string is allowed, and since you are specifying your document as HTML5 this seems not to be the problem.

I'll still leave the answer here, maybe it helps someone with a similar problem.