ทำไม jQuery หรือวิธี DOM เช่น getElementById ไม่พบองค์ประกอบ?


483

อะไรคือเหตุผลที่เป็นไปได้สำหรับdocument.getElementById, $("#id")หรือวิธี DOM / jQuery ตัวเลือกอื่น ๆ ที่ไม่ได้หาองค์ประกอบ?

ตัวอย่างปัญหาประกอบด้วย:

  • jQuery ล้มเหลวในการผูกตัวจัดการเหตุการณ์อย่างเงียบ ๆ
  • jQuery "ทะเยอทะยาน" วิธีการ ( .val(), .html(), .text()) กลับมาundefined
  • วิธี DOM มาตรฐานที่ส่งคืนnullทำให้เกิดข้อผิดพลาดหลายประการ:

Uncaught TypeError: ไม่สามารถตั้งค่าคุณสมบัติ '... ' ของ null ได้ Uncaught TypeError: ไม่สามารถอ่านคุณสมบัติ '... ' ของ null

รูปแบบที่พบบ่อยที่สุดคือ:

Uncaught TypeError: ไม่สามารถตั้งค่าคุณสมบัติ 'onclick' ของ null

Uncaught TypeError: ไม่สามารถอ่านคุณสมบัติ 'addEventListener' เป็นโมฆะ

Uncaught TypeError: ไม่สามารถอ่านคุณสมบัติ 'style' ของ null ได้


32
มีคำถามมากมายที่ถามเกี่ยวกับสาเหตุที่ไม่พบองค์ประกอบ DOM บางอย่างและเหตุผลมักเกิดขึ้นเนื่องจากวางรหัส JavaScript ไว้หน้าองค์ประกอบ DOM นี่มีไว้เพื่อเป็นคำตอบที่ยอมรับได้สำหรับคำถามประเภทนี้ มัน wiki ชุมชนดังนั้นโปรดอย่าลังเลที่จะปรับปรุงมัน
เฟลิกซ์คลิง

คำตอบ:


481

องค์ประกอบที่คุณพยายามค้นหาไม่ได้อยู่ในDOMเมื่อสคริปต์ของคุณทำงาน

ตำแหน่งของสคริปต์พึ่งพา DOM ของคุณสามารถมีผลกระทบอย่างลึกซึ้งต่อพฤติกรรมของสคริปต์ เบราว์เซอร์แยกวิเคราะห์เอกสาร HTML จากบนลงล่าง มีการเพิ่มองค์ประกอบลงใน DOM และสคริปต์จะดำเนินการตามปกติ ซึ่งหมายความว่าคำสั่งนั้นสำคัญ โดยทั่วไปแล้วสคริปต์ไม่สามารถค้นหาองค์ประกอบที่ปรากฏในภายหลังในมาร์กอัปเนื่องจากองค์ประกอบเหล่านั้นยังไม่ได้ถูกเพิ่มใน DOM

พิจารณามาร์กอัปต่อไปนี้ สคริปต์ # 1 ล้มเหลวในการค้นหาใน<div>ขณะที่สคริปต์ # 2 ประสบความสำเร็จ:

<script>
  console.log("script #1: %o", document.getElementById("test")); // null
</script>
<div id="test">test div</div>
<script>
  console.log("script #2: %o", document.getElementById("test")); // <div id="test" ...
</script>

ดังนั้นคุณควรทำอย่างไร คุณมีตัวเลือกน้อย:


ตัวเลือกที่ 1: ย้ายสคริปต์ของคุณ

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

<body>
  <button id="test">click me</button>
  <script>
    document.getElementById("test").addEventListener("click", function() {
      console.log("clicked: %o", this);
    });
  </script>
</body><!-- closing body tag -->

หมายเหตุ: การวางสคริปต์ที่ด้านล่างโดยทั่วไปถือว่าเป็นแนวปฏิบัติที่เหมาะสมที่สุด


ตัวเลือก 2: jQuery ready()

เลื่อนสคริปต์ของคุณจนกว่า DOM จะถูกวิเคราะห์โดยใช้:$(handler)

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
  $(function() {
    $("#test").click(function() {
      console.log("clicked: %o", this);
    });
  });
</script>
<button id="test">click me</button>

หมายเหตุ: คุณสามารถผูกDOMContentLoadedหรือ เพียง แต่แต่ละคนมีข้อแม้ของมัน jQuery's มอบโซลูชันแบบไฮบริดwindow.onloadready()


ตัวเลือก 3: การมอบหมายเหตุการณ์

เหตุการณ์ที่ได้รับมอบหมายมีข้อได้เปรียบที่พวกเขาสามารถประมวลผลเหตุการณ์จากองค์ประกอบลูกหลานที่เพิ่มลงในเอกสารในภายหลัง

เมื่อองค์ประกอบทำให้เกิดเหตุการณ์ (โดยมีเงื่อนไขว่าเป็นเหตุการณ์ที่เดือดดาลและไม่มีสิ่งใดหยุดการแพร่กระจาย) ผู้ปกครองแต่ละคนในบรรพบุรุษขององค์ประกอบนั้นจะได้รับเหตุการณ์เช่นกัน ที่ช่วยให้เราสามารถแนบตัวจัดการกับองค์ประกอบที่มีอยู่และเหตุการณ์ตัวอย่างในขณะที่พวกเขาฟองสบู่ขึ้นมาจากลูกหลานของมัน ... แม้กระทั่งสิ่งที่เพิ่มเข้ามาหลังจากที่ติดตั้งตัวจัดการ สิ่งที่เราต้องทำคือตรวจสอบเหตุการณ์เพื่อดูว่ามันได้รับการเลี้ยงดูโดยองค์ประกอบที่ต้องการหรือไม่และถ้าเป็นเช่นนั้นให้เรียกใช้รหัสของเรา

jQuery on()นั้นใช้ตรรกะนั้นสำหรับเรา เราให้ชื่อเหตุการณ์ตัวเลือกสำหรับผู้สืบทอดที่ต้องการและตัวจัดการเหตุการณ์:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
  $(document).on("click", "#test", function(e) {
    console.log("clicked: %o",  this);
  });
</script>
<button id="test">click me</button>

หมายเหตุ: โดยทั่วไปแล้วรูปแบบนี้สงวนไว้สำหรับองค์ประกอบที่ไม่มีอยู่ ณ เวลาโหลดหรือเพื่อหลีกเลี่ยงการติดตั้งตัวจัดการจำนวนมาก มันก็คุ้มค่าที่ชี้ให้เห็นว่าในขณะที่ฉันได้แนบ handler ไปdocument(เพื่อจุดประสงค์ในการสาธิต) คุณควรเลือกบรรพบุรุษที่เชื่อถือได้ที่ใกล้ที่สุด


ตัวเลือก 4: deferแอตทริบิวต์

ใช้แอตทริบิวต์ของdefer<script>

[ defer, แอตทริบิวต์ Boolean,] ถูกตั้งค่าให้ระบุไปยังเบราว์เซอร์ว่าสคริปต์นั้นหมายถึงการเรียกใช้งานหลังจากที่เอกสารถูกแยกวิเคราะห์ แต่ก่อนที่จะDOMContentLoadedเริ่มทำงาน

<script src="https://gh-canon.github.io/misc-demos/log-test-click.js" defer></script>
<button id="test">click me</button>

สำหรับการอ้างอิงนี่คือรหัสจากสคริปต์ภายนอก :

document.getElementById("test").addEventListener("click", function(e){
   console.log("clicked: %o", this); 
});

หมายเหตุ: deferแอตทริบิวต์ดูเหมือนจะเป็นสัญลักษณ์เวทย์มนตร์แต่สิ่งสำคัญที่ต้องระวังคือข้อควรระวัง ...
1. deferสามารถใช้สำหรับสคริปต์ภายนอกเท่านั้น: ผู้ที่มีsrcคุณสมบัติ
2. ระวังการรองรับเบราว์เซอร์เช่น: การใช้งานบั๊กกี้ใน IE <10


ตอนนี้ในปี 2020 - "การวางสคริปต์ที่ด้านล่าง" ยัง "ถือว่าเป็นแนวปฏิบัติที่ดีที่สุด" หรือไม่? ฉัน (ทุกวันนี้) ใส่ทรัพยากรทั้งหมดของฉันไว้ใน<head>และใช้deferกับสคริปต์ (ฉันไม่ต้องสนับสนุนเบราว์เซอร์ที่ไม่รองรับรุ่นเก่า)
Stephen P

ฉันเป็นผู้สนับสนุนหลักในการย้ายเข้าสู่เบราว์เซอร์สมัยใหม่ ที่กล่าวว่าการปฏิบัตินี้ไม่ได้ทำให้ฉันเสียค่าใช้จ่าย แต่อย่างใดและใช้ได้ทุกที่ ในทางตรงกันข้ามทั้งสองdeferและasyncมีการสนับสนุนในวงกว้าง - ถึงสิบถึงเวอร์ชันเก่าของเบราว์เซอร์ พวกเขามีข้อได้เปรียบเพิ่มเติมอย่างชัดเจนบ่งบอกถึงพฤติกรรมที่ตั้งใจไว้อย่างชัดเจน โปรดจำไว้ว่าแอตทริบิวต์เหล่านี้ใช้สำหรับสคริปต์ที่ระบุsrcแอตทริบิวต์เช่น: สคริปต์ภายนอกเท่านั้น ชั่งน้ำหนักผลประโยชน์ อาจจะใช้ทั้งคู่? การโทรของคุณ
ศีล

146

สั้นและง่าย:เนื่องจากองค์ประกอบที่คุณต้องการไม่มีอยู่ในเอกสาร (ยัง)


สำหรับส่วนที่เหลือของคำตอบนี้ผมจะใช้getElementByIdเป็นตัวอย่าง แต่เช่นเดียวกับgetElementsByTagName, querySelectorและวิธีการ DOM อื่น ๆ ที่เลือกองค์ประกอบ

เหตุผลที่เป็นไปได้

มีสองเหตุผลที่องค์ประกอบอาจไม่มีอยู่:

  1. องค์ประกอบที่มีรหัสผ่านไม่ได้มีอยู่จริงในเอกสาร คุณควรตรวจสอบอีกครั้งว่า ID ที่คุณส่งไปgetElementByIdตรงกับ ID ขององค์ประกอบที่มีอยู่ใน HTML (สร้าง) แล้วและคุณไม่ได้สะกด ID (ID เป็นตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ )!

    อนึ่งในเบราว์เซอร์ร่วมสมัยส่วนใหญ่ที่ใช้งานquerySelector()และquerySelectorAll()วิธีการสัญกรณ์สไตล์ CSS จะใช้ในการดึงองค์ประกอบโดยidตัวอย่างเช่นdocument.querySelector('#elementID')เมื่อเทียบกับวิธีการที่องค์ประกอบถูกดึงโดยidภายใต้document.getElementById('elementID'); ในตอนแรก#ตัวละครมีความสำคัญในครั้งที่สองมันจะนำไปสู่องค์ประกอบที่ไม่ถูกดึงออกมา

  2. องค์ประกอบที่ไม่ได้อยู่ในขณะที่getElementByIdคุณเรียก

กรณีหลังค่อนข้างทั่วไป เบราว์เซอร์แยกวิเคราะห์และประมวลผล HTML จากบนลงล่าง ซึ่งหมายความว่าการเรียกองค์ประกอบ DOM ที่เกิดขึ้นก่อนองค์ประกอบ DOM นั้นจะปรากฏใน HTML จะล้มเหลว

ลองพิจารณาตัวอย่างต่อไปนี้:

<script>
    var element = document.getElementById('my_element');
</script>

<div id="my_element"></div>

divปรากฏหลังจาก scriptในขณะที่สคริปต์ที่จะดำเนินการองค์ประกอบไม่ได้อยู่เลยและจะกลับมาgetElementByIdnull

jQuery

เช่นเดียวกับตัวเลือกทั้งหมดที่มี jQuery jQuery จะไม่พบองค์ประกอบถ้าคุณสะกดผิดตัวเลือกของคุณหรือคุณกำลังพยายามที่จะเลือกพวกเขาก่อนที่พวกเขามีอยู่จริง

การบิดเพิ่มคือเมื่อไม่พบ jQuery เนื่องจากคุณโหลดสคริปต์โดยไม่มีโปรโตคอลและทำงานจากระบบไฟล์:

<script src="//somecdn.somewhere.com/jquery.min.js"></script>

ไวยากรณ์นี้ใช้เพื่อให้สคริปต์โหลดผ่าน HTTPS บนหน้าเว็บที่มีโปรโตคอล https: // และโหลดรุ่น HTTP บนหน้าเว็บที่มีโปรโตคอล http: //

มันมีผลข้างเคียงที่โชคร้ายของการพยายามและล้มเหลวในการโหลด file://somecdn.somewhere.com...


โซลูชั่น

ก่อนที่คุณจะโทรไปที่getElementById(หรือวิธีการ DOM สำหรับเรื่องนั้น) ตรวจสอบให้แน่ใจว่าองค์ประกอบที่คุณต้องการเข้าถึงนั้นมีอยู่นั่นคือโหลด DOM แล้ว

นี้สามารถมั่นใจได้โดยเพียงแค่ใส่ JavaScript ของคุณหลังจากองค์ประกอบ DOM ที่สอดคล้องกัน

<div id="my_element"></div>

<script>
    var element = document.getElementById('my_element');
</script>

ในกรณีที่คุณสามารถใส่รหัสก่อนแท็กปิดร่างกาย ( </body>) (องค์ประกอบ DOM ทั้งหมดจะสามารถใช้ได้ในเวลาที่สคริปต์ถูกดำเนินการ)

การแก้ปัญหาอื่น ๆ ได้แก่ การฟังไปload [MDN]หรือDOMContentLoaded [MDN]เหตุการณ์ ในกรณีเหล่านี้ไม่สำคัญว่าในเอกสารที่คุณวางรหัส JavaScript คุณต้องจำไว้ว่าให้ใส่รหัสการประมวลผล DOM ทั้งหมดลงในตัวจัดการเหตุการณ์

ตัวอย่าง:

window.onload = function() {
    // process DOM elements here
};

// or

// does not work IE 8 and below
document.addEventListener('DOMContentLoaded', function() {
    // process DOM elements here
});

โปรดดูบทความที่ quirksmode.orgสำหรับข้อมูลเพิ่มเติมเกี่ยวกับการจัดการเหตุการณ์และความแตกต่างของเบราว์เซอร์

jQuery

ก่อนอื่นตรวจสอบให้แน่ใจว่าโหลด jQuery อย่างถูกต้อง ใช้เครื่องมือสำหรับนักพัฒนาของเบราว์เซอร์เพื่อค้นหาว่าพบไฟล์ jQuery และแก้ไข URL หากไม่ได้เป็นเช่นนั้น (เช่นเพิ่มhttp:หรือhttps:โครงร่างในตอนเริ่มต้นปรับเส้นทาง ฯลฯ )

ฟังload/ DOMContentLoaded เหตุการณ์ที่เกิดขึ้นเป็นสิ่งที่ jQuery จะทำกับ[เอกสาร].ready() รหัส jQuery ทั้งหมดของคุณที่มีผลต่อองค์ประกอบ DOM ควรอยู่ในตัวจัดการเหตุการณ์นั้น

ในความเป็นจริงการสอน jQueryระบุอย่างชัดเจน:

เกือบทุกอย่างที่เราทำเมื่อใช้ jQuery อ่านหรือปรับเปลี่ยนโมเดลวัตถุเอกสาร (DOM) เราต้องตรวจสอบให้แน่ใจว่าเราเริ่มเพิ่มกิจกรรม ฯลฯ ทันทีที่ DOM พร้อม

ในการทำสิ่งนี้เราลงทะเบียนเหตุการณ์ที่พร้อมสำหรับเอกสาร

$(document).ready(function() {
   // do stuff when DOM is ready
});

หรือคุณสามารถใช้ไวยากรณ์ชวเลขได้:

$(function() {
    // do stuff when DOM is ready
});

ทั้งสองมีความเท่าเทียมกัน


1
มันจะคุ้มค่าหรือไม่ที่จะแก้ไขบิตสุดท้ายเกี่ยวกับreadyเหตุการณ์เพื่อสะท้อนถึงไวยากรณ์ที่ต้องการ "ใหม่กว่า" หรือดีกว่าที่จะปล่อยให้มันเป็นแบบนั้นเพื่อให้ใช้ได้กับเวอร์ชันเก่ากว่าหรือไม่
Tieson T.

1
สำหรับ jQuery คือมันคุ้มค่านอกจากนี้ยังมีการเพิ่มในทางเลือก$(window).load()(และทางเลือกที่อาจจะเป็นประโยคไป$(document).ready(), $(function(){})ดูเหมือนว่าเกี่ยวข้อง แต่มันได้หรือไม่รู้สึกสัมผัสเล็กน้อยไปยังจุดที่คุณทำกำลัง.
เดวิดกล่าวว่าคืนสถานะโมนิกา

@ David: .loadจุดที่ดีกับ เกี่ยวกับทางเลือกทางไวยากรณ์พวกเขาสามารถค้นหาในเอกสาร แต่เนื่องจากคำตอบควรอยู่ในตัวเองจึงอาจมีค่าเพิ่ม จากนั้นอีกครั้งฉันค่อนข้างแน่ใจว่าบิตเฉพาะเกี่ยวกับ jQuery นี้ได้รับคำตอบแล้วและอาจครอบคลุมในคำตอบอื่นและการเชื่อมโยงไปยังอาจเพียงพอ
Felix Kling

1
@ David: ฉันมีการแก้ไข: เห็นได้ชัดว่า.loadจะเลิก: api.jquery.com/load-event ฉันไม่รู้ว่ามันมีไว้สำหรับรูปภาพเท่านั้นหรือwindowดีกว่า
เฟลิกซ์ลิ่ง

1
@ David: ไม่ต้องกังวล :) แม้ว่าคุณจะไม่แน่ใจมันดีที่คุณพูดถึงมัน ฉันอาจจะเพิ่มตัวอย่างรหัสง่ายๆเพื่อแสดงการใช้งาน ขอบคุณสำหรับข้อมูลของคุณ!
เฟลิกซ์ลิ่ง

15

สาเหตุที่ตัวเลือกที่ใช้ id ไม่ทำงาน

  1. องค์ประกอบ / DOM ที่ระบุ id ยังไม่มีอยู่
  2. มีองค์ประกอบอยู่ แต่ไม่ได้ลงทะเบียนใน DOM [ในกรณีของโหนด HTML ต่อท้ายแบบไดนามิกจากการตอบกลับ Ajax]
  3. มีองค์ประกอบมากกว่าหนึ่งรายการที่มีรหัสเดียวกันซึ่งทำให้เกิดข้อขัดแย้ง

โซลูชั่น

  1. ลองเข้าถึงองค์ประกอบหลังจากประกาศหรือใช้สิ่งที่ชอบ $(document).ready();

  2. สำหรับองค์ประกอบที่มาจากการตอบสนองของ Ajax ให้ใช้.bind()วิธีการของ jQuery jQuery เวอร์ชันที่เก่ากว่ามี.live()เหมือนกัน

  3. ใช้เครื่องมือ [ตัวอย่างเช่นปลั๊กอิน webdeveloper สำหรับเบราว์เซอร์] เพื่อค้นหารหัสที่ซ้ำกันและลบออก


13

ตามที่ @FelixKling ชี้ให้เห็นว่าสถานการณ์ที่เป็นไปได้มากที่สุดคือโหนดที่คุณกำลังมองหาไม่มีอยู่ (ยัง)

อย่างไรก็ตามแนวทางการพัฒนาที่ทันสมัยมักจะสามารถจัดการองค์ประกอบเอกสารด้านนอกของทรีเอกสารด้วย DocumentFragments หรือเพียงแค่ถอด / ใส่ส่วนประกอบปัจจุบันโดยตรงอีกครั้ง เทคนิคดังกล่าวอาจถูกนำมาใช้เป็นส่วนหนึ่งของการสร้างเทมเพลต JavaScript หรือเพื่อหลีกเลี่ยงการวาด / การรีโฟลว์ที่มากเกินไปในขณะที่องค์ประกอบที่เป็นปัญหาถูกเปลี่ยนแปลงอย่างหนัก

ในทำนองเดียวกันฟังก์ชั่น "Shadow DOM" ใหม่ที่กำลังเปิดตัวในเบราว์เซอร์สมัยใหม่ช่วยให้องค์ประกอบต่างๆเป็นส่วนหนึ่งของเอกสาร แต่ไม่สามารถสืบค้นได้โดย document.getElementById และวิธี sibling ทั้งหมด (querySelector เป็นต้น) สิ่งนี้ทำเพื่อหุ้มหน้าที่การใช้งานและซ่อนไว้โดยเฉพาะ

อีกครั้งแม้ว่าเป็นไปได้มากว่าองค์ประกอบที่คุณกำลังมองหาไม่ได้อยู่ในเอกสารและคุณควรทำตามที่เฟลิกซ์แนะนำ อย่างไรก็ตามคุณควรทราบด้วยว่านั่นไม่ใช่เหตุผลเดียวที่องค์ประกอบอาจไม่สามารถแยกแยะได้ (ทั้งชั่วคราวหรือถาวร)


13

หากองค์ประกอบที่คุณพยายามเข้าถึงอยู่ภายในiframeและคุณพยายามที่จะเข้าถึงมันนอกบริบทของสิ่งiframeนี้จะทำให้มันล้มเหลว

หากคุณต้องการที่จะได้รับองค์ประกอบใน iframe ที่คุณสามารถหาวิธีที่นี่


7

หากคำสั่งการเรียกใช้งานสคริปต์ไม่ใช่ปัญหาสาเหตุที่เป็นไปได้อีกประการของปัญหาคือองค์ประกอบไม่ได้ถูกเลือกอย่างเหมาะสม:

  • getElementByIdต้องใช้สตริงที่ส่งผ่านเป็นคำต่อคำ ID และไม่มีอะไรอื่น หากคุณใส่คำนำหน้าสตริงที่ส่งผ่านด้วย a #และ ID ไม่ได้ขึ้นต้นด้วย a #จะไม่มีการเลือกอะไรเลย:

    <div id="foo"></div>
    // Error, selected element will be null:
    document.getElementById('#foo')
    // Fix:
    document.getElementById('foo')
  • ในทำนองเดียวกันสำหรับgetElementsByClassNameห้ามนำหน้าสตริงที่ส่งด้วย.:

    <div class="bar"></div>
    // Error, selected element will be undefined:
    document.getElementsByClassName('.bar')[0]
    // Fix:
    document.getElementsByClassName('bar')[0]
  • ด้วย querySelector, querySelectorAll และ jQuery เพื่อจับคู่อิลิเมนต์ที่มีชื่อคลาสเฉพาะให้วาง.โดยตรงก่อนคลาส หากต้องการจับคู่องค์ประกอบที่มี ID เฉพาะให้วางไว้#ตรงหน้า ID:

    <div class="baz"></div>
    // Error, selected element will be null:
    document.querySelector('baz')
    $('baz')
    // Fix:
    document.querySelector('.baz')
    $('.baz')

    กฎระเบียบที่นี่เป็นในกรณีส่วนใหญ่เหมือนกับเหล่านั้นสำหรับตัวเลือก CSS และสามารถมองเห็นได้ในรายละเอียดที่นี่

  • ในการจับคู่องค์ประกอบที่มีแอตทริบิวต์สองรายการขึ้นไป (เช่นชื่อคลาสสองชื่อหรือชื่อคลาสและdata-แอตทริบิวต์) ให้ใส่ตัวเลือกสำหรับแต่ละแอตทริบิวต์ถัดจากแต่ละรายการในสตริงตัวเลือกโดยไม่มีช่องว่างคั่นพวกเขา (เพราะช่องว่างระบุเลือกลูกหลาน ) ตัวอย่างเช่นเมื่อต้องการเลือก:

    <div class="foo bar"></div>

    .foo.barใช้สตริงการสืบค้น เลือก

    <div class="foo" data-bar="someData"></div>

    .foo[data-bar="someData"]ใช้สตริงการสืบค้น วิธีเลือก<span>ด้านล่าง:

    <div class="parent">
      <span data-username="bob"></span>
    </div>

    div.parent > span[data-username="bob"]ใช้

  • การใช้ตัวพิมพ์ใหญ่และตัวสะกดมีความสำคัญสำหรับทุกข้อ หากการใช้อักษรตัวพิมพ์ใหญ่ต่างกันหรือการสะกดแตกต่างกันองค์ประกอบจะไม่ถูกเลือก:

    <div class="result"></div>
    // Error, selected element will be null:
    document.querySelector('.results')
    $('.Result')
    // Fix:
    document.querySelector('.result')
    $('.result')
  • คุณต้องแน่ใจว่าวิธีการมีตัวพิมพ์ใหญ่และการสะกดคำที่เหมาะสม ใช้หนึ่งใน:

    $(selector)
    document.querySelector
    document.querySelectorAll
    document.getElementsByClassName
    document.getElementsByTagName
    document.getElementById

    การสะกดคำหรือตัวพิมพ์ใหญ่อื่น ๆ จะไม่ทำงาน ตัวอย่างเช่นdocument.getElementByClassNameจะโยนข้อผิดพลาด

  • ตรวจสอบให้แน่ใจว่าคุณส่งสตริงไปยังเมธอดตัวเลือกเหล่านี้ ถ้าคุณผ่านบางสิ่งบางอย่างที่ไม่ได้เป็นสตริงquerySelector, getElementByIdฯลฯ ก็เกือบจะแน่นอนจะไม่ทำงาน


0

เมื่อฉันลองใช้รหัสของคุณมันก็ใช้ได้

สาเหตุเดียวที่กิจกรรมของคุณไม่ทำงานอาจเป็นเพราะ DOM ของคุณยังไม่พร้อมและปุ่มที่ใช้รหัส "event-btn" ยังไม่พร้อม และจาวาสคริปต์ของคุณก็ถูกประหารและพยายามผูกเหตุการณ์ด้วยองค์ประกอบนั้น

ก่อนที่จะใช้องค์ประกอบ DOM เพื่อรวมองค์ประกอบนั้นควรพร้อม มีตัวเลือกมากมายให้ทำเช่นนั้น

ตัวเลือก 1: คุณสามารถย้ายรหัสการผูกกิจกรรมภายในเหตุการณ์ที่พร้อมของเอกสาร ชอบ:

document.addEventListener('DOMContentLoaded', (event) => {
  //your code to bind the event
});

ตัวเลือกที่ 2: คุณสามารถใช้เหตุการณ์หมดเวลาเพื่อให้การเชื่อมโยงล่าช้าในสองสามวินาที ชอบ:

setTimeout(function(){
  //your code to bind the event
}, 500);

ตัวเลือก 3: ย้ายจาวาสคริปต์ของคุณไปไว้ที่ด้านล่างของหน้า

ฉันหวังว่านี่จะช่วยคุณได้


@ Willdomybest18 โปรดตรวจสอบคำตอบนี้
Jatinder Kumar

-1

ปัญหาคือองค์ประกอบ dom 'speclist' ไม่ได้ถูกสร้างขึ้นในเวลาที่รหัส javascript ถูกเรียกใช้งาน ดังนั้นฉันจึงใส่รหัสจาวาสคริปต์ในฟังก์ชั่นและเรียกว่าฟังก์ชั่นนั้นในเหตุการณ์ร่างกาย onload

function do_this_first(){
   //appending code
}

<body onload="do_this_first()">
</body>

-1

วิธีการแก้ปัญหาของผมคือการได้ใช้ ID <a id='star_wars'>Place to jump to</a>ขององค์ประกอบสมอ: เห็นได้ชัดว่าพร่ามัวและกรอบสปาอื่น ๆ มีปัญหาการกระโดดไปที่จุดยึดในหน้าเดียวกัน document.getElementById('star_wars')จะได้รับรอบที่ผมใช้ อย่างไรก็ตามสิ่งนี้ไม่ทำงานจนกว่าฉันจะใส่รหัสในองค์ประกอบย่อหน้าแทน: <p id='star_wars'>Some paragraph<p>.

ตัวอย่างการใช้ bootstrap:

<button class="btn btn-link" onclick="document.getElementById('star_wars').scrollIntoView({behavior:'smooth'})">Star Wars</button>

... lots of other text

<p id="star_wars">Star Wars is an American epic...</p>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.