pengembangan-web-mp-pd.com

'amati' pada 'MutationObserver': parameter 1 bukan tipe 'Node'

Saya membuat ekstensi Chrome dan mencoba memasukkan teks kecil di sebelah tombol KIRIM dari kotak penulisan gMail.

Saya menggunakan MutationObserver untuk mengetahui kapan jendela kotak penulisan muncul. Saya melakukan ini dengan mengamati elemen dengan kelas no karena elemen kotak penulisan dibuat sebagai anak dari elemen ini (kelas no).

Ketika pengguna mengklik tombol penulisan dan jendela kotak penulisan muncul, maka saya menempatkan elemen di samping tombol KIRIM menggunakan metode .after(). Nama kelas tombol KIRIM adalah .gU.Up.

Ini adalah nama kelas gMail yang sebenarnya dan juga cukup aneh.

Di bawah ini adalah kode yang saya gunakan:

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);

Masalahnya adalah saya terus-menerus mendapatkan kesalahan berikut:

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

Adakah yang bisa membantu? Saya telah mencoba beberapa hal dan juga melihat jawaban lain di sini, tetapi masih tidak dapat menyingkirkan kesalahan ini.

Ini file manifest.json saya:

{
    "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. Saya sudah mencoba perpustakaan insertionquery, tetapi memiliki beberapa kekurangan. Itu tidak membiarkan saya menjadi spesifik tentang perubahan pada elemen tertentu. Saya belum mencoba perpustakaan mutationsummary, tetapi karena menggunakan MutationObserver, saya pikir masalah ini akan tetap ada.

Ditambahkan dari komentar:
Memang benar bahwa pemilih tidak memberi saya sebuah simpul. Saya memeriksa konsol, itu memberi objek. Saya juga memeriksa konsol dan memilih elemen yang sesuai yang ingin saya amati. 

Namun, ketika saya menambahkan console.log untuk elemen yang dipilih, itu ditampilkan sebagai tidak terdefinisi. Yang berarti, Anda mungkin benar tentang mengeksekusi kode sebelum ada node. Bisakah Anda memberi tahu saya cara memastikan penundaan itu terjadi? akankah 'setTimeout' berfungsi? Bagaimana cara kerjanya dalam kasus MutationObserver?

12
geet mehar

Seperti yang saya sebutkan dalam komentar, dan Xan menyatakan jawaban, kesalahannya memperjelas bahwa hasil document.querySelectorAll(".no")[2] tidak mengevaluasi ke Node

Dari informasi yang Anda berikan dalam komentar, jelas bahwa masalahnya adalah bahwa simpul yang ingin Anda amati tidak ada ketika kode Anda dijalankan. Ada banyak cara untuk menunda eksekusi kode Anda hingga simpul itu tersedia. Beberapa kemungkinan adalah:

  1. Menggunakan loop setTimeout untuk polling hingga Anda mendeteksi bahwa elemen tempat Anda ingin meletakkan MutationObserver tersedia:

    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();
    

    Ini akan menemukan simpul yang sesuai relatif tidak lama setelah itu ada di DOM. Kelangsungan hidup metode ini tergantung pada berapa lama setelah penyisipan node target Anda perlu pengamat untuk ditempatkan di atasnya. Jelas, Anda dapat menyesuaikan penundaan antara upaya polling berdasarkan kebutuhan Anda.

  2. Buat MutationObserver lain untuk menonton simpul leluhur yang lebih tinggi di DOM untuk penyisipan simpul tempat Anda ingin menempatkan pengamat utama Anda. Meskipun ini akan menemukan node yang tepat segera ketika dimasukkan, mungkin cukup intensif (CPU) sumber daya, tergantung pada seberapa tinggi DOM yang harus Anda amati dan seberapa banyak aktivitas yang ada sehubungan dengan perubahan DOM.
13
Makyen

Kesalahan ini berarti document.querySelectorAll(".no")[2] bukan Node.

Kemungkinan besar ini berarti tidak ada elemen seperti itu; querySelectorAll akan selalu mengembalikan NodeList, meskipun kosong; mengakses anggota yang tidak ada dari daftar berhasil tanpa kesalahan runtime, tetapi mengembalikan undefined: dalam pengertian ini, NodeList bertindak seperti array.

"Tunggu, tetapi ternyata berhasil! Saya menjalankan kode ini di konsol dan berfungsi!" Anda dapat berseru secara dramatis. Itu karena pada saat Anda menjalankannya, lama setelah dokumen selesai memuat, elemen-elemen itu ada.

Jadi, Anda perlu menunggu elemen root ini ditambahkan; kemungkinan, dengan MutationObserver lain untuk melakukan pekerjaan.

3
Xan

Coba gunakan ini dengan jQuery.

Jika Anda mengembangkan Ekstensi Chrome dan Anda mendapatkan elemen HTML (Node) dari halaman atau DOM di content_script , maka Anda akan mendapatkan Object dan Node akan dikembalikan sebagai properti dari Object. Anda kemudian bisa mendapatkan Node dari Object untuk dilewatkan ke metode observe(Node,config).

Contoh

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