การใช้ querySelector กับ ID ที่เป็นตัวเลข


98

จากสิ่งที่ฉันเข้าใจข้อมูลจำเพาะของ HTML5 ช่วยให้คุณใช้ ID ที่เป็นตัวเลขเช่นนี้

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

ฉันสามารถเข้าถึงเหล่านี้ปรับใช้แต่ไม่ได้มีgetElementById querySelectorถ้าฉันลองทำสิ่งต่อไปนี้ฉันจะได้รับSyntaxError: DOM Exception 12ในคอนโซล

document.querySelector("#1")

ฉันแค่อยากรู้ว่าทำไมการใช้ตัวเลขเป็น ID จึงไม่ทำงานquerySelectorเมื่อข้อมูลจำเพาะ HTML5 ระบุว่าถูกต้อง ฉันลองใช้เบราว์เซอร์หลายตัว


1
ฉันไม่คิดว่าข้อมูลจำเพาะของ HTML5 บอกว่าถูกต้อง ฉันจะตรวจสอบอีกครั้ง ...
beautifulcoder


1
ไม่เป็นไรตามvalidator.w3.org/ ตรวจสอบว่าสามารถใช้ตัวเลขได้ บางทีเบราว์เซอร์สมัยใหม่ยังไม่ได้ใช้มาตรฐาน?
beautifulcoder

คำตอบ:


111

ใช้ได้ แต่ต้องมีการจัดการพิเศษ จากที่นี่: http://mathiasbynens.be/notes/css-escapes

เลขนำหน้า

หากอักขระตัวแรกของตัวระบุเป็นตัวเลขคุณจะต้องหลีกเลี่ยงโดยอิงตามจุดรหัส Unicode ตัวอย่างเช่นจุดรหัสสำหรับอักขระ 1 คือ U + 0031 ดังนั้นคุณจึงต้องหลีกเลี่ยงจุดนั้นเป็น \ 000031 หรือ \ 31

โดยพื้นฐานแล้วในการหลีกเลี่ยงอักขระตัวเลขใด ๆ เพียงนำหน้าด้วย \ 3 และต่อท้ายอักขระช่องว่าง () ยัย Unicode!

ดังนั้นโค้ดของคุณจะลงเอยด้วย (CSS แรก, JS วินาที):

#\31  {
    background: hotpink;
}

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

ไวยากรณ์สำหรับค่าที่มากกว่า 9 คืออะไร ฉันไม่สามารถใช้สิ่งนี้กับ ID อย่าง 10.
Berry Blue

5
คุณต้องเว้นวรรคหลังอักขระตัวแรก: #\\31 0- คุณสามารถอ้างถึงmothereffingcssescapes.com
Dennis

ขอบคุณสำหรับการติดตามและลิงค์!
Berry Blue

1
โปรดทราบว่าช่องว่างนั้นจำเป็นก็ต่อเมื่ออักขระที่เป็นเลขฐานสิบหกตามหลังลำดับ Escape ทันทีเพื่อแยกอักขระนั้นออกจากลำดับการหลีกเลี่ยง ดูw3.org/TR/CSS21/syndata.html#charactersสำหรับรายละเอียดเพิ่มเติม
BoltClock

85

เนื่องจากแม้ว่าจะถูกต้องในข้อมูลจำเพาะ HTML5 แต่ก็ไม่ถูกต้องใน CSS ซึ่งเป็นความหมายของ " ตัวเลือกการค้นหา"

แต่คุณจะต้องทำสิ่งนี้document.querySelector("[id='1']")แทนซึ่งเป็นเรื่องที่ยืดยาวมากเมื่อพิจารณาว่าคุณสามารถให้รหัสที่มีความหมายเช่นmessage1หรือบางอย่างได้)


1
คุณไม่จำเป็นต้อง "- มีวิธีใช้ตัวเลือกรหัสที่มีตัวเลขนำหน้า ฉันยอมรับว่าควรมีรหัสที่มีความหมายดีกว่า
Dennis

9
UUID สามารถเริ่มต้นด้วยตัวเลข
Alfonso Nishikawa

24

ฉันต้องการแนวทางที่เป็นแบบอัตโนมัติ การเปลี่ยนแปลงล่าสุดหมายความว่าค่า id ที่ใช้ไม่ใช่ตัวอักษรธรรมดาอีกต่อไปและรวมตัวเลขและอักขระพิเศษ

ฉันลงเอยด้วยการใช้CSS.escape: https://developer.mozilla.org/en-US/docs/Web/API/CSS/escape

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

ประการแรกนี่เป็นกรณีที่ล้มเหลว:

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

และตอนนี้ใช้CSS.escape:

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

ดูว่าการแสดงการเปลี่ยนแปลงอย่างถูกต้องแสดงAfterให้เห็นว่าตัวเลือกทำงานอย่างไร!


ณ วันนี้เมื่อคุณต้องจัดการกับ id แปลก ๆ ที่คุณไม่ได้ควบคุมนี่เป็นวิธีแก้ปัญหาที่สะอาดที่สุดเพราะสิ่งนี้ได้รับการสนับสนุนโดยเบราว์เซอร์สมัยใหม่ทั้งหมด
LasaleFamine

ทางออกที่ยอดเยี่ยมโดยใช้สิ่งนี้ในการผลิต
LoopsGod

3

จาก W3C documentation Attribute selectors syntax

ค่าแอตทริบิวต์ต้องเป็นตัวระบุ CSS หรือสตริงที่ถูกต้อง

ดังนั้นตัวเลขหรือสตริงตัวอักษรและตัวเลขที่มีตัวเลขนำหน้าจึงไม่ถือเป็นตัวระบุที่ถูกต้อง

หากคุณกำลังใช้ยูทิลิตี้ตัวสร้าง ID เพื่อสร้างตัวระบุคุณอาจลงท้ายด้วยรหัสตัวเลขที่เป็นตัวอักษรพร้อมตัวเลขนำหน้า

การแก้ไขอย่างรวดเร็วคือละเว้นตัวเลขจาก SEED ของเครื่องกำเนิดไฟฟ้า (หากสามารถแก้ไขได้) หรือต่อท้ายสตริงกับ id ที่สร้างขึ้น


2

นี่คือฟังก์ชั่นที่ฉันทำขึ้นในตอนนี้เพื่อจัดการกับ ID หมายเลขชั้นนำในตัวเลือก CSS และ IE ปลอดภัยเพราะ CSS.escape ไม่ใช่

ส่งตัวเลือกผ่านฟังก์ชัน cleanSelector นี้ก่อนใช้งาน:

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 ); 


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.