Sử dụng querySelector với ID là số


94

Theo những gì tôi hiểu, thông số kỹ thuật HTML5 cho phép bạn sử dụng ID là những con số như thế này.

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

Tôi có thể truy cập những thứ tốt bằng cách sử dụng getElementByIdnhưng không với querySelector. Nếu tôi cố gắng làm như sau, tôi nhận được SyntaxError: DOM Exception 12 trong bảng điều khiển.

document.querySelector("#1")

Tôi chỉ tò mò tại sao việc sử dụng số làm ID không hoạt động querySelectorkhi thông số kỹ thuật HTML5 cho biết những số này hợp lệ. Tôi đã thử nhiều trình duyệt.


1
Tôi không nghĩ rằng thông số kỹ thuật HTML5 nói rằng chúng hợp lệ. Tôi sẽ kiểm tra lại ...
beautifulcoder vào

3
@beautifulcoder Họ là hợp lệ
dsgriffin

1
Đừng bận tâm, theo validator.w3.org/check , việc sử dụng số là hợp lệ. Có thể các trình duyệt hiện đại chưa thực hiện đúng tiêu chuẩn?
beautifulcoder

Câu trả lời:


108

Nó hợp lệ, nhưng yêu cầu một số xử lý đặc biệt. Từ đây: http://mathiasbynens.be/notes/css-escapes

Chữ số hàng đầu

Nếu ký tự đầu tiên của mã định danh là số, bạn sẽ cần phải thoát nó dựa trên điểm mã Unicode của nó. Ví dụ: điểm mã cho ký tự 1 là U + 0031, vì vậy bạn sẽ thoát nó thành \ 000031 hoặc \ 31.

Về cơ bản, để thoát khỏi bất kỳ ký tự số nào, chỉ cần thêm tiền tố \ 3 và thêm ký tự khoảng trắng (). Yay Unicode!

Vì vậy, mã của bạn sẽ kết thúc là (CSS đầu tiên, JS thứ hai):

#\31  {
    background: hotpink;
}

document.getElementById('1');
document.querySelector('#\\31 ');

Cú pháp sẽ là gì cho các giá trị lớn hơn 9? Tôi không thể có được điều này để làm việc với ID như 10
Berry Xanh

5
Bạn cần một không gian sau khi ký tự đầu tiên: #\\31 0- bạn có thể tham khảo mothereffingcssescapes.com
Dennis

Cảm ơn bạn đã theo dõi và liên kết!
Berry Blue

1
Lưu ý rằng khoảng trắng chỉ cần thiết nếu một ký tự là chữ số hex ngay sau chuỗi thoát, để phân biệt ký tự đó với chuỗi thoát. Xem w3.org/TR/CSS21/syndata.html#characters để biết thêm chi tiết.
BoltClock

84

Bởi vì trong khi chúng hợp lệ trong thông số kỹ thuật HTML5, chúng không hợp lệ trong CSS, đó là ý nghĩa của " bộ chọn truy vấn ".

Thay vào đó, bạn sẽ phải làm điều này:, điều này document.querySelector("[id='1']")rất dài dòng khi bạn có thể cung cấp cho nó một ID có ý nghĩa như message1hoặc một cái gì đó;)


1
Bạn không cần "phải" - có một cách để sử dụng bộ chọn id có chữ số đứng đầu. Tôi đồng ý rằng tốt hơn là nên có một id có ý nghĩa.
Dennis

9
UUID có thể bắt đầu bằng một số.
Alfonso Nishikawa

20

Tôi cần một cách tiếp cận được tự động hóa. Một thay đổi gần đây có nghĩa là các giá trị id được sử dụng không còn là các ký tự chữ cái đơn giản và bao gồm các số và ký tự đặc biệt.

Tôi đã kết thúc bằng cách sử dụng CSS.escape: https://developer.mozilla.org/en-US/docs/Web/API/CSS/escape

console.log(CSS.escape('1'));

Đầu tiên, đây là trường hợp thất bại:

const theId = "1";
document.querySelector(`#${theId}`);
const el = document.querySelector(`#${theId}`);
el.innerHTML = "After";
<div id="1">Before</div>

Và hiện đang sử dụng CSS.escape:

const theId = "1";
const el = document.querySelector(`#${CSS.escape(theId)}`);
el.innerHTML = "After";
<div id="1">Before</div>

Xem cách nó thay đổi chính xác để hiển thị After, chứng tỏ bộ chọn đã hoạt động!


Cho đến ngày nay, khi bạn cần đối phó với một số id lạ mà bạn không kiểm soát, đây là giải pháp sạch sẽ nhất, cũng vì điều này được hỗ trợ bởi tất cả các trình duyệt hiện đại.
LasaleFamine

3

Từ tài liệu W3C Cú pháp bộ chọn thuộc tính

Giá trị thuộc tính phải là chuỗi hoặc mã nhận dạng CSS hợp lệ.

Do đó, các chữ số hoặc chuỗi chữ và số có chữ số đứng đầu không đủ điều kiện là số nhận dạng hợp lệ.

Nếu bạn đang sử dụng tiện ích tạo ID để tạo số nhận dạng, bạn có thể kết thúc với các id số alpha với các chữ số đứng đầu.

Cách khắc phục nhanh chóng là bỏ qua các chữ số từ SEED của trình tạo (nếu nó có thể được sửa đổi) hoặc luôn thêm một chuỗi vào id được tạo.


2

Đây là một chức năng mà tôi đã thực hiện vừa rồi để xử lý các ID số hàng đầu trong bộ chọn CSS và nó an toàn cho IE vì CSS.escape thì không.

Chuyển bộ chọn qua chức năng CleanSelector này trước khi sử dụng nó:

var cleanSelector = function(selector){
    (selector.match(/(#[0-9][^\s:,]*)/g) || []).forEach(function(n){
        selector = selector.replace(n, '[id="' + n.replace("#", "") + '"]');
    });
    return selector;
};

var myselector = ".dog #980sada_as div span#aside:hover div.apple#05crab:nth-of-type(2), .ginger #2_green_div, div.cupcake #darwin p#23434-346365-53453";

var clean_myselector = cleanSelector(myselector);

// print to show difference
console.log(myselector);
console.log(clean_myselector);

//use the new selector like normal
var elems = document.querySelectorAll( clean_myselector ); 


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.