Salah satu konsep yang lebih kuat yang saya tersandung baru -baru ini ialah idea pokok sintaks abstrak, atau AST. Sekiranya anda pernah mempelajari alkimia, anda mungkin ingat bahawa keseluruhan motivasi untuk alkimia adalah untuk mengetahui beberapa cara untuk mengubah emas tidak menjadi emas melalui kaedah saintifik atau arcane.
AST adalah seperti itu. Menggunakan ASTS, kita dapat mengubah markdown ke HTML, JSX ke JavaScript, dan banyak lagi.
Mengapa AST berguna?
Awal dalam karier saya, saya cuba menukar fail menggunakan kaedah mencari dan menggantikan. Ini akhirnya agak rumit, jadi saya cuba menggunakan ungkapan biasa. Saya akhirnya meninggalkan idea itu kerana ia begitu rapuh; Aplikasi ini pecah sepanjang masa kerana seseorang akan memasukkan teks dengan cara yang saya tidak jangkakan dan ia akan memecahkan ekspresi biasa saya menyebabkan seluruh aplikasi jatuh.
Sebabnya sangat sukar ialah HTML adalah fleksibel. Itu menjadikannya sangat sukar untuk menghuraikan menggunakan ungkapan biasa. Penggantian berasaskan rentetan seperti ini terdedah kepada pecah kerana ia mungkin terlepas perlawanan, terlalu banyak memadankan, atau melakukan sesuatu yang pelik yang mengakibatkan markup tidak sah yang meninggalkan halaman yang kelihatan bergelora.
ASTS, sebaliknya, putar HTML menjadi sesuatu yang jauh lebih berstruktur, yang menjadikannya lebih mudah untuk menyelam ke dalam nod teks dan hanya penggantian pada teks itu, atau mengacaukan unsur -unsur tanpa perlu menangani teks sama sekali.
Ini menjadikan transformasi AST lebih selamat dan kurang rawan ralat daripada penyelesaian berasaskan rentetan semata-mata.
Untuk apa AST digunakan?
Untuk memulakan, mari kita lihat dokumen yang minimum menggunakan beberapa baris markdown. Ini akan disimpan sebagai fail yang dipanggil home.md, yang akan kami simpan dalam folder kandungan laman web kami.
# Hello dunia! ! [cardigan corgi] (<https:>) Corgi yang comel! Beberapa teks lagi berlaku di sini.</https:>
Dengan mengandaikan kita tahu Markdown, kita dapat menyimpulkan bahawa apabila markdown ini dihuraikan, ia akan menjadi tag H1 yang mengatakan, "Hello World!" Kemudian dua perenggan teks: yang pertama mengandungi imej corgi dan beberapa teks yang dimaksudkan untuk menggambarkannya, dan yang kedua berkata, "Beberapa teks lagi pergi ke sini."
Tetapi bagaimana ia dapat berubah dari Markdown ke HTML?
Di situlah ASTS masuk!
Kerana ia menyokong pelbagai bahasa, kami akan menggunakan spesifikasi pokok sintaks unist dan, lebih khusus, projek itu bersatu.
Pasang kebergantungan
Pertama, kita perlu memasang kebergantungan yang diperlukan untuk menghuraikan markdown menjadi AST dan menukarnya ke HTML. Untuk melakukan itu, kita perlu memastikan kita telah memulakan folder sebagai pakej. Jalankan arahan berikut di terminal anda:
# Pastikan anda berada di folder root anda (di mana `kandungan` adalah) # Inisialisasi folder ini sebagai pakej npm NPM INIT # Pasang kebergantungan NPM Memasang Catatan Bersatu-Parse-HTML
Jika kita menganggap markdown kita disimpan di home.md, kita boleh mendapatkan AST dengan kod berikut:
const fs = memerlukan ('fs'); const bersatu = memerlukan ('bersatu'); const markdown = memerlukan ('kata-kata-parse'); const html = memerlukan ('card-html'); kandungan const = bersatu () . gunakan (markdown) .Using (html) .ProcessSync (fs.readFileSync (`$ {process.cwd ()}/content/home.md`)) .toString (); console.log (kandungan);
Kod ini mengambil kesempatan daripada modul FS terbina dalam Node, yang membolehkan kita mengakses dan memanipulasi sistem fail. Untuk maklumat lanjut mengenai bagaimana ini berfungsi, lihat dokumen rasmi.
Jika kita menyimpan ini sebagai src/index.js dan gunakan nod untuk melaksanakan skrip ini dari baris arahan, kita akan melihat yang berikut di terminal kita:
$ node src/index.js <h1 id="Hello-World"> Hello World! </h1> <p> <img src="<https://images.dog.ceo/breeds/corgi-cardigan/n02113186_1030.jpg>" alt="cardigan corgi"> corgi yang comel! </p> <p> Beberapa lagi teks pergi ke sini. </p>
Kami memberitahu Unified untuk menggunakan Catatan-Parse untuk menjadikan fail markdown menjadi AST, kemudian menggunakan Catatan-HTML untuk menjadikan markdown AST menjadi HTML-atau, lebih khusus, ia menjadikannya sesuatu yang dipanggil VFILE. Menggunakan kaedah ToString () menjadikan AST menjadi rentetan sebenar HTML yang boleh kita paparkan dalam penyemak imbas!
Terima kasih kepada kerja keras komuniti sumber terbuka, kata semua kerja keras untuk mengubah markdown menjadi HTML untuk kami. (Lihat perbezaan)
Seterusnya, mari kita lihat bagaimana ini sebenarnya berfungsi.
Apa yang kelihatan seperti AST?
Untuk melihat AST sebenar, mari tulis plugin kecil untuk log:
const fs = memerlukan ('fs'); const bersatu = memerlukan ('bersatu'); const markdown = memerlukan ('kata-kata-parse'); const html = memerlukan ('card-html'); kandungan const = bersatu () . gunakan (markdown) .Use (() => pokok => console.log (json.stringify (pokok, null, 2))) .Using (html) .ProcessSync (fs.readFileSync (`$ {process.cwd ()}/content/home.md`)) .toString ();
Output menjalankan skrip sekarang:
{ "jenis": "root", "Kanak -kanak": [ { "jenis": "menuju", "Kedalaman": 1, "Kanak -kanak": [ { "jenis": "teks", "Nilai": "Hello World!", "kedudukan": {} } ], "kedudukan": {} }, { "jenis": "perenggan", "Kanak -kanak": [ { "jenis": "imej", "Tajuk": Null, "URL": "<https:>", "alt": "Cardigan Corgi", "kedudukan": {} }, { "jenis": "teks", "Nilai": "Corgi yang comel!", "kedudukan": {} } ], "kedudukan": {} }, { "jenis": "perenggan", "Kanak -kanak": [ { "jenis": "teks", "Nilai": "Beberapa lagi teks pergi ke sini.", "kedudukan": {} } ], "kedudukan": {} } ], "kedudukan": {} }</https:>
Perhatikan bahawa nilai kedudukan telah dipotong untuk menjimatkan ruang. Mereka mengandungi maklumat mengenai tempat nod dalam dokumen itu. Untuk tujuan tutorial ini, kami tidak akan menggunakan maklumat ini. (Lihat perbezaan)
Ini agak menggembirakan untuk dilihat, tetapi jika kita mengezum dalam kita dapat melihat bahawa setiap bahagian markdown menjadi jenis nod dengan nod teks di dalamnya.
Sebagai contoh, tajuk menjadi:
{ "jenis": "menuju", "Kedalaman": 1, "Kanak -kanak": [ { "jenis": "teks", "Nilai": "Hello World!", "kedudukan": {} } ], "kedudukan": {} }
Inilah maksudnya:
- Jenis ini memberitahu kita jenis nod yang kita hadapi.
- Setiap jenis nod mempunyai sifat tambahan yang menggambarkan nod. Harta kedalaman di tajuk memberitahu kita tahap yang menuju ke arahnya - kedalaman 1 bermakna ia adalah tag
, 2 bermakna
, dan sebagainya.
- Arahan kanak -kanak memberitahu kita apa yang ada di dalam nod ini. Dalam kedua -dua tajuk dan perenggan, hanya ada teks, tetapi kita juga dapat melihat unsur -unsur inline di sini, seperti .
Ini adalah kuasa ASTS: kami kini menerangkan dokumen Markdown sebagai objek yang dapat difahami oleh komputer. Jika kita mahu mencetak kembali ke Markdown, pengkompil markdown akan tahu bahawa nod "tajuk" dengan kedalaman 1 bermula dengan #, dan nod teks kanak -kanak dengan nilai "Hello" bermakna garis akhir harus menjadi # hello.
Bagaimana Transformasi AST berfungsi
Mengubah AST biasanya dilakukan menggunakan corak pelawat. Ia tidak penting untuk mengetahui selok -belok bagaimana ini berfungsi untuk menjadi produktif, tetapi jika anda ingin tahu, corak reka bentuk JavaScript untuk manusia oleh Soham Kamani mempunyai contoh yang baik untuk membantu menjelaskan bagaimana ia berfungsi. Perkara penting yang perlu diketahui ialah majoriti sumber kerja AST akan bercakap tentang "melawat nod," yang secara kasar diterjemahkan untuk "mencari sebahagian daripada AST supaya kita dapat melakukan perkara dengannya." Cara amalan kerja ini ialah kita menulis fungsi yang akan digunakan untuk nod AST yang sepadan dengan kriteria kita.
Beberapa nota penting mengenai bagaimana ia berfungsi:
- ASTS boleh menjadi besar, jadi atas sebab -sebab prestasi kami akan bermutasi nod secara langsung. Ini bertentangan dengan bagaimana saya biasanya akan mendekati perkara - sebagai peraturan umum saya tidak suka untuk bermutasi keadaan global - tetapi masuk akal dalam konteks ini.
- Pengunjung bekerja secara rekursif. Ini bermakna jika kita memproses nod dan membuat nod baru jenis yang sama, pengunjung akan berjalan pada nod yang baru dibuat juga kecuali kita secara jelas memberitahu pengunjung tidak.
- Kami tidak akan terlalu mendalam dalam tutorial ini, tetapi kedua -dua idea ini akan membantu kita memahami apa yang sedang berlaku ketika kita mula mengacaukan kod tersebut.
Bagaimanakah saya mengubah suai output HTML AST?
Bagaimana jika kita mahu menukar output markdown kita, walaupun? Katakan matlamat kami adalah untuk membungkus tag imej dengan elemen angka dan membekalkan kapsyen, seperti ini:
<apet> <img src="<https://images.dog.ceo/breeds/corgi-cardigan/n02113186_1030.jpg>" alt="Cardigan Corgi"> <igcaption> corgi comel! </igcaption></apet>
Untuk mencapai matlamat ini, kita perlu mengubah HTML AST - bukan markdown AST - kerana Markdown tidak mempunyai cara untuk mencipta elemen angka atau figcaption. Nasib baik, kerana bersatu boleh saling beroperasi dengan pelbagai parser, kita boleh melakukannya tanpa menulis sekumpulan kod tersuai.
Tukar markdown AST ke HTML AST
Untuk menukar markdown AST ke AST HTML, tambahkan Rehype Remype dan beralih ke Rehype-Stringify untuk mengubah AST kembali ke HTML.
NPM Pasang Rehype-Stringify Catatan-Rehype
Buat perubahan berikut dalam src/index.js untuk beralih ke rehype:
const fs = memerlukan ('fs'); const bersatu = memerlukan ('bersatu'); const markdown = memerlukan ('kata-kata-parse'); const Catatan2Rehype = memerlukan ('Catatan-Rehype'); const html = memerlukan ('rehype-stringify'); kandungan const = bersatu () . gunakan (markdown) . Gunakan (Catatan2Rehype) .Use (() => pokok => console.log (json.stringify (pokok, null, 2))) .Using (html) .ProcessSync (fs.readFileSync ('corgi.md')) .toString (); console.log (kandungan);
Perhatikan bahawa pembolehubah HTML berubah dari Catatan-HTML ke Rehype-Stringify-kedua-duanya menghidupkan AST menjadi format yang boleh dibentangkan ke HTML
Jika kita menjalankan skrip, kita dapat melihat elemen imej sekarang kelihatan seperti ini dalam AST:
{ "jenis": "elemen", "tagname": "img", "Properties": { "src": "https://images.dog.ceo/breeds/corgi-cardigan/n02113186_1030.jpg", "alt": "Cardigan Corgi" }, "Kanak -kanak": [], "kedudukan": {} }
Ini adalah AST untuk perwakilan HTML imej, jadi kita boleh mula mengubahnya untuk menggunakan elemen angka. (Lihat perbezaan)
Tulis plugin untuk bersatu
Untuk membungkus elemen IMG kita dengan elemen angka, kita perlu menulis plugin. Di Unified, plugin ditambah dengan kaedah penggunaan (), yang menerima plugin sebagai hujah pertama dan sebarang pilihan sebagai hujah kedua:
. Gunakan (plugin, pilihan)
Kod plugin adalah fungsi (dipanggil "lampiran" dalam jargon bersatu) yang menerima pilihan. Pilihan ini digunakan untuk membuat fungsi baru (dipanggil "Transformer") yang menerima AST dan tidak berfungsi, mengubahnya. Untuk maklumat lanjut mengenai plugin, lihat gambaran Plugin dalam dokumen bersatu.
Fungsi yang dikembalikan akan menerima keseluruhan AST sebagai hujahnya, dan ia tidak mengembalikan apa -apa. .
modul.exports = options => tree => { console.log (pokok); };
Untuk menggunakan ini, kita perlu menambahkannya ke src/index.js:
const fs = memerlukan ('fs'); const bersatu = memerlukan ('bersatu'); const markdown = memerlukan ('kata-kata-parse'); const Catatan2Rehype = memerlukan ('Catatan-Rehype'); const html = memerlukan ('rehype-stringify'); const imgtOfigure = memerlukan ('./ img-to-figure'); kandungan const = bersatu () . gunakan (markdown) . Gunakan (Catatan2Rehype) . gunakan (imgtofigure) .ProcessSync (fs.readFileSync ('corgi.md')) .toString (); console.log (kandungan);
Jika kita menjalankan skrip, kita akan melihat seluruh pokok yang dilog masuk dalam konsol:
{ Jenis: 'Root', Kanak -kanak: [ { Jenis: 'Elemen', TagName: 'P', sifat: {}, kanak -kanak: [array], Kedudukan: [Objek] }, {type: 'text', value: '\\ n'}, { Jenis: 'Elemen', TagName: 'P', sifat: {}, kanak -kanak: [array], Kedudukan: [Objek] } ], kedudukan: { Mula: {line: 1, lajur: 1, offset: 0}, akhir: {line: 4, lajur: 1, offset: 129} } }
(Lihat perbezaan)
Tambahkan pelawat ke plugin
Seterusnya, kita perlu menambah pelawat. Ini akan membolehkan kita mendapatkan kod. Unified mengambil kesempatan daripada beberapa pakej utiliti, semua yang diawali dengan unist-util-*, yang membolehkan kita melakukan perkara yang sama dengan AST kita tanpa menulis kod tersuai.
Kita boleh menggunakan Unist-Util-Visit untuk mengubah suai nod. Ini memberi kita penolong lawatan yang mengambil tiga hujah:
- Keseluruhan AST yang kami bekerjasama
- Fungsi predikat untuk mengenal pasti nod mana yang ingin kita lawati
- Fungsi untuk membuat perubahan pada AST yang ingin kita buat
Untuk memasang, jalankan yang berikut dalam baris arahan anda:
NPM Pasang Unist-Util-Visit
Mari melaksanakan pelawat di plugin kami dengan menambahkan kod berikut:
const visit = memerlukan ('unist-util-visit'); modul.exports = options => tree => { Lawati ( pokok, // Hanya lawati t tag yang mengandungi elemen IMG nod => node.tagname === 'p' && node.children.some (n => n.tagname === 'img'), nod => { console.log (nod); } ); };
Apabila kita menjalankan ini, kita dapat melihat hanya ada satu nod perenggan yang dilog masuk:
{ Jenis: 'Elemen', TagName: 'P', sifat: {}, Kanak -kanak: [ { Jenis: 'Elemen', TagName: 'img', sifat: [objek], Kanak -kanak: [], Kedudukan: [Objek] }, {jenis: 'teks', nilai: 'corgi comel!', kedudukan: [objek]} ], kedudukan: { Mula: {line: 3, lajur: 1, offset: 16}, akhir: {line: 3, lajur: 102, offset: 117} } }
Sempurna! Kami hanya mendapat nod perenggan yang mempunyai imej yang ingin kami ubah. Sekarang kita boleh mula mengubah AST!
(Lihat perbezaan)
Balut imej dalam elemen angka
Sekarang kita mempunyai atribut imej, kita boleh mula mengubah AST. Ingat, kerana ASTS boleh menjadi sangat besar, kami bermutasi mereka untuk mengelakkan membuat banyak salinan dan berpotensi memperlahankan skrip kami.
Kami mulakan dengan menukar nama tag nod untuk menjadi angka dan bukannya perenggan. Selebihnya butiran boleh tetap sama buat masa ini.
Buat perubahan berikut dalam src/img-to-figure.js:
const visit = memerlukan ('unist-util-visit'); modul.exports = options => tree => { Lawati ( pokok, // Hanya lawati t tag yang mengandungi elemen IMG nod => node.tagname === 'p' && node.children.some (n => n.tagname === 'img'), nod => { node.tagname = 'angka'; } ); };
Jika kita menjalankan skrip kita sekali lagi dan melihat output, kita dapat melihat bahawa kita semakin dekat!
<h1 id="Hello-World"> Hello World! </h1> <rige> <img src="<https://images.dog.ceo/breeds/corgi-cardigan/n02113186_1030.jpg>" alt="cardigan corgi"> corgi yang comel! <p> Beberapa lagi teks pergi ke sini. </p></rige>
(Lihat perbezaan)
Gunakan teks di sebelah imej sebagai kapsyen
Untuk mengelakkan perlu menulis sintaks tersuai, kami akan menggunakan mana -mana teks yang diluluskan sejajar dengan imej sebagai kapsyen imej.
Kita boleh membuat andaian bahawa biasanya imej tidak mempunyai teks sebaris dalam markdown, tetapi perlu diperhatikan bahawa ini boleh 100% menyebabkan kapsyen yang tidak diingini muncul untuk orang yang menulis markdown. Kami akan mengambil risiko dalam tutorial ini. Jika anda merancang untuk meletakkan ini dalam pengeluaran, pastikan untuk menimbang perdagangan dan pilih yang terbaik untuk keadaan anda.
Untuk menggunakan teks, kami akan mencari nod teks di dalam nod induk kami. Jika kita dapati, kita mahu merebut nilainya sebagai kapsyen kita. Sekiranya tiada kapsyen ditemui, kami tidak mahu mengubah nod ini sama sekali, jadi kami boleh kembali lebih awal.
Buat perubahan berikut kepada src/img-to-figure.js untuk merebut kapsyen:
const visit = memerlukan ('unist-util-visit'); modul.exports = options => tree => { Lawati ( pokok, // Hanya lawati t tag yang mengandungi elemen IMG nod => node.tagname === 'p' && node.children.some (n => n.tagname === 'img'), nod => { // Cari nod teks const textNode = node.children.find (n => n.type === 'text'); // Sekiranya tidak ada kapsyen, kita tidak perlu mengubah nod jika (! TextNode) kembali; const caption = textNode.value.trim (); console.log ({caption}); node.tagname = 'angka'; } ); };
Jalankan skrip dan kita dapat melihat kapsyen yang dilog masuk:
{Caption: 'Corgi yang comel!' }
(Lihat perbezaan)
Tambah elemen figcaption ke angka
Sekarang kita mempunyai teks kapsyen kita, kita boleh menambah figcaption untuk memaparkannya. Kita boleh melakukan ini dengan membuat nod baru dan memadam nod teks lama, tetapi kerana kita bermutasi di tempatnya agak kurang rumit untuk hanya menukar nod teks ke dalam elemen.
Unsur -unsur tidak mempunyai teks, jadi, kita perlu menambah nod teks baru sebagai anak elemen Figcaption untuk memaparkan teks kapsyen.
Buat perubahan berikut kepada src/img-to-figure.js untuk menambah kapsyen ke markup:
const visit = memerlukan ('unist-util-visit'); modul.exports = options => tree => { Lawati ( pokok, // Hanya lawati t tag yang mengandungi elemen IMG nod => node.tagname === 'p' && node.children.some (n => n.tagname === 'img'), nod => { // Cari nod teks const textNode = node.children.find (n => n.type === 'text'); // Sekiranya tidak ada kapsyen, kita tidak perlu mengubah nod jika (! TextNode) kembali; const caption = textNode.value.trim (); // Tukar nod teks ke elemen figcaption yang mengandungi nod teks textNode.type = 'element'; textNode.tagname = 'figcaption'; textNode.children = [ { jenis: 'teks', Nilai: Kapsyen } ]; node.tagname = 'angka'; } ); };
Jika kita menjalankan skrip sekali lagi dengan nod src/index.js, kita melihat imej yang diubah dibalut dalam elemen angka dan diterangkan dengan figcaption!
<h1 id="Hello-World"> Hello World! </h1> <rige> <img src="<https://images.dog.ceo/breeds/corgi-cardigan/n02113186_1030.jpg>" alt="cardigan corgi"> <p> Beberapa lagi teks pergi ke sini. </p></rige>
(Lihat perbezaan)
Simpan kandungan yang diubah ke fail baru
Sekarang bahawa kami telah membuat banyak transformasi, kami ingin menyimpan pelarasan tersebut ke fail sebenar supaya kami dapat membagikannya.
Oleh kerana markdown tidak termasuk dokumen HTML penuh, kami akan menambah satu lagi plugin Rehype yang dipanggil Rehype-Document untuk menambah struktur dokumen penuh dan tag tajuk.
Pasang dengan berjalan:
NPM Pasang Rehype-Document
Seterusnya, buat perubahan berikut kepada src/index.js:
const fs = memerlukan ('fs'); const bersatu = memerlukan ('bersatu'); const markdown = memerlukan ('kata-kata-parse'); const Catatan2Rehype = memerlukan ('Catatan-Rehype'); const doc = memerlukan ('rehype-document'); const html = memerlukan ('rehype-stringify'); const imgtOfigure = memerlukan ('./ img-to-figure'); kandungan const = bersatu () . gunakan (markdown) . Gunakan (Catatan2Rehype) . gunakan (imgtofigure) .Use (Doc, {Title: 'A Document Transformed!'}) .Using (html) .ProcessSync (fs.readFileSync (`$ {process.cwd ()}/content/home.md`)) .toString (); const outputDir = `$ {process.cwd ()}/public`; jika (! fs.existssync (outputDir)) { fs.mkdirsync (outputDir); } fs.writeFileSync (`$ {outputDir}/home.html`, kandungan);
Jalankan skrip sekali lagi dan kami akan dapat melihat folder baru dalam akar yang dipanggil awam, dan di dalamnya kami akan melihat home.html. Di dalamnya, dokumen yang berubah -ubah kami disimpan!
<meta charset="utf-8"> <tirtle> Dokumen yang diubah! <meta name="viewport" content="width = peranti-lebar, skala awal = 1"> <h1 id="Hello-World"> Hello World! </h1> <rige> <img src="<https://images.dog.ceo/breeds/corgi-cardigan/n02113186_1030.jpg>" alt="cardigan corgi"> <p> Beberapa lagi teks pergi ke sini. </p> </rige></tirtle>
(Lihat perbezaan)
Jika kita membuka awam/home.html Dalam penyemak imbas, kita dapat melihat markdown yang berubah menjadi tokoh dengan kapsyen.
Baldi Kudus! Lihatlah corgi yang comel itu! Dan kita tahu ia comel kerana kapsyen memberitahu kita demikian.
Apa yang Harus Dilakukan Seterusnya
Mengubah fail menggunakan ASTS sangat kuat - dengan itu, kami dapat mencipta apa sahaja yang dapat kami bayangkan dengan cara yang selamat. Tiada regex atau parsing rentetan diperlukan!
Dari sini, anda boleh menggali lebih mendalam ke dalam ekosistem plugin untuk ucapan dan rehype untuk melihat lebih banyak daripada apa yang mungkin dan mendapatkan lebih banyak idea untuk apa yang boleh anda lakukan dengan transformasi AST, dari membina penjana tapak statik bertenaga markdown anda sendiri; untuk mengautomasikan peningkatan prestasi dengan mengubahsuai kod di tempat; Untuk apa sahaja yang anda boleh bayangkan!
Transformasi AST adalah kuasa besar pengekodan. Bermula dengan menyemak kod sumber demo ini - Saya tidak sabar untuk melihat apa yang anda bina dengannya! Kongsi projek anda dengan saya di Twitter.
Atas ialah kandungan terperinci Cara mengubah suai nod dalam pokok sintaks abstrak. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Baru -baru ini saya dapati penyelesaian untuk mengemas kini warna mana -mana imej produk. Jadi dengan hanya satu produk, kita boleh mewarnakannya dengan cara yang berbeza untuk ditunjukkan

Pada minggu ini, Roundup, Lighthouse menyoroti cahaya pada skrip pihak ketiga, sumber yang tidak selamat akan disekat di tapak yang selamat, dan banyak kelajuan sambungan negara

Terdapat banyak platform analisis untuk membantu anda mengesan data pelawat dan penggunaan di laman web anda. Mungkin paling penting Google Analytics, yang digunakan secara meluas

Ketua dokumen mungkin bukan bahagian paling glamor dari laman web, tetapi apa yang masuk ke dalamnya boleh dikatakan sama pentingnya dengan kejayaan laman web anda sebagai

Apa yang berlaku apabila anda melihat beberapa JavaScript yang memanggil Super (). Dalam kelas kanak -kanak, anda menggunakan super () untuk memanggil pembina ibu bapa dan super. untuk mengaksesnya

JavaScript mempunyai pelbagai API popup terbina dalam yang memaparkan UI khas untuk interaksi pengguna. Terkenal:

Saya sedang berbual dengan beberapa orang depan pada hari yang lain tentang mengapa begitu banyak syarikat berjuang untuk membuat laman web yang boleh diakses. Mengapa laman web yang boleh diakses begitu sukar

Terdapat atribut HTML yang betul -betul apa yang anda fikir harus dilakukan:


Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

MantisBT
Mantis ialah alat pengesan kecacatan berasaskan web yang mudah digunakan yang direka untuk membantu dalam pengesanan kecacatan produk. Ia memerlukan PHP, MySQL dan pelayan web. Lihat perkhidmatan demo dan pengehosan kami.

ZendStudio 13.5.1 Mac
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Inggeris
Disyorkan: Versi Win, menyokong gesaan kod!

SublimeText3 Linux versi baharu
SublimeText3 Linux versi terkini