6 điểm bởi GN⁺ 2023-11-07 | 1 bình luận | Chia sẻ qua WhatsApp
  • Bài viết bàn về việc làm chủ thao tác với Document Object Model (DOM) bằng JavaScript thuần.
  • Bài viết nhấn mạnh tầm quan trọng của việc hiểu DOM API của trình duyệt trong phát triển web, dù hiện nay có các công cụ hiện đại như Angular, VueJS, React, Solid và Svelte.
  • Tác giả cung cấp một bộ sưu tập tài liệu bao gồm các API trình duyệt cơ bản, ví dụ dễ hiểu, demo thời gian thực, mẹo và thực tiễn tốt nhất, các trường hợp sử dụng thực tế, cùng khả năng tương thích với trình duyệt hiện đại và Internet Explorer.
  • Các tài liệu này được chia thành ba cấp độ: cơ bản, trung cấp và nâng cao.
  • Ở cấp độ cơ bản có các tác vụ như thay đổi favicon động theo tùy chọn bảng màu của người dùng, tính thời gian đọc của trang web và cập nhật động biến gốc CSS.
  • Ở cấp độ trung cấp có các tác vụ như bỏ thụt lề trong vùng văn bản bằng tổ hợp phím Shift+Tab, vào chế độ toàn màn hình và xây dựng input số tăng giảm.
  • Ở cấp độ nâng cao có các tác vụ như tạo con trỏ tùy chỉnh, khử độc chuỗi HTML và tạo thanh cuộn tùy chỉnh.
  • Tác giả cũng cung cấp các mẹo như tránh bố cục bị xê dịch khi mở modal và lấy hình chữ nhật bao quanh của text node.
  • Bài viết kết thúc bằng lời mời đăng ký nhận bản tin của tác giả về nội dung kỹ thuật frontend.

1 bình luận

 
GN⁺ 2023-11-07
Ý kiến trên Hacker News
  • Danh sách ví dụ rất xuất sắc, chỉ cần lướt qua vài cái cũng thấy sự chỉn chu và chi tiết đáng kinh ngạc
    Khi chuyển sang các cách triển khai nhỏ hơn, tối giản hơn từ những nền tảng như React, tôi thường bị khựng lại ở chỗ phải xử lý các pattern phức tạp bằng JS chuẩn thế nào, nhưng rồi nhìn vào code mới thấy nhiều lúc lại là kiểu “ơ, cái này còn dễ hơn nhiều so với việc nhét cả đống thuộc tính vào một thư viện khổng lồ”

    • Tôi cũng đi đến một nhận ra tương tự sau khi trải qua 3~4 đợt cập nhật lớn của RiotJS
      Ngay cả các framework JS tối giản, khi các yêu cầu tính năng tưởng như vô hại cứ chồng chất lên, cuối cùng cũng rất dễ biến thành quái vật của hook, event và các miếng vá cho side effect
      Giờ tôi cũng không dùng jQuery nữa; những thứ như ES module thì tôi dùng để sắp xếp code, nhưng không nhất thiết phải chạy lệnh npm. Đây không phải thứ cần kéo vào như vendor, mà là tiêu chuẩn toàn cục của trình duyệt
      Dạo này tôi đọc MDN như kinh thánh. Cứ tin và đi theo là gần như nó dẫn mình tới tận nơi, còn framework thì từ một điểm nào đó lại bắt đầu cản chân. 5 năm trước chưa được như bây giờ, nhưng các browser API đã nhanh chóng hội tụ thành những nền tảng cơ bản mạnh mẽ và nhất quán như module, flexbox, grid
    • Các ví dụ trong bài gốc không mang tính cạnh tranh với framework web client. Vấn đề phổ biến mà framework giải quyết là quản lý trạng thái và cập nhật UI khi trạng thái thay đổi
      Ví dụ, phần lớn các ví dụ trong bài gốc là loại code mà ngay cả khi dùng React bạn vẫn phải tự viết
  • Tôi đang làm một side project chưa có tên, kiểu như “vim cho web designer”. Nó tạo website hoặc component trong trình duyệt như Webflow, nhưng mọi thứ được vận hành hoàn toàn bằng ngôn ngữ lệnh
    Ban đầu tôi quyết tâm làm mà không dùng framework. Tôi làm việc này từ 2009, dùng JS từ rất lâu trước khi đụng tới framework, nên tôi nghĩ chỉ cần DOM API gốc là đủ
    Nhưng việc chuyển dữ liệu ra vào DOM quá tẻ nhạt và dễ lỗi, nên vì sức khỏe tinh thần tôi cuối cùng cũng bắt đầu tự dùng một mini-framework. Lúc đó tôi mới nhớ ra vì sao ban đầu người ta lại dùng framework. Rốt cuộc kiểu gì bạn cũng sẽ dùng framework dưới một dạng nào đó; khác biệt chỉ là đó là thứ tùy biến do bạn tự làm hay chuẩn ngành do cộng đồng tạo ra
    Với những site ít tương tác thì DOM gốc vẫn ổn, và phần lớn website dùng React có lẽ thật ra không cần đến nó. Nhưng nếu sản phẩm có dù chỉ một chút sắc thái hay độ phức tạp, tôi sẽ dùng framework để tránh phiền toái. Cuối cùng tôi chuyển sang Svelte và hài lòng hơn hẳn

    • Các dự án siêu tối giản rồi cũng sẽ dẫn tới việc tự viết lại một nửa jquery hay lodash. Tìm một thư viện tốt như ramda có tree shaking hiệu quả rồi dùng tiết kiệm sẽ dễ hơn nhiều
    • Câu “nếu bạn không chọn framework thì bạn sẽ tự làm ra một cái” đúng là quá chuẩn
    • Đây là trường hợp đang xây dựng ứng dụng, nên chỉ đọc mô tả thôi cũng có thể đoán rằng tốt hơn hết là bọc các tương tác DOM lại
      Với website cần tương tác, thao tác DOM có thể là lựa chọn tốt hơn vì nó dùng kỹ thuật nền tảng và phổ quát hơn, quy trình build nhẹ hoặc không có, chạy nhanh hơn và minh bạch hơn
      Tất nhiên có rất nhiều vùng xám, nhưng trường hợp này thuộc chính xác vào nhóm mà framework mang lại lợi ích
    • Hiện nay SvelteKit tập trung vào SSR, còn bản thân Svelte thì không có router client-side mặc định. Tôi đã thử dùng Svelte cho một SPA CSR nhưng rồi bỏ cuộc
  • Chỉ dùng value.startsWith('javascript:') là sẽ tạo ra lỗ hổng. Có thể có khoảng trắng tùy ý ở đầu URL, nên ít nhất phải là value.trim().startsWith('javascript:')
    Dù vậy, tôi vẫn nghĩ danh sách cho phép tốt hơn danh sách chặn. Chỉ nên cho phép http:, https: và nếu cần thì thêm mailto:, ftp:, sftp:; URL tương đối bắt đầu bằng / có lẽ cũng có thể cho phép
    Nhưng vì phải xử lý chính xác mọi thuộc tính thực tế có thể là URL, nên cuối cùng có lẽ tốt hơn là chỉ cho phép một vài thẻ và thuộc tính của chúng

  • Có vẻ là một danh sách hữu ích đáng để biết; tôi chưa xem hết nhưng đến giờ trông vẫn ổn
    Tôi bấm vào ví dụ đầu tiên thì thấy đang gọi window.matchMedia('(prefers-color-scheme: dark)') hai lần một cách không cần thiết
    Nếu định dùng setFavicon làm callback cho event listener thì chỉ cần dùng event.matches từ tham số event được truyền vào callback là được
    Cá nhân tôi thích xử lý ở phía HTML hơn. Vì như vậy vẫn hỗ trợ được cả người dùng đã tắt JS
    https://phuoc.ng/collection/html-dom/change-the-favicon-dyna...

    • Làm ở HTML còn có thể tránh hiện tượng nội dung của theme khác chớp lên trong thoáng chốc. Cách tương tự cũng áp dụng được cho meta theme-color, và với nhà phát triển PWA chú ý đến chi tiết thì đây là một tính năng rất hay dù chưa được dùng nhiều
  • Kỹ thuật “tự động mở rộng textarea” đang dần lỗi thời vì thuộc tính CSS mới form-sizing
    https://chriscoyier.net/2023/09/29/css-solves-auto-expanding...
    Ngay cả khi không dùng thuộc tính CSS mới này, cách điều chỉnh height của phần tử cũng không lý tưởng và có thể bị giật
    Cách tiếp cận tốt hơn là dùng một phần tử gương ẩn
    https://css-tricks.com/the-cleanest-trick-for-autogrowing-te...

  • Khá nhiều mục ở đây đang dùng các API cũ và vụng về dù đã có native API tốt hơn
    Ví dụ, “thay thế phần tử” được viết là ele.parentNode.replaceChild(newEle, ele);, nhưng nếu không nhắm tới Chrome dưới 54, Firefox dưới 49, hay Safari dưới 10, thì cứ dùng ele.replaceWith(newEle) là được
    replaceWith cũng có thể thay một node bằng nhiều node hoặc văn bản
    Tương tự, ở mục “duyệt NodeList” họ bảo trải mảng rồi dùng forEach, nhưng chỉ cần for (let ele of nodelist) ... là được

    • Cần nhớ rằng NodeList có thể là một đối tượng live. Nếu thao tác với danh sách đó trong lúc duyệt, bạn có thể gặp kết quả ngoài dự đoán
  • Hay. Đã bookmark. Một tài liệu hay khác cùng tinh thần là https://youmightnotneedjquery.com/
    Tôi không làm web thường xuyên, nhưng mỗi lần làm là lại hoàn toàn mất hứng vì chứng nghiện framework bên đó. Việc một dự án React mới bắt đầu với hàng trăm dependency đã vượt khỏi tầm kiểm soát, và sức nặng của sự phức tạp đó thật đáng kinh ngạc
    Trong khi đó, công nghệ trình duyệt đa nền tảng có sẵn mạnh hơn bao giờ hết, và lượng code để làm các việc phổ biến cũng không nhiều đến thế
    Các lập trình viên frontend vẫn ổn chứ?

    • Tôi hoàn toàn không thích React hay npm, nhưng tôi nghĩ một số framework vẫn có chỗ đứng vì chúng mang lại những thứ hữu ích mà DOM API thuần không cung cấp
      Ví dụ, quản lý trạng thái ứng dụng và routing là những phần lớn mà nếu chỉ dùng DOM API thuần thì bạn phải tự làm
      Tùy độ phức tạp của ứng dụng mà có thể không thành vấn đề gì, nhưng một khi vượt khỏi mức app cơ bản thì giá trị của các tính năng bổ sung này tăng rất nhanh. Chỉ là nếu phải dùng NPM để lấy thứ mình cần thì sẽ đau đầu
    • Một tài liệu tuyệt vời khác cùng tinh thần là https://javascript.info/
      Là một lập trình viên frontend yêu thích nền tảng gốc và các tính năng của nó, tôi rất vui khi thấy những thứ hay ho xuất hiện như nested CSS, container query, và trải nghiệm JS nhìn chung tốt hơn kể từ ES6
      Đồng thời tôi cũng ngạc nhiên vì quá nhiều người dùng component ngay cả cho những thứ vụn vặt như button hay chữ in đậm
      Tôi thích framework bản thân nó, nhưng việc marketing của nhiều framework và thư viện đang dựa vào niềm tin rằng CSS và thao tác DOM thuần khó một cách điên rồ, còn việc kéo đại một package từ NPM về không chỉ nhanh và dễ mà còn là cách làm chuyên nghiệp
    • Tôi đồng ý là nó đã vượt khỏi tầm kiểm soát. Nhưng trong năm qua tôi chuyển sang đội platform và lần đầu bắt đầu đụng vào công cụ phía DevOps, thì độ phức tạp ở đó cũng chẳng kém frontend
      Chỉ nhìn vào những thứ như Kubernetes, Helm, Terraform, CircleCI thôi cũng đã thấy lượng thuật ngữ chồng tầng lên nhau là vô lý
    • Tôi tò mò không biết bạn đã từng làm việc không hề đơn giản nào với “công nghệ đa nền tảng mạnh mẽ” đó chưa. Và React cũng không phải lựa chọn duy nhất
  • Tôi thật sự bất ngờ khi biết nhiều hàm DOM trả về live HTMLCollection tự động cập nhật
    Tôi tò mò không biết trước thời kỳ bùng nổ framework, hoặc quanh thời điểm xu hướng phát triển không dùng framework bắt đầu lấy lại chút phổ biến, tính năng này đã từng được dùng tích cực đến mức nào trong code production thực tế

  • Cái cũ lại thành cái mới. Vai trò frontend đầu tiên của tôi là làm ứng dụng web vào năm 1999
    Tôi đã làm mọi thứ bằng JS “Vanilla”, kể cả các tính năng hay ho như kéo thả tree view, click để chỉnh sửa, gần như là ứng dụng một trang
    Phần khó nhất là dung hòa sự khác biệt giữa Netscape và Internet Explorer

    • Tôi tò mò không biết khi đó bạn quản lý trạng thái và các thay đổi của nó như thế nào
      Sao giờ lại có cảm giác như chúng ta không còn biết làm mấy chuyện đó nữa ;]
  • Tính năng JavaScript thuần tôi thích nhất dạo này là Element.insertAdjacentHTML, thứ đã có từ thời Chrome 1.0 và IE
    Đặc biệt khi dùng cùng chuỗi nhiều dòng với backtick thì mức độ hữu ích phải nói là cực kỳ lớn. Thật khó tin là nó đã tồn tại từ lâu như vậy mà tôi chỉ mới biết đến khoảng một năm trước
    insertAdjacentHTML(position, text) sẽ phân tích chuỗi văn bản được chỉ định thành HTML hoặc XML rồi chèn các node kết quả vào vị trí được chỉ định trong cây DOM
    Nếu chỉ dùng DOM thuần theo cách cũ, bạn phải tạo phần tử li, tạo phần tử a, gắn làm con, đặt thuộc tính href, đưa giá trị text vào rồi chèn vào ul. Hoặc phải gom thành một chuỗi lớn rồi đưa vào innerHTML, và việc sửa danh sách hiện có còn đau đớn và dài dòng hơn nữa

    1. https://developer.mozilla.org/en-US/docs/Web/API/Element/ins...