it-swarm-vi.com

'quan sát' trên 'MutingObserver': tham số 1 không thuộc loại 'Nút'

Tôi đang tạo tiện ích mở rộng Chrome và cố gắng bao gồm một văn bản nhỏ bên cạnh nút GỬI của hộp soạn thảo gMail.

Tôi đang sử dụng MutingObserver để biết khi nào cửa sổ hộp soạn thảo xuất hiện. Tôi đang làm điều này bằng cách quan sát một phần tử với lớp no vì phần tử hộp soạn thảo được tạo như là phần tử con của phần tử này (lớp no).

Khi người dùng nhấp vào nút soạn thảo và cửa sổ hộp soạn thảo xuất hiện, sau đó tôi đặt một phần tử bên cạnh nút GỬI bằng phương thức .after(). Tên lớp nút GỬI là .gU.Up.

Đây là tên lớp thực sự của gMail và cũng khá kỳ lạ.

Dưới đây là mã tôi đang sử dụng:

var composeObserver = new MutationObserver(function(mutations){ 
    mutations.forEach(function(mutation){
        mutation.addedNodes.forEach(function(node){
            $(".gU.Up").after("<td> <div> Hi </div> </td>");
        });
    });
});

var composeBox = document.querySelectorAll(".no")[2];
var config = {childList: true};
composeObserver.observe(composeBox,config);

Vấn đề là tôi liên tục gặp lỗi sau:

Uncaught TypeError: Failed to execute 'observe' on 'MutationObserver': parameter 1 is not of type 'Node'

Có ai giúp được không? Tôi đã thử khá nhiều thứ và cũng đã xem xét các câu trả lời khác ở đây, nhưng vẫn không thể thoát khỏi lỗi này.

Đây là tập tin manifest.json của tôi:

{
    "manifest_version": 2,
    "name": "Gmail Extension",
    "version": "1.0",

    "browser_action": {
        "default_icon": "icon19.png",   
        "default_title": "Sales Analytics Sellulose"    
    },

    "background": {
        "scripts": ["eventPage.js"],
        "persistent": false
    },

    "content_scripts": [
    {
        "matches": ["https://mail.google.com/*"],
        "js": ["jquery-3.1.1.js", "insQ.min.js", "gmail_cs.js"]
    }
],

    "web_accessible_resources":[
        "compose_icon.png",
        "sellulosebar_icon.png" 
    ]
}

P.S. Tôi đã thử thư viện chèn, nhưng nó có một vài thiếu sót. Nó không cho phép tôi cụ thể về những thay đổi trong yếu tố cụ thể. Tôi vẫn chưa thử thư viện đột biến, nhưng vì nó sử dụng M mutObserver, tôi đoán rằng vấn đề sẽ còn tồn tại.

Đã thêm từ nhận xét:
Đúng là bộ chọn không cho tôi một nút. Tôi đã kiểm tra trong giao diện điều khiển, nó đưa ra một đối tượng. Tôi cũng đã kiểm tra trong bảng điều khiển và nó đang chọn yếu tố thích hợp mà tôi muốn được quan sát. 

Tuy nhiên, khi tôi thêm console.log cho phần tử được chọn, nó sẽ hiển thị dưới dạng không xác định. Điều đó có nghĩa là, bạn có thể đúng về việc thực thi mã trước khi các nút xuất hiện. Bạn có thể cho tôi biết làm thế nào để đảm bảo sự chậm trễ xảy ra? 'setTimeout' sẽ hoạt động? Làm thế nào nó hoạt động trong trường hợp của MutingObserver?

12
geet mehar

Như tôi đã đề cập trong một nhận xét và Xan đã nêu câu trả lời, lỗi cho thấy rõ rằng kết quả của document.querySelectorAll(".no")[2] không đánh giá thành Nút

Từ thông tin bạn cung cấp trong một bình luận, rõ ràng vấn đề là nút bạn muốn quan sát không tồn tại khi mã của bạn thực thi. Có nhiều cách để trì hoãn việc thực thi mã của bạn cho đến khi nút đó khả dụng. Một số khả năng là:

  1. Sử dụng vòng lặp setTimeout để thăm dò cho đến khi bạn phát hiện ra rằng phần tử mà bạn muốn đặt MutingObserver khả dụng:

    function addObserverIfDesiredNodeAvailable() {
        var composeBox = document.querySelectorAll(".no")[2];
        if(!composeBox) {
            //The node we need does not exist yet.
            //Wait 500ms and try again
            window.setTimeout(addObserverIfDesiredNodeAvailable,500);
            return;
        }
        var config = {childList: true};
        composeObserver.observe(composeBox,config);
    }
    addObserverIfDesiredNodeAvailable();
    

    Điều này sẽ tìm thấy nút thích hợp tương đối ngắn sau khi nó tồn tại trong DOM. Khả năng tồn tại của phương pháp này phụ thuộc vào khoảng thời gian sau khi chèn nút mục tiêu, bạn cần người quan sát được đặt trên nó. Rõ ràng, bạn có thể điều chỉnh độ trễ giữa các lần bỏ phiếu dựa trên nhu cầu của bạn.

  2. Tạo một MutingObserver khác để xem nút tổ tiên cao hơn trong DOM để chèn nút mà bạn muốn đặt trình quan sát chính của mình vào đó. Mặc dù điều này sẽ tìm thấy nút thích hợp ngay lập tức khi nó được chèn, nhưng nó có thể khá tốn tài nguyên (CPU), tùy thuộc vào mức độ bạn phải quan sát trong DOM và mức độ hoạt động của nó đối với các thay đổi của DOM.
13
Makyen

Lỗi này có nghĩa là document.querySelectorAll(".no")[2] không phải là Node.

Rất có thể điều này có nghĩa là không có yếu tố như vậy; querySelectorAll sẽ luôn trả về NodeList, ngay cả khi nó trống; truy cập các thành viên không tồn tại của danh sách thành công mà không có lỗi thời gian chạy, nhưng trả về undefined: theo nghĩa này, NodeList hoạt động như một mảng.

"Đợi, nhưng có! Tôi chạy mã này trong bảng điều khiển và nó hoạt động!" bạn có thể kêu lên đáng kể. Đó là bởi vì tại thời điểm bạn thực thi nó, rất lâu sau khi tài liệu tải xong, những yếu tố đó tồn tại.

Vì vậy, bạn cần chờ phần tử gốc này được thêm vào; có khả năng, với một MutationObserver khác để thực hiện công việc.

3
Xan

Hãy thử sử dụng cái này với jQuery.

Nếu bạn đang phát triển Tiện ích mở rộng Chrome và bạn đang nhận phần tử HTML (Nút) từ trang hoặc DOM trong content_script , thì bạn sẽ nhận được Object và Node sẽ được trả về làm thuộc tính của Object. Sau đó, bạn có thể lấy Node từ Object để truyền vào phương thức observe(Node,config).

Thí dụ

var node = $("#elementId");  //this is wrong because if you logged this in the console you will get Object

var node = $("#elementId")[0];  //This gives the first property of the Object returned, and this is correct because if you logged this in the console you will get the Node element for which you want to detect changes in the DOM.
1
Code Me