4 คะแนน โดย GN⁺ 2025-03-08 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • ปุ่มเป็นองค์ประกอบสำคัญในการสร้างเว็บแอปพลิเคชันแบบไดนามิก ใช้สำหรับเปิดเมนู สลับงาน และส่งฟอร์ม
  • ใน Chrome 135 มีการเพิ่มแอตทริบิวต์ command และ commandfor ใหม่ เพื่อปรับปรุงและแทนที่แอตทริบิวต์เดิมอย่าง popovertargetaction และ popovertarget
  • ปัญหาที่เกิดขึ้นเมื่อสร้างพฤติกรรมของปุ่มแบบเดิม:
    • ตัวจัดการ onclick ของ HTML อาจถูกจำกัดการใช้งานในโค้ดจริงเนื่องจากนโยบายความปลอดภัย (CSP)
    • ต้องซิงก์สถานะของปุ่มกับองค์ประกอบอื่น และโค้ดสำหรับจัดการสถานะโดยยังคงการเข้าถึงได้ดีนั้นมีความซับซ้อน
    • แม้ใน React, AlpineJS, Svelte เป็นต้น การจัดการสถานะและอีเวนต์ก็ยังซับซ้อน

แพตเทิร์น command และ commandfor

  • เมื่อใช้แอตทริบิวต์ command และ commandfor ปุ่มจะสามารถทำงานกับองค์ประกอบอื่นแบบประกาศได้ ช่วยมอบความสะดวกแบบเฟรมเวิร์กพร้อมคงความยืดหยุ่นไว้
  • ปุ่ม commandfor ใช้ ID (คล้ายแอตทริบิวต์ for) และ command รับค่าที่มีมาให้ในตัว ทำให้แนวทางนี้เข้าใจง่ายขึ้น
  • ตัวอย่าง: การทำปุ่มเปิดเมนู
    • ไม่ต้องใช้ aria-expanded หรือ JavaScript เพิ่มเติม
    
      Open Menu
    
    

command และ commandfor เทียบกับ popovertargetaction และ popovertarget

  • หากเคยใช้ popover มาก่อน คุณอาจคุ้นเคยกับแอตทริบิวต์ popovertarget และ popovertargetaction
  • ทั้งสองทำงานคล้ายกับ commandfor และ command แต่เจาะจงสำหรับ popover
  • แอตทริบิวต์ใหม่เข้ามาแทนที่แอตทริบิวต์เดิมทั้งหมด พร้อมเพิ่มความสามารถเพิ่มเติม

คำสั่งในตัว

  • แอตทริบิวต์ command มีการทำงานในตัวที่แมปกับ API หลายตัว
    • show-popover: แมปกับ el.showPopover()
    • hide-popover: แมปกับ el.hidePopover()
    • toggle-popover: แมปกับ el.togglePopover()
    • show-modal: แมปกับ dialogEl.showModal()
    • close: แมปกับ dialogEl.close()
  • ตัวอย่าง: การทำไดอะล็อกยืนยันการลบ
    • จัดการสถานะและการเข้าถึงได้โดยไม่ต้องใช้ JavaScript
    
      Delete Record
    
        Delete Record?
    
      Are you sure? This action cannot be undone
    
          Cancel
    
          Delete
    
    
    • โค้ดสำหรับจัดการผลลัพธ์: สามารถจัดการค่าที่ส่งกลับได้ในอีเวนต์ close ของไดอะล็อก
    dialog.addEventListener("close", (event) => {
      if (event.target.returnValue === "cancel") {
        console.log("Cancel was clicked");
      } else if (event.target.returnValue === "delete") {
        console.log("Delete was clicked");
      }
    });
    

คำสั่งแบบกำหนดเอง

  • นอกจากคำสั่งในตัวแล้ว ยังสามารถกำหนดคำสั่งเองได้ด้วยการใช้คำนำหน้า --
  • คำสั่งแบบกำหนดเองจะทำให้เกิดอีเวนต์ "command" บนองค์ประกอบเป้าหมาย แต่จะไม่ทำตรรกะเพิ่มเติมเอง
  • ตัวอย่าง: การทำคำสั่งหมุนภาพ
    
      Landscape
    
      Portrait
    
      const image = document.getElementById("the-image");
      image.addEventListener("command", (event) => {
        if (event.command === "--rotate-landscape") {
          image.style.rotate = "-90deg";
        } else if (event.command === "--rotate-portrait") {
          image.style.rotate = "0deg";
        }
      });
    
    

การจัดการคำสั่งใน Shadow DOM

  • ใน Shadow DOM มีข้อจำกัดต่อไปนี้เนื่องจาก commandfor ทำงานบนพื้นฐานของ ID:
    • ไม่สามารถอ้างอิงองค์ประกอบข้าม Shadow DOM ได้
    • ในกรณีนี้สามารถใช้ JavaScript API เพื่อตั้งค่าพร็อพเพอร์ตี .commandForElement ได้
  • ตัวอย่าง: การเชื่อมคำสั่งใน Shadow DOM
    
        Show popover
    
      customElements.define("my-element", class extends HTMLElement {
        connectedCallback() {
          const popover = this.querySelector('[popover]');
          this.shadowRoot.querySelector('button').commandForElement = popover;
        }
      });
    
    

แผนในอนาคต

  • Chrome มีแผนจะเพิ่มคำสั่งในตัวเพิ่มเติม เช่น:
    • การเปิดและปิดองค์ประกอบ ``
    • รองรับคำสั่ง "show-picker" ใน และ
    • คำสั่งเล่นสำหรับ และ
    • ความสามารถในการคัดลอกข้อความจากองค์ประกอบ

1 ความคิดเห็น

 
GN⁺ 2025-03-08
ความเห็นจาก Hacker News
  • นักทฤษฎีภาษาการเขียนโปรแกรมคาดเดาเกี่ยวกับ "comefrom" ซึ่งเป็นเวอร์ชันที่ทรงพลังกว่าของ "goto" มาตั้งแต่ยุค 80 โดยสิ่งนี้ถูกนำไปใช้จริงเฉพาะใน intercal เท่านั้น แม้ intercal จะเหนือกว่าภาษาอย่าง C ในด้านความปลอดภัย ประสิทธิภาพ และการยศาสตร์ แต่กลับประสบปัญหาในการเข้าสู่ตลาดเชิงพาณิชย์ การได้เห็น javascript นำความสามารถนี้ของ intercal มาใช้เป็นเรื่องน่าสนใจ และหวังว่าสิ่งนี้จะนำไปสู่การเติบโตของการเขียนโปรแกรมแบบสุภาพ เช่นเดียวกับที่อ็อบเจ็กต์แบบ closure ของ javascript เคยผลักดัน functional programming เข้าสู่กระแสหลัก

  • Invokers ไม่ได้มีเฉพาะใน Chrome เท่านั้น ใน Firefox nightly ก็ใช้งานได้แล้วเช่นกัน

  • แนวคิดในการทำพฤติกรรม UI แบบประกาศโดยไม่ใช้ JS นั้นน่าสนใจ

    • ช่วยลบ boilerplate ของ popover/modal ออกไป (ไม่ต้องจัดการ aria-expanded)
    • คำสั่งที่มีมาให้ในตัวอย่าง show-modal ผสานเรื่องการเข้าถึงเข้ากับมาร์กอัป
    • คำสั่งแบบกำหนดเอง (เช่น --rotate-landscape) ทำให้คอมโพเนนต์สามารถเปิดเผย API ผ่าน HTML ได้
  • ข้อสงสัย:

    • abstraction vs. magic: นี่เป็นแค่การย้ายความซับซ้อนจาก JS ไปไว้ใน HTML หรือไม่? เฟรมเวิร์กก็มีการ abstraction สถานะอยู่แล้ว แล้วสิ่งนี้จะอยู่ร่วมกันอย่างไร?
    • ปัญหากับ Shadow DOM: การตั้งค่า .commandForElement ข้าม shadow roots ยังต้องใช้ JS อยู่ดี จึงดูเหมือนเป็นปัญหาที่แก้ไปได้แค่ครึ่งเดียว
    • การรองรับอนาคต: ถ้า OpenUI เพิ่มคำสั่งมากกว่า 20 รายการ (เช่น show-picker, toggle-details) แพลตฟอร์มจะบวมด้วยไวยากรณ์เฉพาะทางหรือไม่?
  • สเปก:

    • button element, แอตทริบิวต์ commandfor
    • button element, แอตทริบิวต์ command
  • นี่คือแพตเทิร์น action/messaging ที่ Next, Be, Apple และรายอื่น ๆ ใช้เมื่อราว 30 ปีก่อนหรือเปล่า หรือฉันกำลังพลาดอะไรบางอย่าง?

    • มันมีประโยชน์ แต่ก็พัฒนาไปเป็นแพตเทิร์นคอนโทรลเลอร์แบบอิงอินเทอร์เฟซ เนื่องจากความซับซ้อนในการพยายามคงแพตเทิร์นการออกแบบพื้นฐานเอาไว้ ดังนั้นถ้าเปิดกล่องนี้ขึ้นมา ก็คาดว่าจะมีคำขอปรับปรุงตามมาอีกมาก
  • ชุดเครื่องมือ Java UI ยุคแรกของ Netscape (IFC) ก็เคยทำให้สามารถเชื่อมองค์ประกอบแบบ action เข้าด้วยกันได้

  • แอตทริบิวต์ command และ commandfor ใหม่ ช่วยปรับปรุงและมาแทนที่แอตทริบิวต์ popovertargetaction และ popovertarget

    • สิ่งเหล่านี้กลายเป็นสิ่งที่ใช้ได้โดยปริยายแล้วหรือ? คำว่าแทนที่หมายถึงอะไร? สุดท้ายแล้วจะลบของเดิมออกหรือไม่? นักพัฒนาเว็บไม่สามารถลบของที่ไม่จำเป็นแล้วออกจากอัปเดตได้
  • แพ้ทางอย่างแรงกับการเขียนโปรแกรมผ่านสตริง เข้าใจข้อดีด้าน accessibility แต่ไม่ได้ตื่นเต้นเป็นพิเศษกับการใช้ element ID เป็นอีกชั้นหนึ่งของพฤติกรรมเว็บแอป

  • ไม่ควรทำสิ่งนี้โดยไม่มี API ที่ครบถ้วน แทนที่จะมีคำสั่งสัก 5 คำสั่ง มันดูเหมือนควรทำให้ความสามารถทั้งหมดของ JavaScript ใช้งานผ่าน HTML ได้ ซึ่งอาจกลายเป็นคำสั่งนับพันรายการ

  • ตอนแรกนึกว่าจะเป็นเรื่อง command and conquer ใน HTML

  • การปรับปรุงและขยาย HTML เป็นเรื่องดี แต่ยังต้องไปอีกไกล ทีม HTMX มีไอเดียดี ๆ อยู่บ้าง