เหตุใด JavaScript ของฉันจึงไม่ทำงานใน JSFiddle


114

ฉันไม่สามารถหาสิ่งที่เป็นปัญหานี้JSFiddle

HTML:

<input type="button" value="test" onclick="test()">

JavaScript:

function test(){alert("test");}

และเมื่อฉันคลิกที่ปุ่ม - ไม่มีอะไรเกิดขึ้น คอนโซลแจ้งว่า "ไม่ได้กำหนดการทดสอบ"

ฉันได้อ่านเอกสาร JSFiddle - มีการระบุว่ามีการเพิ่มโค้ด JS <head>และโค้ด HTML จะถูกเพิ่มเข้ามา<body>(ดังนั้นโค้ด JS นี้จึงเร็วกว่า html และควรใช้งานได้)


การถอดวงเล็บออกจะใช้งานได้ภายใต้สถานการณ์ปกติที่ไม่ใช่เสียงซอแม้ว่าจะเป็นคำแนะนำที่ดีในการแยก js ออกจาก HTML ให้มากที่สุด ฉันอนุญาตเฉพาะ style = "display: none" CSS inline no-no เท่านั้น
Adrian Bartholomew

ที่เกี่ยวข้อง: JavaScript ไม่ทำงานบน jsfiddle.net
Bergi

คำตอบ:


60

ฟังก์ชันนี้ถูกกำหนดไว้ภายในตัวจัดการโหลดดังนั้นจึงอยู่ในขอบเขตที่แตกต่างกัน ดังที่ @ellisbben บันทึกไว้ในความคิดเห็นคุณสามารถแก้ไขปัญหานี้ได้โดยกำหนดไว้อย่างชัดเจนบนwindowวัตถุ ยังดีกว่าให้เปลี่ยนเพื่อใช้ตัวจัดการกับวัตถุอย่างไม่ปิดบัง: http://jsfiddle.net/pUeue/

$('input[type=button]').click( function() {
   alert("test");   
});

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


@Innuendo - jsFiddle ใช้เฟรมแยกต่างหากสำหรับโค้ด / html / สไตล์ชีต คุณจำเป็นต้องอ้างอิงเฟรมในการเรียกใช้ฟังก์ชัน แต่ไม่มีวิธีง่ายๆในการทำเช่นนั้นเนื่องจากเฟรมไม่มีชื่อ มันเป็นปัญหาจริงๆเนื่องจากวิธีการทำงานของ jsfiddle แต่คุณควรแยกจาวาสคริปต์ของคุณออกจากกันโดยสิ้นเชิง
tvanfosson

5
@ tvanfosson- โซลูชันของคุณใช้งานได้ แต่ jsfiddle ไม่ได้ใช้เฟรมแยกเพื่อแสดงผลลัพธ์ เห็นjsfiddle.net/Yazpj/show เหตุผลที่มันใช้ไม่ได้ในตอนแรกคือtestถูกกำหนดไว้ในonLoadฟังก์ชัน ใช้window.test = function(){/*...*/}ทำให้ทำงานได้ดีอย่างสมบูรณ์
ellisbben

@ellisbben - ถ้าฉันใช้ Firebug เพื่อตรวจสอบ DOM แต่ละบานหน้าต่างแยกกัน 4 บานจะอยู่ใน iframe แยกกัน
tvanfosson

1
ใช่ แต่ถ้าคุณตรวจสอบ iframe เดียวที่ใช้แสดงตัวอย่างคุณจะเห็นว่าโค้ดทั้งหมดอยู่ในหน้าเดียวที่ไม่ใช้เฟรมดังนั้นเฟรมเหล่านั้นจึงไม่สามารถทำลายตัวอย่างของคุณได้ ต่อท้ายshowURL jsfiddle เพื่อดูว่าฉันกำลังพูดถึงอะไร: jsfiddle.net/Yazpj/show
ellisbben

100

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

เปลี่ยนการตั้งค่าการห่อเป็น "ไม่ห่อ" และจะได้ผล:

http://jsfiddle.net/zalun/Yazpj/1/

ฉันเปลี่ยนกรอบงานเป็น "No Library" ตามที่คุณไม่ได้ใช้


22

มีอีกวิธีหนึ่งคือประกาศฟังก์ชันของคุณเป็นตัวแปรดังนี้:

test = function() {
  alert("test");
}

jsFiddle


รายละเอียด

แก้ไข (อ้างอิงจากความคิดเห็นของ @nnnnnn)

@nnnnnn:

ทำไมการพูดtest =(โดยไม่var) จะแก้ไขได้?

เมื่อคุณกำหนดฟังก์ชันเช่นนี้:

var test = function(){};

ฟังก์ชันถูกกำหนดไว้ในเครื่อง แต่เมื่อคุณกำหนดฟังก์ชันของคุณโดยไม่มีvar:

test = function(){};

testถูกกำหนดบนwindowวัตถุซึ่งอยู่ในขอบเขตระดับบนสุด

ทำไมถึงได้ผล?

ชอบ @zalun พูดว่า:

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

แต่ถ้าคุณใช้ไวยากรณ์นี้:

test = function(){};

คุณสามารถเข้าถึงฟังก์ชันได้testเนื่องจากมีการกำหนดไว้ทั่วโลก


อ้างอิง:


2
นี่เป็นวิธีที่ง่ายที่สุดคือคุณกำลังทดสอบโค้ดเล็กน้อยใน JSFiddle
DOK

แต่ทำไมถึงได้ผล? ลิงก์ "ข้อมูลเพิ่มเติม" ที่คุณระบุไม่ได้อธิบายว่าปัญหาเกี่ยวข้องกับขอบเขตหรือเหตุใดการบอกว่าtest = (ไม่มีvar) จะแก้ไขได้
nnnnnn

@ R3tep ลิงค์แรกของคุณซึ่งก็คือjsfiddle.net/R3tep/Yazpj/1406 alert ไม่ได้ทำอะไรให้ฉัน ฉันใช้ Chrome
Ced

@ R3tep ใช่มันใช้งานได้กับ console.log ฉันจะโพสต์คำถามใน SO เพราะฉันเชื่อว่าฉันไม่มีกล่องแจ้งเตือนที่เชื่อมโยงกับปัญหาอื่นที่ฉันใช้กับ iframe
Ced

1
@ R3tep ฉันคิดว่าคุณเข้าใจผิดฉัน แต่ฉันไม่แน่ใจ รหัสของคุณถูก / ดี มีปัญหาเกี่ยวกับวิธีการเข้ารหัส JSFiddle (ไม่มีค่าในคุณลักษณะแซนด์บ็อกซ์ของ iframe ที่ใช้เพื่อแสดงผลลัพธ์) นั่นทำให้มันใช้ไม่ได้กับ Chrome บางเวอร์ชัน ฉันส่งรายงานปัญหาเกี่ยวกับ github ของพวกเขา ฉันสนใจเรื่องนี้มากเพราะฉันคิดว่าปัญหาที่ฉันพบในเว็บไซต์นั้นเหมือนกัน แต่ไม่ใช่ ไชโย
Ced


-1

ไม่มีปัญหากับรหัสของคุณเพียงเลือกส่วนขยาย onLoad () จากด้านขวา



-3
Select OnDomready

HTML:

<input id="dButton" type="button" value="test"/>

JavaScript:

addEventListener('load', init, false);

function init()
{
  oInput = document.getElementById('dButton');
  oInput.onclick = test;
}

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