Tại sao JavaScript của tôi không hoạt động trong JSFiddle?


114

Tôi không thể tìm ra vấn đề với JSFiddle này .

HTML:

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

JavaScript:

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

Và khi tôi nhấp vào nút - không có gì xảy ra. Bảng điều khiển cho biết "thử nghiệm không được xác định"

Tôi đã đọc tài liệu JSFiddle - ở đó nó nói rằng mã JS được thêm vào <head>và mã HTML được thêm vào <body>(vì vậy mã JS này sớm hơn html và sẽ hoạt động).


Loại bỏ dấu ngoặc đơn cũng sẽ hoạt động trong các trường hợp bình thường không khó hiểu mặc dù chắc chắn là lời khuyên tốt nên tách js khỏi HTML càng nhiều càng tốt. Tôi chỉ cho phép mình style = "display: none" CSS nội tuyến no-no.
Adrian Bartholomew

Câu trả lời:


60

Hàm đang được định nghĩa bên trong một trình xử lý tải và do đó nằm trong một phạm vi khác. Như @ellisbben ghi chú trong các nhận xét, bạn có thể khắc phục điều này bằng cách xác định rõ ràng nó trên windowđối tượng. Tốt hơn hết, hãy thay đổi nó để áp dụng trình xử lý cho đối tượng một cách không phô trương: http://jsfiddle.net/pUeue/

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

Lưu ý áp dụng trình xử lý theo cách này, thay vì nội tuyến, giữ cho HTML của bạn sạch sẽ. Tôi đang sử dụng jQuery, nhưng bạn có thể làm điều đó có hoặc không có khuôn khổ hoặc sử dụng một khuôn khổ khác, nếu bạn muốn.


@Innuendo - jsFiddle sử dụng các khung riêng biệt cho mã / html / trang định kiểu. bạn cần tham chiếu đến khung trong lệnh gọi hàm, nhưng thực sự không có cách nào dễ dàng để làm điều đó vì khung không có tên. Đó thực sự là một vấn đề do cách thức hoạt động của jsfiddle, nhưng bạn vẫn nên giữ javascript của mình hoàn toàn riêng biệt.
tvanfosson

5
@ tvanfosson- giải pháp của bạn hoạt động, nhưng jsfiddle không sử dụng các khung riêng biệt để hiển thị kết quả; xem jsfiddle.net/Yazpj/show . Lý do ban đầu nó không hoạt động là nó testđược định nghĩa bên trong một onLoadhàm; sử dụng window.test = function(){/*...*/}làm cho nó hoạt động hoàn toàn tốt.
ellisbben

@ellisbben - nếu tôi sử dụng Firebug để kiểm tra DOM, mỗi ngăn trong số 4 ngăn riêng biệt tồn tại trong một iframe riêng biệt.
tvanfosson

1
Có, nhưng nếu bạn kiểm tra iframe duy nhất được sử dụng để hiển thị ví dụ, bạn sẽ thấy rằng nó đặt tất cả mã trong một trang duy nhất không sử dụng khung, do đó những khung đó không thể phá vỡ ví dụ của bạn. Nối showđến bất kỳ URL jsfiddle để xem những gì tôi đang nói về: jsfiddle.net/Yazpj/show
ellisbben

100

Nếu bạn không chỉ định cài đặt bọc, nó sẽ mặc định là "onLoad". Điều này dẫn đến việc tất cả JavaScript được bao bọc trong một hàm chạy sau khi kết quả được tải. Tất cả các biến là cục bộ của hàm này do đó không khả dụng trong phạm vi toàn cục.

Thay đổi cài đặt gói thành "không bọc" và nó sẽ hoạt động:

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

Tôi đã chuyển khung thành "Không có Thư viện" vì bạn không sử dụng bất kỳ.


22

Có một cách khác, khai báo hàm của bạn thành một biến như sau:

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

jsFiddle


Chi tiết

CHỈNH SỬA (dựa trên nhận xét của @nnnnnn)

@nnnnnn:

tại sao nói test =(không có var) sẽ sửa chữa nó?

Khi bạn xác định một hàm như thế này:

var test = function(){};

Hàm được định nghĩa cục bộ, nhưng khi bạn xác định hàm của mình mà không có var:

test = function(){};

testđược xác định trên windowđối tượng ở phạm vi cấp cao nhất.

tại sao nó hoạt động?

Giống như @zalun nói:

Nếu bạn không chỉ định cài đặt bọc, nó sẽ mặc định là "onLoad". Điều này dẫn đến việc tất cả JavaScript được bao bọc trong một hàm chạy sau khi kết quả được tải. Tất cả các biến là cục bộ của hàm này do đó không khả dụng trong phạm vi toàn cục.

Nhưng nếu bạn sử dụng cú pháp này:

test = function(){};

Bạn có quyền truy cập vào hàm testvì nó được xác định trên toàn cầu


Người giới thiệu :


2
Đây thực sự là cách tiếp cận đơn giản nhất là bạn chỉ đang thử nghiệm một đoạn mã nhỏ trong JSFiddle.
DOK

Nhưng tại sao điều này lại hoạt động? Liên kết "Thông tin khác" mà bạn đã cung cấp không giải thích rằng vấn đề có liên quan đến phạm vi hay lý do tại sao nói test = (không có var) sẽ khắc phục được sự cố.
nnnnnn

@ R3tep tốt, liên kết đầu tiên của bạn là: jsfiddle.net/R3tep/Yazpj/1406 cảnh báo không làm được gì cho tôi. Tôi đang sử dụng chrome.
Ced

@ R3tep vâng nó hoạt động với console.log. Tôi sẽ đăng một câu hỏi trên SO vì tôi tin rằng thực tế là tôi không có hộp cảnh báo nào có liên quan đến một vấn đề khác mà tôi với iframe.
Ced

1
@ R3tep Tôi nghĩ bạn đã hiểu lầm tôi nhưng tôi không chắc lắm. Mã của bạn là / tốt. Có một vấn đề với cách JSFiddle được mã hóa (thiếu giá trị trong thuộc tính hộp cát của iframe mà họ đang sử dụng để hiển thị kết quả). Điều đó làm cho nó như vậy nó sẽ không hoạt động trên một số phiên bản chrome. Tôi đã gửi một báo cáo sự cố trên github của họ. Tôi rất quan tâm đến nó bởi vì tôi nghĩ rằng vấn đề tôi đang gặp phải trên trang web của mình cũng vậy nhưng không. Chúc mừng.
Ced

3

Thay đổi cài đặt bọc trong bảng Khung công tác & Tiện ích mở rộng thành "Không bọc <body>"


-1

Không có vấn đề gì với mã của bạn, chỉ cần chọn phần mở rộng onLoad () từ phía bên phải.


-1
<script> 
function test(){
 alert("test");   
}
</script>

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

-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");
}
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.