2014-09-29 32 views
44

Tôi phải sử dụng JavaScript vani cho một dự án. Tôi có một vài chức năng, một trong số đó là một nút mở menu. Nó hoạt động trên các trang có id mục tiêu, nhưng gây ra lỗi trên các trang mà id không tồn tại. Trên những trang mà hàm không thể tìm thấy id, tôi nhận được lỗi "Không thể đọc thuộc tính" addEventListener 'của null "và không có hàm nào khác của tôi hoạt động.Không thể đọc thuộc tính 'addEventListener' của null

Dưới đây là mã cho nút mở menu.

function swapper() { 
toggleClass(document.getElementById('overlay'), 'open'); 
} 

var el = document.getElementById('overlayBtn'); 
el.addEventListener('click', swapper, false); 

var text = document.getElementById('overlayBtn'); 
text.onclick = function(){ 
this.innerHTML = (this.innerHTML === "Menu") ? "Close" : "Menu"; 
return false; 
}; 

Làm cách nào để giải quyết vấn đề này? Tôi có lẽ cần phải tất cả các mã này bọc trong một chức năng khác hoặc sử dụng một if/else tuyên bố để nó chỉ tìm kiếm id trên các trang cụ thể, nhưng không chắc chắn chính xác.

+1

bạn có thể hiển thị mã html hay không. có vẻ như không thể tìm thấy phần tử có id 'overlayBtn' – BlaShadow

+1

Trên những trang mà hàm không thể tìm thấy id, tôi nhận được lỗi "Không thể đọc thuộc tính" addEventListener 'của null "và không có hàm nào khác của tôi hoạt động. Tôi nghĩ câu trả lời là khá nhiều trong câu hỏi. Bạn không thể tìm thấy phần tử, vì vậy bạn không thể thêm một trình xử lý sự kiện vào nó ... – Etai

+1

Nó có thể đơn giản xảy ra nếu bạn đã sử dụng 'lớp' trong html của bạn thay vì' id' và bạn gọi một 'getElementById' trong tập lệnh của bạn. – Deke

Trả lời

89

Tôi nghĩ rằng cách tiếp cận đơn giản nhất là nên chỉ kiểm tra xem el không phải là null trước khi thêm một người biết lắng nghe sự kiện:

var el = document.getElementById('overlayBtn'); 
if(el){ 
    el.addEventListener('click', swapper, false); 
} 
+0

tuyệt vời. đã làm được điều đó. Tôi cũng đã chuyển hàm onclick vào câu lệnh if. Tôi đã đăng mã cuối cùng bên dưới. – morocklo

+1

nó sẽ là 'null' trước khi phản ứng thành phần đã gắn kết! –

2

Nhờ @ Rob M. sự giúp đỡ của ông. Đây là những gì khối cuối cùng của mã trông giống như:

function swapper() { 
    toggleClass(document.getElementById('overlay'), 'open'); 
} 

var el = document.getElementById('overlayBtn'); 
if (el){ 
    el.addEventListener('click', swapper, false); 

    var text = document.getElementById('overlayBtn'); 
    text.onclick = function(){ 
    this.innerHTML = (this.innerHTML === "Menu") ? "Close" : "Menu"; 
    return false; 
    }; 
} 
11

Tôi đã nhận được lỗi tương tự, nhưng thực hiện một kiểm tra null dường như không giúp đỡ.

Giải pháp tôi tìm thấy là bọc chức năng của mình bên trong trình xử lý sự kiện để toàn bộ tài liệu kiểm tra khi DOM tải xong.

document.addEventListener('DOMContentLoaded', function() { 
    el.addEventListener('click', swapper, false); 
}); 

Tôi nghĩ rằng điều này là do tôi đang sử dụng một khung (Góc) đang thay đổi các lớp HTML và ID của tôi theo cách động.

10

Tôi gặp phải tình huống tương tự. Điều này có thể do tập lệnh được thực thi trước khi tải trang. Bằng cách đặt tập lệnh ở cuối trang, tôi đã giải quyết được vấn đề.

+1

Vâng, tôi nghĩ có nhiều giải pháp cho vấn đề này tùy thuộc vào kịch bản. – rpeg

0

Như những người khác đã nói vấn đề là tập lệnh được thực thi trước khi trang (và đặc biệt là phần tử đích) được tải.

Nhưng tôi không thích giải pháp sắp xếp lại nội dung.

Giải pháp ưu tiên là đặt trình xử lý sự kiện vào sự kiện tải trang và đặt Trình nghe ở đó. Điều đó sẽ đảm bảo trang và phần tử đích được tải trước khi thực thi nhiệm vụ. ví dụ

<script> 
    function onLoadFunct(){ 
      // set Listener here, also using suggested test for null 
    } 
    .... 
    </script> 

    <body onload="onLoadFunct()" ....> 
    ..... 
46

Dường như document.getElementById('overlayBtn'); đang trở lại null vì nó thực thi trước khi DOM đầy đủ tải.

Nếu bạn đặt dòng mã này dưới

window.onload=function(){ 
    -- put your code here 
} 

sau đó nó sẽ chạy mà không có vấn đề.

Ví dụ:

window.onload=function(){ 
    var mb = document.getElementById("b"); 
    mb.addEventListener("click", handler); 
    mb.addEventListener("click", handler2); 
} 


function handler() { 
    $("p").html("<br>" + $("p").text() + "<br>You clicked me-1!<br>"); 
} 

function handler2() { 
    $("p").html("<br>" + $("p").text() + "<br>You clicked me-2!<br>"); 
} 
0

Tôi đã một tập hợp các dấu ngoặc kép cùng với tên. Tôi đang sử dụng nút cập nhật để cập nhật báo giá cuối cùng được liên kết với một tên cụ thể nhưng khi nhấp vào nút cập nhật, nó không cập nhật. Tôi bao gồm mã bên dưới cho tệp server.js và tệp js bên ngoài (main.js).

main.js (js bên ngoài)

var update = document.getElementById('update'); 
if (update){ 
update.addEventListener('click', function() { 

    fetch('quotes', { 
    method: 'put', 
    headers: {'Content-Type': 'application/json'}, 
    body: JSON.stringify({ 
    'name': 'Muskan', 
    'quote': 'I find your lack of faith disturbing.' 
    }) 
})var update = document.getElementById('update'); 
if (update){ 
update.addEventListener('click', function() { 

    fetch('quotes', { 
    method: 'put', 
    headers: {'Content-Type': 'application/json'}, 
    body: JSON.stringify({ 
    'name': 'Muskan', 
    'quote': 'I find your lack of faith disturbing.' 
    }) 
}) 
.then(res =>{ 
    if(res.ok) return res.json() 
}) 
.then(data =>{ 
    console.log(data); 
    window.location.reload(true); 
}) 
}) 
} 

tập tin server.js

app.put('/quotes', (req, res) => { 
    db.collection('quotations').findOneAndUpdate({name: 'Vikas'},{ 
    $set:{ 
     name: req.body.name, 
     quote: req.body.quote 
    } 
    },{ 
    sort: {_id: -1}, 
    upsert: true 
    },(err, result) =>{ 
    if (err) return res.send(err); 
    res.send(result); 
    }) 

}) 
-1

Điều này là do nguyên tố này đã không được nạp vào thời điểm đó khi js bó đã được thực thi.

Tôi muốn di chuyển <script src="sample.js" type="text/javascript"></script> xuống dưới cùng của tệp index.html. Bằng cách này bạn có thể đảm bảo tập lệnh được thực hiện sau khi tất cả các phần tử html đã được phân tích cú pháp và hiển thị.

+0

Không đúng. Đây là suy nghĩ trường học cũ. Tải ở cuối sẽ làm chậm quá trình tải, như bạn đã nói, nhưng nó ** không đảm bảo DOM được vẽ hoàn toàn **. Tôi đã có các trang cũ sử dụng hack này không chạy vì vẽ DOM chậm hơn tải. [Câu trả lời này] (https://stackoverflow.com/a/30063375/2370483) ** đảm bảo ** DOM được vẽ trước khi thực thi. – Machavity

-2

Thêm tất cả người nghe sự kiện khi tải cửa sổ. Làm việc như một nét duyên dáng bất kể bạn đặt thẻ script ở đâu.

window.addEventListener("load", startup); 
function startup() { 
document.getElementById("el").addEventListener("click", myFunc); 
document.getElementById("el2").addEventListener("input", myFunc); 
} 
myFunc(){ 
} 
+0

Bản vẽ của trang đôi khi có thể mất nhiều thời gian hơn việc tải tập lệnh, vì vậy vị trí không quan trọng trong mọi trường hợp. Việc thêm trình nghe là cách ưu tiên, nhưng 'tải' cũng bị phản đối vì cùng lý do. [DOMContentLoaded] (https://stackoverflow.com/questions/2414750/difference-between-domcontentloaded-and-load-events) là cách ưa thích, vì nó chỉ cháy sau khi DOM được vẽ hoàn toàn. – Machavity

+0

Đó là một thử rất tốt, bạn. – statosdotcom

+0

Cảm ơn tôi sẽ cố gắng. Tôi nhận được câu trả lời từ mạng lưới Mozilla. Tôi nghĩ đó là một nguồn đáng tin cậy. –

Các vấn đề liên quan