<div class="title">
I am text node
<a class="edit">Edit</a>
</div>
Saya ingin mendapatkan "Saya node teks", tidak ingin menghapus tag "edit", dan memerlukan solusi lintas browser.
javascript
jquery
Val
sumber
sumber
Jawaban:
Ini mendapatkan
contents
elemen yang dipilih, dan menerapkan fungsi filter padanya. Fungsi filter hanya mengembalikan node teks (yaitu node dengannodeType == Node.TEXT_NODE
).sumber
text()
karenafilter
fungsi mengembalikan node itu sendiri, bukan konten node.jQuery("*").each(function() { console.log(this.nodeType); })
dan saya mendapatkan 1 untuk semua jenis node.Anda bisa mendapatkan nodeValue dari childNode pertama menggunakan
http://jsfiddle.net/TU4FB/
sumber
null
nilai kembali.Jika Anda bermaksud mendapatkan nilai node teks pertama dalam elemen, kode ini akan berfungsi:
Anda dapat melihat ini beraksi di sini: http://jsfiddle.net/ZkjZJ/
sumber
curNode.nodeType == 3
bukannodeName
juga.curNode.nodeType == Node.TEXT_NODE
(perbandingan numerik lebih cepat tetapi curNode.nodeType == 3 tidak dapat dibaca - node apa yang memiliki angka 3?)curNode.NodeType === Node.TEXT_NODE
. Perbandingan ini terjadi dalam loop iterasi yang mungkin tidak diketahui. Membandingkan dua angka kecil lebih baik daripada membandingkan string dengan panjang yang berbeda (pertimbangan waktu dan ruang). Pertanyaan yang benar untuk ditanyakan dalam situasi ini adalah "jenis / tipe node apa yang saya miliki?", Dan bukan "nama apa yang saya miliki?" developer.mozilla.org/en-US/docs/Web/API/Node/nodeTypechildNodes
, ketahuilah bahwa node elemen dapat memiliki lebih dari satu node teks. Dalam solusi umum, seseorang mungkin perlu menentukan instance node teks mana di dalam node elemen yang ingin Anda targetkan (pertama, kedua, ketiga, dll ...).Solusi JS asli lainnya yang dapat berguna untuk elemen "kompleks" atau sangat bertingkat adalah dengan menggunakan NodeIterator . Letakkan
NodeFilter.SHOW_TEXT
sebagai argumen kedua ("whatToShow"), dan lakukan iterasi hanya pada anak node teks elemen tersebut.Anda juga bisa menggunakan
TreeWalker
. Perbedaan antara keduanya adalahNodeIterator
iterator linier sederhana, sementaraTreeWalker
memungkinkan Anda untuk menavigasi melalui saudara dan leluhur juga.sumber
JavaScript Murni: Minimalis
Pertama, selalu ingat ini saat mencari teks di DOM.
MDN - Spasi di DOM
Masalah ini akan membuat Anda memperhatikan struktur XML / HTML Anda.
Dalam contoh JavaScript murni ini, saya memperhitungkan kemungkinan beberapa node teks yang dapat disisipkan dengan node jenis lain . Namun, awalnya, saya tidak memberikan penilaian pada spasi, membiarkan tugas pemfilteran itu ke kode lain.
Dalam versi ini, saya meneruskan
NodeList
dari kode panggilan / klien.Tentu saja, dengan menguji
node.hasChildNodes()
terlebih dahulu, tidak perlu menggunakanfor
loop pra-tes .JavaScript Murni: Kuat
Di sini fungsi tersebut
getTextById()
menggunakan dua fungsi pembantu:getStringsFromChildren()
danfilterWhitespaceLines()
.getStringsFromChildren ()
filterWhitespaceLines ()
getTextById ()
Selanjutnya, nilai yang dikembalikan (Array, atau null) dikirim ke kode klien tempat nilai itu harus ditangani. Mudah-mudahan, array harus memiliki elemen string teks asli, bukan baris spasi.
String kosong (
""
) tidak dikembalikan karena Anda memerlukan node teks untuk menunjukkan dengan benar keberadaan teks yang valid. Returning (""
) dapat memberikan kesan yang salah bahwa node teks ada, membuat seseorang berasumsi bahwa mereka dapat mengubah teks dengan mengubah nilai.nodeValue
. Ini salah, karena node teks tidak ada dalam kasus string kosong.Contoh 1 :
Contoh 2 :
Masalahnya muncul saat Anda ingin membuat HTML Anda mudah dibaca dengan memberi jarak. Sekarang, meskipun tidak ada teks valid yang dapat dibaca manusia, masih ada node teks dengan
"\n"
karakter newline ( ) di.nodeValue
propertinya.Manusia melihat contoh satu dan dua sebagai fungsi yang setara - elemen kosong menunggu untuk diisi. DOM berbeda dengan penalaran manusia. Inilah sebabnya mengapa
getStringsFromChildren()
fungsi harus menentukan apakah ada node teks dan mengumpulkan.nodeValue
nilai - nilai ke dalam array.Dalam contoh dua, dua node teks memang ada dan
getStringFromChildren()
akan mengembalikan.nodeValue
keduanya ("\n"
). Namun,filterWhitespaceLines()
menggunakan ekspresi reguler untuk memfilter baris karakter spasi putih murni.Apakah mengembalikan karakter
null
baris baru ("\n"
) sebagai bentuk kebohongan ke klien / kode panggilan? Dalam istilah manusia, tidak. Dalam istilah DOM, ya. Namun, masalahnya di sini adalah mendapatkan teks, bukan mengeditnya. Tidak ada teks manusia untuk kembali ke kode panggilan.Seseorang tidak akan pernah tahu berapa banyak karakter baris baru yang mungkin muncul di HTML seseorang. Membuat penghitung yang mencari karakter baris baru "kedua" tidak dapat diandalkan. Mungkin tidak ada.
Tentu saja, lebih jauh lagi, masalah pengeditan teks dalam
<p></p>
elemen kosong dengan spasi ekstra (contoh 2) mungkin berarti menghancurkan (mungkin, melewatkan) semua kecuali satu simpul teks di antara tag paragraf untuk memastikan elemen tersebut berisi dengan tepat apa itu. seharusnya ditampilkan.Terlepas dari itu, kecuali untuk kasus di mana Anda melakukan sesuatu yang luar biasa, Anda akan memerlukan cara untuk menentukan
.nodeValue
properti node teks mana yang memiliki teks yang benar dan dapat dibaca manusia yang ingin Anda edit.filterWhitespaceLines
membuat kita setengah jalan ke sana.Pada titik ini Anda mungkin memiliki keluaran yang terlihat seperti ini:
Tidak ada jaminan bahwa kedua string ini berdekatan satu sama lain di DOM, jadi menggabungkan keduanya dengan
.join()
dapat membuat komposit yang tidak wajar. Sebagai gantinya, dalam kode yang memanggilgetTextById()
, Anda harus memilih string mana yang ingin Anda gunakan.Uji hasilnya.
Seseorang dapat menambahkan
.trim()
di dalamgetStringsFromChildren()
untuk menghilangkan spasi kosong di depan dan di belakang (atau untuk mengubah sekumpulan spasi menjadi string panjang nol (""
), tetapi bagaimana Anda bisa mengetahui apriori apa yang mungkin dibutuhkan setiap aplikasi untuk terjadi pada teks (string) setelah ditemukan? Anda tidak, jadi serahkan itu pada implementasi tertentu, dan biarkangetStringsFromChildren()
generik.Mungkin ada kalanya tingkat kekhususan ini (
target
dan semacamnya) tidak diperlukan. Itu hebat. Gunakan solusi sederhana dalam kasus tersebut. Namun, algoritme umum memungkinkan Anda mengakomodasi situasi yang sederhana dan kompleks.sumber
Versi ES6 yang mengembalikan konten node #text pertama
sumber
.from()
untuk membuat instance array yang disalin dangkal. (2) Penggunaan.find()
untuk melakukan perbandingan string menggunakan.nodeName
. Menggunakannode.NodeType === Node.TEXT_NODE
akan lebih baik. (3) Mengembalikan string kosong bila tidak ada nilai,,null
lebih benar jika tidak ada simpul teks yang ditemukan. Jika tidak ada simpul teks yang ditemukan, seseorang mungkin perlu membuatnya! Jika Anda mengembalikan string kosong``""
Anda dapat memberikan kesan palsu bahwa node teks ada dan dapat dimanipulasi secara normal. Intinya, mengembalikan string kosong adalah kebohongan putih dan sebaiknya dihindari.[...node.childNodes]
untuk mengonversi HTMLCollection menjadi Array.text() - for jquery
sumber
a
elemen juga: jsfiddle.net/ekHJH.
di awal pemilih Anda, yang berarti Anda benar-benar mendapatkan tekstitle
elemen, bukan elemen denganclass="title"
.innerText
adalah konvensi IE lama yang baru saja diadopsi. Dalam hal skrip DOM standar,node.nodeValue
adalah bagaimana seseorang mengambil teks dari sebuah simpul teks.Ini akan mengabaikan whitespace juga jadi, Anda tidak akan pernah mendapatkan Blank textNodes..code menggunakan core Javascript.
Periksa di jsfiddle: - http://jsfiddle.net/webx/ZhLep/
sumber
curNode.nodeType === Node.TEXT_NODE
akan lebih baik. Menggunakan perbandingan string dan ekspresi reguler dalam satu loop adalah solusi berkinerja rendah, terutama karena besarnyaoDiv.childNodes.length
kenaikan. Algoritme ini memecahkan pertanyaan spesifik OP, tetapi berpotensi dengan biaya kinerja yang buruk. Jika pengaturan, atau jumlah, node teks berubah, maka solusi ini tidak dapat dijamin untuk menghasilkan keluaran yang akurat. Dengan kata lain, Anda tidak dapat menargetkan node teks yang Anda inginkan. Anda berada di bawah kekuasaan struktur HTML dan pengaturan teks di sana.Anda juga dapat menggunakan
text()
pengujian node XPath untuk mendapatkan node teks saja. Sebagai contohsumber
Ini adalah solusi saya di ES6 untuk membuat string yang mengandung teks gabungan dari semua childnodes (rekursif) . Perhatikan bahwa kunjungi juga shdowroot of childnodes.
Solusi ini terinspirasi oleh solusi https://stackoverflow.com/a/41051238./1300775 .
sumber