Coupling Ketat Antara Javascript, HTML, dan CSS: Pendekatan Yang Lebih Modern?

29

Sangat umum untuk melihat Javascript terikat pada pemilih tertentu untuk menemukan elemen, menyimpan data, dan mendengarkan acara. Juga umum untuk melihat penyeleksi yang sama ini digunakan untuk styling.

jQuery (dan mesin pemilihnya Sizzle) mendukung dan mempromosikan ini dengan mereferensikan elemen dengan sintaks tipe CSS. Dengan demikian, teknik ini sangat sulit untuk 'melepaskan' (atau refactor) ketika membangun proyek.

Saya telah memahami bahwa ini adalah hasil dari sejarah pengembangan HTML dan Javascript, dan bahwa browser telah dibangun untuk secara efisien mengkonsumsi / mem-parsing / dan membuat penggandaan semacam ini. Tetapi ketika situs web menjadi semakin kompleks, kenyataan ini dapat memperkenalkan kesulitan dalam mengatur dan memelihara lapisan-lapisan yang terpisah ini.

Pertanyaan saya adalah: dapat dan haruskah ini dihindari di situs web modern?

Jika saya baru dalam pengembangan front-end, dan saya ingin mempelajari berbagai hal 'dengan cara yang benar', apakah ada baiknya belajar memisahkan diri dan menghindari ketergantungan seperti itu sejak awal? Apakah ini berarti menghindari jQuery yang mendukung perpustakaan yang mempromosikan struktur yang lebih terpisah?

Stuart Kershaw
sumber
1
Bagaimana hal seperti itu bekerja? Bagaimana Anda, misalnya, menonaktifkan kontrol pada halaman tanpa benar-benar menyentuh kontrol itu dalam beberapa cara, atau memiliki pengetahuan tentang itu? (Ini adalah cara kecil saya untuk mengatakan bahwa Anda harus lebih spesifik tentang apa yang Anda maksud dengan decoupling, idealnya dengan beberapa contoh, bahkan jika mereka dibuat-buat).
Robert Harvey
2
Yang paling penting ketika Anda berbicara tentang decoupling html, css dan js adalah menggunakan penyeleksi kelas, bukan yang lain, ini adalah konsep inti dari metodologi seperti oocss dan BEM.
angvillar
Pelajari Bereaksi atau komponen web, dan Anda tidak perlu repot dengan pemilih di JS lagi.
Andy

Jawaban:

35

Tidak ada cara untuk menghindarinya. Mereka digabungkan karena mereka berinteraksi satu sama lain. Jika javascript Anda bermaksud melakukan manipulasi DOM apa pun, maka diperlukan cara untuk merujuk DOM.

Ada berbagai konvensi untuk itu.

API DOM Level 2 menyediakan metode getElementById, getElementByTagName, dan getElementsByName. Sampai hari ini, ini adalah workhorses dari segala jenis traversal DOM. Semua penyeleksi jQuery lain yang lebih menarik menyelesaikannya pada kombinasi ini pada akhirnya, dan / atau meluruskan traversal dari setiap node DOM (ini adalah cara untuk melakukan getByClassName).

Tidak ada jalan pintas lainnya. Javascript perlu tahu apa yang harus dilakukan dan di mana. Biasanya, jika suatu elemen memiliki id atau kelas yang hanya relevan dalam skrip, banyak orang akan awalan dengan js-atau beberapa flag yang jelas lainnya.

Konvensi lain yang lebih baru adalah pemilihan atribut-data.

<ul data-myapp-sortable="true">

jQuery('[data-myapp-sortable]').makeSortable();

Atribut data umumnya digunakan untuk tujuan skrip dan memilih menggunakan yang masuk akal. Kekurangannya adalah ini lebih lambat daripada menggunakan getElementById ().

Pendekatan lain adalah yang digunakan oleh angularJS, yang menciptakan model tampilan. Dalam konvensi ini segala jenis fungsi scripting ditentukan oleh atribut yang ditunjuk secara khusus seperti ng-disabled ng-hrefdan banyak lagi. Anda tidak menambahkan pemilih di javascript Anda. Dokumen HTML menjadi otoritas utama tentang apa yang dituliskan dan bagaimana, dan javascript bekerja secara abstrak. Ini pendekatan yang bagus, tetapi jelas dengan kurva belajar yang lebih tinggi dari metode sebelumnya. Dan lagi, kinerja harus dipertimbangkan.

Tetapi jangan pernah berpikir bahwa Anda dapat menulis HTML interaktif dan javascript, dan entah bagaimana kedua bagian itu tidak tahu tentang yang lain. Ini lebih tentang bagaimana Anda dapat membatasi referensi ke dependensi.

mastaBlasta
sumber
2
Jawaban cemerlang, +1. Jika hanya untuk menyebutkan atribut data sebagai mekanisme untuk menghindari kopling ketat
Fergus In London
3
atribut-data bukan obat mujarab. Mereka sangat populer akhir-akhir ini dan orang-orang menaruh segalanya kecuali dapur. Banyak kerangka kerja (misalnya UI jQuery) menggunakannya secara luas. Anda harus benar-benar ketat dengan penempatan nama dan konvensi lain untuk menghindari masalah. Mereka membantu memisahkan HTML dari JS, tetapi mereka tidak serta merta membuat proses debug menjadi lebih mudah.
mastaBlasta
Saya tidak pernah mengerti mengapa menggunakan kelas, ID, dan atribut data sebagai pengait dan bendera negara perlu diciptakan kembali. Semua yang telah dicapai Angular dalam hal itu adalah pengurangan kinerja dan menggantikan konvensi yang diketahui / dipahami secara luas dengan konvensi baru yang mengharuskan orang memahami cara melakukannya "dengan cara Angular," dengan menciptakan atribut dan tag Anda sendiri. Tidak ada kurva belajar yang besar di sana. Itu lebih lambat, bertentangan dengan konvensi yang masuk akal dan umum dikenal dan IMO yang sama sekali tidak perlu.
Erik Reppen
9

Jika Anda ingin melepaskan interaktivitas yang Anda dapatkan, Anda dapat menghindari Javascript sepenuhnya. Kerangka kerja seperti ASP.NET MVC sangat baik melayani halaman yang hanya berisi tombol HTML, CSS, dan SUBMIT.

BAIK. Mungkin itu agak ekstrem.

Decoupling dalam aplikasi web sudah terjadi di banyak tingkatan. Aplikasi REST memungkinkan Anda menentukan aplikasi Anda dalam hal "sumber daya web" yang dikaitkan dengan URL. Lihat Model memungkinkan Anda untuk menyajikan data ke UI yang dipisahkan dari model domain, tetapi memiliki bentuk yang Anda butuhkan untuk menampilkannya dengan benar. Lapisan layanan memungkinkan satu UI untuk ditukar dengan yang lain, dan sebagainya.

Secara historis, selalu ada pertukaran antara interaktivitas dan penggandengan. Semakin interaktif halaman web Anda, semakin erat pula aplikasi yang akan digabungkan. Tetapi logika interaktivitas di halaman web terbatas pada halaman web itu sendiri; setiap sambungan dengan server akan terjadi melalui POST atau AJAX. Jadi saya tidak yakin Anda harus terlalu khawatir dengan kopling di tingkat Javascript, selain memperhatikan cara paket data dilewatkan antara browser dan server.

Pendekatan yang paling "modern" (yaitu citarasa minggu ini) mungkin adalah aplikasi SPA .

Robert Harvey
sumber
Tidak terdengar ekstrem bagi saya. Banyak situs yang menggunakan JavaScript secara ekstensif, hingga tidak dapat digunakan tanpa itu, sebenarnya tidak memerlukannya. Seandainya pengembang mereka memiliki lebih banyak petunjuk ...
Michael Hampton
5

Martin Fowler menjelaskan satu pendekatan untuk ini sebagai DOM Terpisah, di mana Anda memisahkan JavaScript DOM Anda dari JavaScript halaman logika Anda.

Application Logic <----> DOM Manipulation <----> DOM / HTML
Rory Hunter
sumber
1
+1 Saya sepenuhnya setuju dengan memisahkan JavaScript <--> DOM logic. Saya benar-benar tidak suka atribut data karena ini tidak berkaitan dengan DOM tetapi untuk alat eksternal. Saya merasa bahwa pendekatan yang lebih bersih adalah memiliki semacam pemetaan. Ya, ini dapat berarti bahwa Anda kemudian memiliki file dengan referensi ke dua aspek (mis., Fungsi JS dan elemen DOM) daripada, misalnya, DOM yang mengandung beberapa referensi yang diambil oleh JS (yang mungkin digambarkan sebagai 'aspek tunggal' '). Namun, jika dilakukan dengan penuh pertimbangan, ini bisa sangat dipertahankan, dapat digunakan kembali, dan menawarkan pemisahan kekhawatiran yang lebih baik daripada atribut data.
awj
2

Tidak, menggunakan kelas, elemen, dan pemilih ID sisi klien tidak harus dihindari. Sintaksis digunakan karena penyeleksi CSS sangat matang dan bahasa domain yang mapan, dan memiliki desain umum membuatnya jauh lebih mudah untuk berbagi model logis umum halaman antara program dan desain, yang merupakan hal yang sangat, sangat bagus.

Meskipun dimungkinkan untuk salah menggunakan sintaks ini dan membuat aplikasi yang mengerikan dan tidak dapat dipelihara, hal itu dimungkinkan terlepas dari bahasa atau perangkat Anda.

DougM
sumber
2
Saya sebenarnya merekomendasikan untuk tidak menggunakan penyeleksi kelas, elemen, dan ID untuk banyak hal, dan alih-alih fokus menggunakan [data-*]penyeleksi atribut khusus , yang dapat digunakan dengan cara yang sangat kuat.
zzzzBov
2
Nasihat yang buruk dalam pikiran saya, terutama ketika menulis modular / dapat digunakan kembali JS yang seharusnya tidak membuat asumsi pada pemilih. Atribut data adalah ide yang lebih baik untuk skenario ini.
Fergus In London
3
@zzzzBov - Saya tahu ini adalah optimasi mikro, tetapi pencarian ID dan kelas jauh lebih cepat daripada pencarian atribut-data. Tapi ya, saya suka ide menggunakan set atribut yang berbeda untuk menangani masalah yang berbeda.
Jimmy Breck-McKye
0

Seseorang perlu membangun antarmuka manajer jalur jQuery untuk tipuan dan lapisan cache ke dom.

pathMgr.register(name,selector [,isDynamic=false]);
pathMgr.get(name [,refresh]);

Kemudian,

String.prototype.reg([isDynamic=false]);
String.prototype.get(name [,refresh]);

Begitu,

// at init....
var pathMgr=new PathMgr();
'sidebar-links #sidebar a'.reg();// new registery of selector '#sidebar a' under name 'sidebar-links'
// more, more


// in code
'sidebar-links'.get().css(etc...);
//or
'sidebar-links'.addStyleRule({});
Menandai
sumber