Bagaimana saya bisa mereferensikan elemen skrip yang memuat javascript yang sedang berjalan?
Inilah situasinya. Saya memiliki skrip "master" yang dimuat tinggi di halaman, hal pertama di bawah tag HEAD.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<script type="text/javascript" src="scripts.js"></script>
Ada skrip di "scripts.js" yang harus dapat melakukan pemuatan skrip lain berdasarkan permintaan. Metode normal tidak cukup berfungsi untuk saya karena saya perlu menambahkan skrip baru tanpa merujuk tag HEAD, karena elemen HEAD belum selesai render:
document.getElementsByTagName('head')[0].appendChild(v);
Yang ingin saya lakukan adalah mereferensikan elemen skrip yang memuat skrip saat ini sehingga saya kemudian dapat menambahkan tag skrip baru yang dimuat secara dinamis ke dalam DOM setelahnya.
<script type="text/javascript" src="scripts.js"></script>
loaded by scripts.js--><script type="text/javascript" src="new_script1.js"></script>
loaded by scripts.js --><script type="text/javascript" src="new_script2.js"></script>
javascript
element
parent
Shog9
sumber
sumber
Jawaban:
Cara mendapatkan elemen skrip saat ini:
1. Gunakan
document.currentScript
document.currentScript
akan mengembalikan<script>
elemen yang skripnya sedang diproses.Manfaat
defer
&async
)Masalah
<script type="module">
2. Pilih skrip berdasarkan id
Memberi script atribut id akan memungkinkan Anda dengan mudah memilihnya dengan id dari dalam menggunakan
document.getElementById()
.Manfaat
defer
&async
)Masalah
id
atribut dapat menyebabkan perilaku aneh untuk skrip di beberapa browser untuk beberapa kasus tepi3. Pilih skrip menggunakan
data-*
atributDengan memberikan
data-*
atribut pada skrip, Anda dapat dengan mudah memilihnya dari dalam.Ini memiliki sedikit manfaat dibandingkan opsi sebelumnya.
Manfaat
defer
&async
)Masalah
querySelector()
tidak memenuhi semua browserid
atribut<script>
denganid
kasus tepi.4. Pilih skrip berdasarkan src
Alih-alih menggunakan atribut data, Anda dapat menggunakan pemilih untuk memilih skrip menurut sumber:
Di embed.js:
Manfaat
defer
&async
)Masalah
id
atribut5. Ulangi semua skrip untuk menemukan yang Anda inginkan
Kami juga dapat mengulangi setiap elemen skrip dan memeriksa masing-masing satu per satu untuk memilih yang kami inginkan:
Ini memungkinkan kami menggunakan kedua teknik sebelumnya di browser lama yang tidak mendukung
querySelector()
dengan baik dengan atribut. Sebagai contoh:Ini mewarisi manfaat dan masalah dari pendekatan apa pun yang diambil, tetapi tidak mengandalkan
querySelector()
sehingga akan bekerja di browser lama.6. Dapatkan skrip yang dieksekusi terakhir
Karena skrip dieksekusi secara berurutan, elemen skrip terakhir akan sangat sering menjadi skrip yang sedang berjalan:
Manfaat
Masalah
defer
&async
)sumber
script
berada dalamtemplate
dimasukkan dalam bayangan DOMKarena skrip dieksekusi secara berurutan, tag skrip yang saat ini dieksekusi selalu menjadi tag skrip terakhir pada halaman sampai saat itu. Jadi, untuk mendapatkan tag skrip, Anda dapat melakukan:
sumber
Mungkin hal termudah untuk dilakukan adalah memberikan
id
atribut tag tag Anda .sumber
Script dijalankan secara berurutan hanya jika mereka tidak memiliki atribut "penangguhan" atau "async". Mengetahui salah satu atribut ID / SRC / TITLE yang mungkin dari tag script dapat bekerja juga dalam kasus-kasus itu. Jadi saran Greg dan Justin benar.
Sudah ada proposal untuk
document.currentScript
di daftar WHATWG.EDIT : Firefox> 4 sudah menerapkan properti yang sangat berguna ini tetapi tidak tersedia di IE11 yang terakhir saya periksa dan hanya tersedia di Chrome 29 dan Safari 8.
EDIT : Tidak ada yang menyebutkan koleksi "document.scripts" tapi saya percaya bahwa yang berikut ini mungkin merupakan alternatif lintas browser yang baik untuk mendapatkan skrip yang sedang berjalan:
sumber
Berikut adalah sedikit polyfill yang memanfaatkan
document.CurrentScript
jika ada dan kembali menemukan skrip dengan ID.Jika Anda memasukkan ini di bagian atas setiap tag skrip saya percaya Anda akan dapat secara konsisten mengetahui tag skrip mana yang sedang dipecat, dan Anda juga akan dapat mereferensikan tag skrip tersebut dalam konteks panggilan balik asinkron.
Belum diuji, jadi tinggalkan umpan balik untuk orang lain jika Anda mencobanya.
sumber
id
atribut tidak valid dalamscript
elemen sekalipun. Jenis masalah apa yang bisa dihasilkan oleh pendekatan ini?id
atribut.id
,,class
danslot
didefinisikan pada level DOM, bukan level HTML. Jika Anda pergi ke atribut global dalam HTML dan menggulir melewati daftar, Anda akan menemukan "Standar DOM mendefinisikan persyaratan agen pengguna untuk atribut kelas, id, dan slot untuk setiap elemen di namespace apa pun." diikuti oleh "Atribut class, id, dan slot dapat ditentukan pada semua elemen HTML." Spesifikasi DOM membahasnya di sini .Ini harus berfungsi saat memuat halaman dan ketika tag skrip ditambahkan dengan javascript (mis. Dengan ajax)
sumber
Ikuti langkah-langkah sederhana ini untuk mendapatkan referensi ke blok skrip eksekusi saat ini:
Contoh (ABCDE345678 adalah ID unik) :
btw, untuk kasus Anda, Anda cukup menggunakan metode document.write () kuno untuk memasukkan skrip lain. Seperti yang Anda sebutkan bahwa DOM belum dirender, Anda dapat memanfaatkan fakta bahwa browser selalu menjalankan skrip dalam urutan linier (kecuali untuk yang ditangguhkan yang akan dirender nanti), sehingga sisa dokumen Anda masih "tidak ada". Apa pun yang Anda tulis melalui document.write () akan ditempatkan tepat setelah skrip penelepon.
Contoh halaman HTML asli :
Konten script.js :
Setelah diberikan, struktur DOM akan menjadi:
sumber
Suatu pendekatan untuk berurusan dengan skrip async & deferred adalah untuk memanfaatkan penangan onload- menetapkan penangan onload untuk semua tag skrip dan yang pertama yang dijalankan harus menjadi milik Anda.
sumber
Untuk mendapatkan skrip, skrip yang saat ini dimuat dapat Anda gunakan
Anda harus menyimpan referensi di awal skrip Anda, sehingga Anda dapat menelepon nanti
sumber
Pertimbangkan algoritma ini. Ketika skrip Anda dimuat (jika ada beberapa skrip identik), lihat melalui document.scripts, cari skrip pertama dengan atribut "src" yang benar, dan simpan dan tandai sebagai 'dikunjungi' dengan atribut data atau className unik.
Saat skrip berikutnya dimuat, pindai lagi melalui dokumen.kripsinya, lewati setiap skrip yang sudah ditandai sebagai dikunjungi. Ambil contoh skrip yang belum dikunjungi pertama kali.
Ini mengasumsikan bahwa skrip identik kemungkinan akan mengeksekusi dalam urutan di mana mereka dimuat, dari head ke body, dari atas ke bawah, dari sinkron ke asinkron.
Ini akan memindai seluruh skrip untuk skrip pencocokan pertama yang tidak ditandai dengan atribut khusus.
Kemudian tandai simpul itu, jika ditemukan, dengan atribut data sehingga pemindaian selanjutnya tidak akan memilihnya. Ini mirip dengan algoritma BFS dan DFS traversal grafik di mana node dapat ditandai sebagai 'dikunjungi' untuk mencegah kunjungan kembali.
sumber
Saya punya ini, yang bekerja di FF3, IE6 & 7. Metode-metode dalam skrip yang dimuat berdasarkan permintaan tidak tersedia sampai pemuatan halaman selesai, tetapi ini masih sangat berguna.
sumber
Jika Anda dapat menganggap nama file skrip, Anda dapat menemukannya. Saya hanya benar-benar menguji fungsi berikut di Firefox sejauh ini.
sumber
Saya telah menemukan kode berikut ini sebagai yang paling konsisten, berkinerja, dan sederhana.
sumber