Uncaught ReferenceError: chức năng không được xác định với onclick


84

Tôi đang cố gắng tạo ra một usercript cho một trang web để thêm các biểu tượng cảm xúc tùy chỉnh. Tuy nhiên, tôi đã nhận được rất nhiều lỗi.

Đây là chức năng:

function saveEmotes() {
    removeLineBreaks();
    EmoteNameLines = EmoteName.value.split("\n");
    EmoteURLLines = EmoteURL.value.split("\n");
    EmoteUsageLines = EmoteUsage.value.split("\n");

    if (EmoteNameLines.length == EmoteURLLines.length && EmoteURLLines.length == EmoteUsageLines.length) {
        for (i = 0; i < EmoteURLLines.length; i++) {
            if (checkIMG(EmoteURLLines[i])) {
                localStorage.setItem("nameEmotes", JSON.stringify(EmoteNameLines));
                localStorage.setItem("urlEmotes", JSON.stringify(EmoteURLLines));
                localStorage.setItem("usageEmotes", JSON.stringify(EmoteUsageLines));
                if (i == 0) {
                    console.log(resetSlot());
                }
                emoteTab[2].innerHTML += '<span style="cursor:pointer;" onclick="appendEmote(\'' + EmoteUsageLines[i] + '\')"><img src="' + EmoteURLLines[i] + '" /></span>';
            } else {
                alert("The maximum emote(" + EmoteNameLines[i] + ") size is (36x36)");
            }
        }
    } else {
        alert("You have an unbalanced amount of emote parameters.");
    }
}

Các spanthẻ làonclick gọi hàm này:

function appendEmote(em) {
    shoutdata.value += em;
}

Mỗi khi tôi nhấp vào một nút có onclick thuộc tính, tôi gặp lỗi sau:

Uncaught ReferenceError: chức năng không được xác định.

Bất kỳ trợ giúp sẽ được đánh giá cao.

Cảm ơn bạn!

Cập nhật

Tôi đã thử sử dụng:

emoteTab[2].innerHTML += '<span style="cursor:pointer;" id="'+ EmoteNameLines[i] +'"><img src="' + EmoteURLLines[i] + '" /></span>';
document.getElementById(EmoteNameLines[i]).addEventListener("click", appendEmote(EmoteUsageLines[i]), false);

Nhưng tôi có một undefined lỗi.

Đây là kịch bản .

Tôi đã thử làm điều này để kiểm tra xem người nghe có hoạt động hay không và họ không thích tôi:

emoteTab[2].innerHTML = '<td class="trow1" width="12%" align="center"><a id="togglemenu" style="cursor: pointer;">Custom Icons</a></br><a style="cursor: pointer;" id="smilies" onclick=\'window.open("misc.php?action=smilies&amp;popup=true&amp;editor=clickableEditor","Smilies","scrollbars=yes, menubar=no,width=460,height=360,toolbar=no");\' original-title="">Smilies</a><br><a style="cursor: pointer;" onclick=\'window.open("shoutbox.php","Shoutbox","scrollbars=yes, menubar=no,width=825,height=449,toolbar=no");\' original-title="">Popup</a></td></br>';
document.getElementById("togglemenu").addEventListener("click", changedisplay,false);

1
Chỉ đăng mã có liên quan. Đọc các quy tắc.
alt

1
Liên kết đến tập lệnh hoàn chỉnh của bạn luôn thích hợp và được đánh giá cao, ngoài các đoạn mã liên quan cần có trong bài đăng của bạn.
Brock Adams

Câu trả lời:


131

Không bao giờ sử dụng .onclick(), hoặc các thuộc tính tương tự từ một chỉ số người dùng! (Nó cũng thực hành kém trong một trang web thông thường ).

Lý do là các usercript hoạt động trong một hộp cát ("thế giới bị cô lập") và onclickhoạt động trong phạm vi trang đích và không thể thấy bất kỳ chức năng nào mà script của bạn tạo ra.

Luôn sử dụng addEventListener()Doc (hoặc một hàm thư viện tương đương, như jQuery .on () ).

Vì vậy, thay vì mã như:

something.outerHTML += '<input onclick="resetEmotes()" id="btnsave" ...>'


Bạn sẽ sử dụng:

something.outerHTML += '<input id="btnsave" ...>'

document.getElementById ("btnsave").addEventListener ("click", resetEmotes, false);

Đối với vòng lặp, bạn không thể chuyển dữ liệu cho một trình xử lý sự kiện như vậy. Xem tài liệu . Thêm vào đó mỗi lần bạn thay đổi innerHTMLnhư vậy, bạn đã phá hủy những người nghe sự kiện trước đó!

Không cần cấu trúc lại mã của bạn nhiều, bạn có thể chuyển dữ liệu với các thuộc tính dữ liệu. Vì vậy, hãy sử dụng mã như thế này:

for (i = 0; i < EmoteURLLines.length; i++) {
    if (checkIMG (EmoteURLLines[i])) {
        localStorage.setItem ("nameEmotes", JSON.stringify (EmoteNameLines));
        localStorage.setItem ("urlEmotes", JSON.stringify (EmoteURLLines));
        localStorage.setItem ("usageEmotes", JSON.stringify (EmoteUsageLines));
        if (i == 0) {
            console.log (resetSlot ());
        }
        emoteTab[2].innerHTML  += '<span style="cursor:pointer;" id="' 
                                + EmoteNameLines[i] 
                                + '" data-usage="' + EmoteUsageLines[i] + '">'
                                + '<img src="' + EmoteURLLines[i] + '" /></span>'
                                ;
    } else {
        alert ("The maximum emote (" + EmoteNameLines[i] + ") size is (36x36)");
    }
}
//-- Only add events when innerHTML overwrites are done.
var targetSpans = emoteTab[2].querySelectorAll ("span[data-usage]");
for (var J in targetSpans) {
    targetSpans[J].addEventListener ("click", appendEmote, false);
}

Nơi appendEmote giống như:

function appendEmote (zEvent) {
    //-- this and the parameter are special in event handlers.  see the linked doc.
    var emoteUsage  = this.getAttribute ("data-usage");
    shoutdata.value += emoteUsage;
}


CẢNH BÁO:

  • Mã của bạn sử dụng lại cùng một id cho một số phần tử. Đừng làm điều này, nó không hợp lệ. Một ID nhất định chỉ nên xuất hiện một lần trên mỗi trang.
  • Mỗi khi bạn sử dụng .outerHTMLhoặc .innerHTML, bạn sẽ dọn rác bất kỳ trình xử lý sự kiện nào trên các nút bị ảnh hưởng. Nếu bạn sử dụng phương pháp này, hãy cẩn thận với thực tế đó.

1
Tôi nhận được lỗi này: của router Lỗi Loại: Object 3 không có phương pháp 'addEventListener'
ECMAScript

Vậy thì bạn đang làm sai. Liên kết tới tập lệnh đầy đủ đã gây ra lỗi đó VÀ liên kết tới trang đích mà tập lệnh đó chạy.
Brock Adams

2
Đã sửa lỗi tôi đã sử dụng: btnreset.onclick = function () {resetEmotes (); }; Cảm ơn!
ECMAScript

Rất vui vì bạn đã làm cho nó hoạt động, nhưng kỹ thuật đó sẽ chỉ hoạt động trong một số điều kiện và không thể di chuyển.
Brock Adams

Mã của tôi thực sự được mã hóa kém nên tôi đang viết mã toàn bộ và sử dụng jQuery. Cảm ơn!
ECMAScript

3

Tôi đã nhận lỗi (Tôi đang sử dụng Vue) và tôi chuyển tôi onclick="someFunction()"đến @click="someFunction"và bây giờ họ đang làm việc.


câu hỏi không liên quan đến Vue
Dave Manuel

-2

Nếu hàm không được xác định khi sử dụng hàm đó trong html, chẳng hạn như onclick = 'function ()', điều đó có nghĩa là hàm đang ở trong một lệnh gọi lại, trong trường hợp của tôi là 'DOMContentLoaded'.


1
Đây không phải là một câu trả lời. Bạn có thể đăng nó dưới dạng nhận xét (bằng cách xây dựng một số danh tiếng thích hợp). Vui lòng đọc Làm thế nào để tôi viết một câu trả lời tốt?
EhsanT
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.