การตรวจสอบฟอร์ม HTML ที่ถูกใช้งานน้อยเกินไป
(expressionstatement.com)- ฟอร์ม HTML มี ความสามารถตรวจสอบแบบเนทีฟ อยู่แล้ว เช่น
required,type="email",pattern,maxlength,setCustomValidityแต่ในการใช้งานจริงกลับถูกใช้ต่ำเมื่อเทียบกับขอบเขตความสามารถ setCustomValidityซึ่งทรงพลังที่สุด สามารถจัดการลอจิกการตรวจสอบแบบกำหนดเองและกรณีซับซ้อนได้ แต่ถูก提供ให้ใช้ได้เฉพาะในรูปแบบ เมธอดของ DOM จึงไม่เข้ากับคอมโพเนนต์แบบ declarative มากนัก- ในสภาพแวดล้อมอย่าง React หากต้องการให้การตรวจสอบค่าเริ่มต้นถูกต้อง จะต้องพัวพันกับ
useRef,useLayoutEffect,onChangeและลอจิกการตรวจสอบเดียวกันมักถูก ทำซ้ำ ทั้งในการเรนเดอร์ครั้งแรกและในตัวจัดการการเปลี่ยนแปลง - หากมี abstraction แบบแอตทริบิวต์อย่าง
custom-validityก็จะสามารถแสดงการตรวจสอบที่มี dependency ระหว่าง state กับ input เช่น การตรวจสอบแบบ asynchronous ว่าชื่อผู้ใช้ซ้ำหรือไม่ หรือการยืนยันรหัสผ่าน ได้ในที่เดียว - การที่การตรวจสอบฟอร์มแบบเนทีฟถูกนำไปใช้น้อยนั้นใกล้เคียงกับปัญหาเรื่อง ความใช้งานง่ายของ API มากกว่าการขาดฟีเจอร์ และหากมี API แบบ declarative อยู่ในสเปก HTML ก็จะเพิ่มโอกาสในการใช้งานได้มากขึ้น
สิ่งที่การตรวจสอบฟอร์ม HTML มีให้อยู่แล้ว
- วิธีที่ง่ายที่สุดในการกันไม่ให้กรอกค่าว่างคือการเพิ่มแอตทริบิวต์
required - ข้อจำกัดของ input สามารถกำหนดได้หลัก ๆ สามวิธี
- ใช้ ประเภท input เช่น
type="email",type="number",type="url" - ใช้ แอตทริบิวต์ข้อจำกัด เช่น
pattern,maxlength - ใช้เมธอด DOM
setCustomValidityของ input
- ใช้ ประเภท input เช่น
setCustomValidityเป็นวิธีที่ทรงพลังที่สุด เพราะสามารถจัดการลอจิกการตรวจสอบแบบกำหนดเองและกรณีซับซ้อนได้- สองวิธีแรกสามารถประกาศเป็นแอตทริบิวต์ HTML ได้ แต่
setCustomValidityต่างออกไปตรงที่ต้อง เรียกเมธอด - มีการเชื่อมโยงเอกสารอ้างอิง Attributes vs Properties ที่พูดถึงความแตกต่างระหว่างแอตทริบิวต์กับพร็อพเพอร์ตีของ DOM
จุดที่ setCustomValidity เริ่มใช้งานไม่สะดวก
setCustomValidityถูกเปิดเผยให้ใช้เฉพาะในรูปแบบเมธอด โดยไม่มีแอตทริบิวต์ HTML ที่สอดคล้องกัน- เมื่อส่งสตริงเข้าไป input จะอยู่ในสถานะ invalid และเบราว์เซอร์จะแสดงสตริงนั้นเป็นเหตุผลที่การตรวจสอบล้มเหลว
- หากส่งสตริงว่างเข้าไป input จะอยู่ในสถานะ valid ตราบใดที่ไม่มีข้อจำกัดอื่น
- หากต้องการทำพฤติกรรมแบบเดียวกับ
requiredเอง จะต้องเรียกsetCustomValidityทุกครั้งที่ค่ามีการเปลี่ยนแปลง - อย่างไรก็ตาม input จะอยู่ในสถานะ valid ในตอนแรก ดังนั้นหากกดปุ่ม submit ทันทีหลังรีเซ็ตคอมโพเนนต์ การส่งฟอร์มอาจผ่านไปได้
- เพราะแม้ค่าจะว่าง แต่โค้ดตรวจสอบจะยังไม่ทำงานก่อนเกิด event การเปลี่ยนแปลง
- หากต้องการให้ครอบคลุมถึงค่าเริ่มต้นด้วย ก็ต้องรันการตรวจสอบเดียวกันตอนที่คอมโพเนนต์ mount ด้วย
Boilerplate ที่เพิ่มขึ้นในคอมโพเนนต์แบบ declarative
- เมื่อต้องจัดการการตรวจสอบค่าเริ่มต้นด้วย โค้ดจะกลายเป็นงานซ้ำ ๆ และไม่สะดวกอย่างรวดเร็ว
- โดยเฉพาะจะเกิดปัญหาสามอย่าง
- ลอจิกการตรวจสอบถูก ทำซ้ำ ทั้งใน handler
onChangeและขั้นตอนการเรนเดอร์ครั้งแรก - โค้ดตรวจสอบเริ่มต้นอยู่ห่างจาก element input ทำให้ cohesion ต่ำลง และมีความเสี่ยงที่จะแก้ไขเพียงด้านใดด้านหนึ่ง
- การผสม
useRef,useLayoutEffect,onChangeจะดูเกินจำเป็นเมื่อจำนวน input เพิ่มขึ้น และจะยิ่งสับสนเมื่อมีเพียงบาง input ที่ใช้customValidity
- ลอจิกการตรวจสอบถูก ทำซ้ำ ทั้งใน handler
- ความซับซ้อนลักษณะนี้จะเด่นชัดเมื่อจัดการ API แบบ imperative ล้วน ๆ ในคอมโพเนนต์แบบ declarative
CustomValidityไม่มีแอตทริบิวต์ input สำหรับตั้งค่าแบบ declarative เหมือนแอตทริบิวต์ตรวจสอบแบบเนทีฟ- หาก API ใช้งานยุ่งยาก แม้ฟีเจอร์จะทรงพลังก็อาจถูกนำไปใช้น้อย และนี่คือสาเหตุหลักของการใช้การตรวจสอบฟอร์มแบบเนทีฟไม่เต็มที่
ชิ้นส่วนที่ขาดหายไป: แอตทริบิวต์ custom-validity
- รูปแบบที่ต้องการคือ แอตทริบิวต์แบบ declarative อย่าง
custom-validityที่กำหนดลงบน input ได้โดยตรง - ในเฟรมเวิร์กแบบ declarative แอตทริบิวต์นี้จะช่วยวางสถานะการตรวจสอบไว้ใกล้กับ element input ได้
- ปัจจุบัน
HTML Specยังไม่มีcustom-validityจริง ๆ - สามารถเลียนแบบพฤติกรรมนี้ได้ด้วย implementation ใน userland เพื่อจุดประสงค์ในการสาธิต
- มี implementation ที่สมบูรณ์กว่า ให้เป็นตัวอย่างคอมโพเนนต์สำหรับ production
การตรวจสอบแบบ asynchronous และ dependency ระหว่าง input
- การตรวจสอบในแอปพลิเคชันจริงอาจซับซ้อนกว่าการเช็กในเครื่อง
- input ชื่อผู้ใช้ต้องตรวจสอบกับเซิร์ฟเวอร์ว่า เป็นชื่อที่ถูกใช้อยู่แล้วหรือไม่ และระหว่างที่ request กำลังทำงาน ฟอร์มไม่ควรอยู่ในสถานะ valid
- ตัวอย่างใช้
requiredเพื่อกัน input ว่าง และทำให้ input อยู่ในสถานะ invalid ด้วยcustomValidityตามสถานะโหลดและผลลัพธ์การตอบกลับ - implementation ประกอบด้วยสองส่วน
- จัดการสถานะ request เพื่อตรวจสอบความ unique ของชื่อผู้ใช้ด้วย
useQueryของreact-query - ใช้คอมโพเนนต์
<Input />แบบกำหนดเองที่รับ propcustomValidityได้
- จัดการสถานะ request เพื่อตรวจสอบความ unique ของชื่อผู้ใช้ด้วย
- วิธีนี้สามารถแสดง flow การตรวจสอบแบบ asynchronous ทั้งหมด รวมถึงสถานะโหลด ข้อผิดพลาด และสำเร็จ ได้ในแอตทริบิวต์เดียว
- ตัวอย่างเพิ่มเติมเป็นฟอร์มที่บังคับให้กรอกรหัสผ่านซ้ำอีกครั้ง ซึ่งจัดการการตรวจสอบ field input ที่พึ่งพากัน
สรุป
setCustomValidityเป็นเครื่องมือที่ทรงพลังซึ่งรองรับความต้องการด้านการตรวจสอบได้หลากหลาย- สิ่งที่กำหนดการใช้งานจริงไม่ใช่แค่การมีอยู่ของฟีเจอร์ แต่รวมถึง API ที่ทำให้ฟีเจอร์นั้นใช้งานง่าย
- abstraction แบบ declarative อย่าง
custom-validityช่วยให้ใช้การตรวจสอบฟอร์มแบบเนทีฟได้อย่างเป็นธรรมชาติมากขึ้น - คาดหวังได้ว่าวันหนึ่งฟีเจอร์ลักษณะนี้อาจถูกบรรจุเข้าไปในสเปก HTML แบบเนทีฟ
1 ความคิดเห็น
ความคิดเห็นบน Hacker News
เท่าที่ตรวจดูครั้งล่าสุด เว็บเบราว์เซอร์ยุคนี้ก็ยังไม่สามารถปรับสไตล์หน้าตาของ ข้อความตรวจสอบความถูกต้อง HTML แบบในตัว ได้ https://stackoverflow.com/questions/5328883/how-do-i-style-t...
ถ้า Chrome กับ Firefox อย่างน้อยทำตามแนวทาง UI ของแพลตฟอร์ม OS จนดูเหมือนเป็นสิ่งที่ระบบแสดงขึ้นมาเอง แบบเดียวกับ tooltip ของ
title=""ก็คงยังพอรับได้ แต่ Chrome ใช้ไอคอนสีเหลือง/ส้ม ตัวอักษรสีดำบนพื้นหลังขาว และกล่องคำพูดมุมมนแบบตายตัว ซึ่งชนกับสุนทรียะของโปรเจกต์ปัจจุบันอย่างแรงChrome สมัยก่อนเคยอนุญาตให้ปรับสไตล์ข้อความตรวจสอบความถูกต้องด้วย pseudo-element selector ที่มี vendor prefix แต่หลังจากถอดฟีเจอร์นั้นออกไปแล้วก็ไม่ได้นำกลับมาอีก เลยต้องใส่ไว้ในรายการความหงุดหงิดจิปาถะ เช่น “ขอ HTML combobox แบบเนทีฟหน่อย”, “ทำไมยังเป็นกล่อง Ctrl+คลิกที่ใช้งานยาก แทนที่จะเป็นรายการ checkbox”
validityแบบเนทีฟของอินพุตแล้วเรนเดอร์ตามต้องการนั้นทำได้ค่อนข้างง่ายปัญหาจริงคือการ subscribe ให้ตรงกับการเปลี่ยนแปลงสถานะความถูกต้องนี้ทำได้ยุ่งยาก มี event ด้านความถูกต้องอยู่ก็จริง แต่ไม่ได้เกิดขึ้นเสมอไป ถ้าเปลี่ยนสถานะฟอร์มด้วยโปรแกรม เช่น เรียก
form.reset()หรือinput.value = '...'event เหล่านี้จะไม่ถูก triggerผมมองว่านี่เป็นหัวข้อที่ดีสำหรับไปสืบค้นเพิ่มเติมและเสนอเข้าสู่เว็บแพลตฟอร์ม
สิ่งที่ใหญ่ที่สุด ทำได้ง่าย แต่กลับถูกใช้น้อย คือการใช้ ค่าแอตทริบิวต์
typeที่เฉพาะเจาะจง อย่างemail,number,urlบนมือถือสามารถแสดงคีย์บอร์ดที่เหมาะที่สุดได้ ทำให้ประสบการณ์ผู้ใช้ดีขึ้นมาก
type=numberแล้วใช้type=text inputmode=numericแทน เพราะจะไม่มีปุ่มลูกศรที่ผู้ใช้ส่วนใหญ่ไม่ต้องใช้ในการกรอกตัวเลข และบน iOS คีย์บอร์ดก็ดีกว่าtypeให้ถูกต้องdateด้วย ไลบรารีฟรอนต์เอนด์แต่ละตัวมีวิดเจ็ตวันที่ของตัวเอง และหลายตัวก็ดูแย่มากบนหน้าจอขนาดเล็กต้องเพิ่ม JS กับ CSS เพียงเพื่อวิดเจ็ตนั้นตัวเดียว และบางตัวก็พึ่งพา jQuery แน่นอนว่าบางตัวมีตัวเลือกตั้งค่าเยอะมาก แต่ด้วยต้นทุนที่เล็กมาก คุณสามารถได้วิดเจ็ตที่ดูใช้ได้ทุกที่และให้ความรู้สึกแบบเนทีฟ โดยทั่วไปก็ตรงกับความต้องการ แถมปล่อยลืมไว้ได้โดยไม่ต้องกังวลเรื่องอัปเดตหรือ CDN
อินพุตทั่วไปยังพอทำได้แบบเฉียดฉิว แต่อินพุตพิเศษรองรับ event น้อยกว่านั้นอีก
ผลิตภัณฑ์ของผมไม่ผ่านการตรวจสอบด้านการเข้าถึงได้ เพราะใช้ การตรวจสอบความถูกต้องของฟอร์ม HTML แบบเนทีฟ และคำแนะนำอย่างเป็นทางการคือให้สร้างชั้นการตรวจสอบความถูกต้องเอง ผมก็เห็นด้วยกับคำแนะนำนั้น
การตรวจสอบความถูกต้องแบบเนทีฟของ HTML มีข้อบกพร่องเยอะ และพูดตรง ๆ การปรับแต่งด้านภาพไม่ใช่เรื่องที่น่ากังวลที่สุดด้วยซ้ำ แต่ก็ค่อนข้างเหมือนตะปูดอกสุดท้ายที่ตอกฝาโลง
เช่น ถ้าต้องการแสดงข้อผิดพลาดหลายรายการต่อฟิลด์พร้อมกัน ก็ทำได้แค่ต่อสตริงเข้าด้วยกัน เช่น “ต้องมีตัวเลข ต้องมีสัญลักษณ์ ต้องยาวกว่า 10 อักขระ” ซึ่งประสบการณ์ผู้ใช้ก็แย่ และด้านการเข้าถึงได้ก็ไม่ดี เพราะไม่สามารถนำทางสตริงที่ต่อกันใน accessibility tree ได้ นี่ไม่ใช่ปัญหาของการ implement แต่ละเจ้า แต่เป็นปัญหาของตัวสเปกเอง ผู้ใช้คงไม่สนุกกับการเล่นตีตัวตุ่นไล่แก้ข้อผิดพลาดการตรวจสอบความถูกต้อง ดังนั้นควรแสดงข้อผิดพลาดหลายรายการพร้อมกันได้
การพึ่งพาเบราว์เซอร์ก็แย่เช่นกัน ควบคุมไม่ได้ และ implementation ส่วนใหญ่ก็ไม่ดีนัก Chrome แสดงป๊อปอัปเมื่อโฟกัส ซึ่งเป็นป๊อปอัป ดูเหมือน modal และไม่สามารถแสดงข้อผิดพลาดของฟอร์มทั้งหมดพร้อมกันได้ จึงไม่ดีต่อการเข้าถึงได้ในตัวมันเอง การไม่แสดงข้อมูลสำคัญในป๊อปอัปเป็นพื้นฐานของการเข้าถึงได้ แต่เบราว์เซอร์ก็ทำอะไรได้ไม่มากนักถ้าไม่รบกวนเอกสารจริง
ข้อผิดพลาดระดับทั้งฟอร์มที่ไม่ได้สังกัดฟิลด์ใดฟิลด์หนึ่งก็ยังต้องใช้การตรวจสอบแบบกำหนดเองอยู่ดี เช่นข้อผิดพลาดอย่าง “ฟิลด์ A และ B ใช้ร่วมกันไม่ได้” และถ้าเป็นแบบนั้น การมีวิธีตรวจสอบความถูกต้องที่สอดคล้องกันย่อมดีกว่า
หากมีอินพุตแบบกำหนดเองที่ไม่เข้ากับ input type แบบเนทีฟ ก็ต้องมีอินพุตที่ซ่อนไว้เพื่อความสอดคล้อง ซึ่งก็ทำลายการเข้าถึงได้เช่นกัน การแก้เรื่องนี้สุดท้ายก็ยากพอ ๆ กับการสร้างระบบตรวจสอบความถูกต้องของตัวเองที่เป็นมิตรต่อการเข้าถึงได้
API
customValidityเป็นแบบ imperative และใช้งานยุ่งยาก เว้นแต่คุณอยากได้ข้อความแย่ ๆ อย่าง “ฟิลด์นี้ไม่ถูกต้อง” แทบจะไม่มีทางเลือกที่จะไม่ใช้ custom validity ดังนั้นการตรวจสอบความถูกต้องของฟอร์ม HTML จึงแย่มากถึงอย่างนั้น ผมก็คิดว่ากลไกการตรวจสอบแบบเนทีฟยังมีคุณค่าให้ใช้อยู่ ไม่จำเป็นต้องใช้ native validity tooltip สำหรับข้อความข้อผิดพลาดเสมอไป สามารถอ่าน
ValidityStateของinput.validityโดยตรง แล้วเรนเดอร์ข้อความในแบบที่ต้องการ และแสดงข้อผิดพลาดหลายรายการได้ถ้าจำเป็นเบราว์เซอร์สามารถปรับปรุงได้ และถ้าใช้แนวทางที่เป็นมาตรฐาน ก็จะได้รับประโยชน์จากการปรับปรุงนั้น ข้อสรุปทำนองว่า “ถ้าไม่ใช้ป๊อปอัป การเข้าถึงได้จะพัง” ฟังดูแปลก แต่ถ้าต้องรับมือกับการตรวจสอบ ก็อาจต้องไปทางนั้น
ข้อผิดพลาดที่ไม่ได้สังกัดฟิลด์ใดฟิลด์หนึ่งก็มีเทคนิคจัดการได้ ในโปรเจกต์ของผม ใช้คอมโพเนนต์
HiddenValidationInputที่สร้างอินพุตอ่านอย่างเดียวที่มองไม่เห็น เพื่อเรนเดอร์ข้อผิดพลาดแบบกำหนดเองที่ไม่ได้สังกัดฟิลด์อื่น แค่เรนเดอร์แบบมีเงื่อนไขก็พอ จึงค่อนข้างใช้งานดีจริง ๆผมเห็นด้วยเต็มที่ว่า API
customValidityเป็นแบบ imperative และยุ่งยาก ผมเขียนบทความที่พูดถึงประเด็นนี้โดยตรงไว้แล้ว และหวังว่าส่วนนี้จะดีขึ้นเมื่อเวลาผ่านไปดีไซน์ที่หยาบและการเข้าถึงได้ต่ำของ Chrome เป็นปัญหาของ Chrome ดังนั้นผมจะส่ง bug report
ที่ว่า “สเปก” หมายถึงอันนี้หรือเปล่า? https://html.spec.whatwg.org/multipage/dom.html#concept-elem...
ผมไม่เห็นส่วนที่นิยามว่าควรแสดงข้อความตรวจสอบความถูกต้องอย่างไร แม้แต่ข้อความที่ว่าต้องมีข้อความก็ยังไม่มี
พูดตรง ๆ ผมรู้สึกว่าคนที่เขียนสเปกแบบนี้อยู่ห่างไกลจากความเป็นจริง และไม่ได้ใช้สิ่งที่ตัวเองสเปกไว้จริง ๆ มันทำงานได้กับสิ่งที่เรียบง่ายมาก ๆ แต่พอฟอร์มเริ่มซับซ้อนขึ้น สุดท้ายก็จะรู้ว่าการเขียนเองทั้งหมดดีกว่า
ทันทีที่เริ่มใช้ JS การทำทุกอย่างด้วยโค้ดจะง่ายกว่าการไปปรับแอตทริบิวต์ตรวจสอบความถูกต้องมาก
ถ้า checkbox มี label ก็อยากให้ใส่แอตทริบิวต์
forให้ label เพื่อให้คลิก label แล้วเปิดปิด checkbox ได้ นี่เป็นหนึ่งในเรื่องที่ผมรำคาญที่สุดเป็นการส่วนตัว แต่อาจมีแค่ผมก็ได้inputด้วยlabelก็ทำงานได้เหมือนกัน ผมไม่ค่อยเข้าใจว่าทำไมคนถึงมักแยกสองอย่างนี้ออกจากกันและก็ไม่เข้าใจว่าทำไมเบราว์เซอร์ถึงเริ่มแยกสิ่งเหล่านี้ออกจากกันด้วย ผมคิดว่าไม่ใช่ให้ข้อความมี checkbox และ radio อยู่ข้างใน แต่ควรเป็น checkbox และ radio ที่มีข้อความอยู่ข้างในมากกว่า
ตัวอย่างง่าย ๆ ที่ไม่ใช้ React อยู่ที่นี่
https://developer.mozilla.org/en-US/docs/Web/API/HTMLObjectE...
การตรวจสอบฟอร์มของ HTML นั้นยอดเยี่ยม แต่มีหลุมพรางใหญ่มากอยู่อย่างหนึ่ง
มันไม่ทำงานใน Firefox สำหรับ Android
https://bugzilla.mozilla.org/show_bug.cgi?id=1510450
มันไม่คุ้มที่จะเพิกเฉยมาตรฐานเพื่อผู้ใช้น้อยกว่า 1% ที่มองไม่เห็นข้อความผิดพลาดของคอนโทรลที่ถูกทำเครื่องหมายสีแดง ยิ่งเว็บไซต์ใช้สิ่งนี้มากเท่าไร แรงกดดันให้ Mozilla แก้เบราว์เซอร์ก็จะยิ่งมากขึ้นเท่านั้น
นี่ไม่ใช่ API แบบ WebMIDI ที่ Chrome หรือ Safari นำไป implement ก่อนการทำให้เป็นมาตรฐาน แต่เป็นส่วนหนึ่งของสเปก HTML5 เดิมอยู่แล้ว
ยิ่งเมื่อคิดว่าเราใช้เวลาน้อยแค่ไหนในการทำให้คนที่ใช้ซอฟต์แวร์ช่วยการเข้าถึงสามารถใช้ไซต์ได้อย่างถูกต้องก็ยิ่งเป็นเช่นนั้น ถ้ายังไม่พร้อมจะพูดถึง UC Browser ผมว่าประเด็นแบบนี้ก็ไม่ค่อยมีคุณค่าพอให้หยิบมาพูดถึง
ถึงอย่างนั้น การใช้ uBlock Origin ร่วมกับส่วนขยายอื่น ๆ ได้ก็ยังเป็นข้อได้เปรียบที่แข็งแกร่ง
[1] https://bugzilla.mozilla.org/show_bug.cgi?id=1884282
[2] https://bugzilla.mozilla.org/show_bug.cgi?id=1897707
ถ้าไม่ได้ implement การตรวจสอบเลยยังจะดีกว่า แต่นี่มันเละเทะจริง ๆ ผมเพิ่งรู้หลังจาก debug อย่างยาวนานและทรมานเมื่อหลายปีก่อน และมั่นใจว่าผมคงไม่ใช่คนแรกและไม่ใช่คนสุดท้ายที่เจอเรื่องแบบเดียวกัน
ก่อนจะลองค้นหา ผมนึกไม่ออกเลยว่าตัวเองพลาดอะไรไป และค่อนข้างช็อก การทำการตรวจสอบเองนั้นพอรับได้ แต่สิ่งนี้ควรต้องทำงาน
ต้องระวังไม่ใช้มากเกินไป
เมื่อไม่นานมานี้ผมพยายามขอ refund จาก Groupon เพราะร้านที่ผมซื้อ Groupon ไว้เปลี่ยนผู้บริหารชุดใหม่และไม่ยอมรับ Groupon ของผม
ฟอร์มมีเงื่อนไขว่า “อย่างน้อย 15 คำ” แต่ไม่ว่าจะทำอย่างไรก็ไม่ผ่านการตรวจสอบ สุดท้ายจึงต้อง inspect HTML
\wคืออักขระของคำ,\bคือขอบเขตคำ,\sคือช่องว่าง และไม่อนุญาตเครื่องหมายวรรคตอนเลยแม้แต่นิดเดียวpatternนั้นเจ๋ง แต่ยังไม่พอตัวอย่างเช่นกรณี “กรอกรหัสผ่านซ้ำ” สามารถ implement ด้วย attribute
patternได้โดยไม่ต้องใช้setCustomValidityแต่ต้องสร้าง regex แบบ dynamic จากค่าที่ป้อนครั้งแรกผมไม่ได้เปรียบเทียบวิธีแก้ต่าง ๆ เพราะกลัวบทความจะยาวเกินไป แต่ประเด็นหลักคือเมื่อใช้
customValidityการตรวจสอบจะชัดเจนและอ่านง่ายขึ้นมาก ในกรณีนี้ API ที่ดีกว่าสร้างความแตกต่างได้มากเงื่อนไข “อย่างน้อย 15 คำ” ก็สามารถแสดงให้อ่านง่ายกว่าได้มาก เช่น
value.split(/\s+/).length >= 15มีเหตุผลที่มันถูกใช้น้อย เฟรมเวิร์กและไลบรารีจำนวนมากมีฟังก์ชันการตรวจสอบที่แข็งแรงและปรับสไตล์ได้ บางตัวก็ซับซ้อนและขยายได้มาก ถ้าไม่จำเป็นต้องลำบาก ก็ไม่ควรทรมานตัวเอง
curl, หรือเครื่องมืออื่นที่ไม่มีการตรวจสอบฟอร์มแบบเดียวกันในตัวเสมอเราเชื่อถือไม่ได้ว่าไคลเอนต์ได้ตรวจสอบแล้วหรือทำอย่างถูกต้องหรือไม่ ดังนั้นแบ็กเอนด์ยังต้องตรวจสอบอินพุตและต้องสามารถแสดงฟอร์มพร้อมข้อผิดพลาดการตรวจสอบของทุกฟิลด์ได้
การตรวจสอบฝั่งฟรอนต์เอนด์มีไว้เพื่อช่วยผู้ใช้เท่านั้น แต่ถ้าจะปรับสไตล์หรือ trigger จากแบ็กเอนด์ตอน submit สุดท้ายก็ต้อง implement สไตล์ของตัวเองอยู่ดี
หลุมพรางมีมากเกินไป และถ้าต้องการรองรับการตรวจสอบที่ซับซ้อนขึ้นได้ง่าย สุดท้ายก็ต้องใช้ไลบรารีอยู่ดี
นอกจากนี้ การใช้ไลบรารียังอาจเปิดโอกาสให้แชร์โค้ดการตรวจสอบบางส่วนระหว่างฟรอนต์เอนด์กับแบ็กเอนด์ได้ในบางกรณี
โดยเฉพาะบทความนี้ดูเหมือนจะใช้
useLayoutEffectเพื่อเลี่ยงปัญหาหนึ่ง ซึ่งไม่ใช่สิ่งที่ควรทำแบบเบา ๆสิ่งหนึ่งที่ผมไม่ชอบในการตรวจสอบฟอร์มของ HTML คือมันเริ่มทำงาน ตั้งแต่ตอนโหลดหน้า ตัวอย่างเช่น ถ้าผูกสไตล์สถานะผิดพลาดไว้กับสิ่งนี้ ฟอร์มจะโหลดขึ้นมาพร้อมข้อผิดพลาดเต็มไปหมดตั้งแต่แรก และอาจดูน่ากดดันสำหรับผู้ใช้
:user-invalidที่ช่วยหลีกเลี่ยงเรื่องนี้ได้ในระดับหนึ่ง แต่ก็มีส่วนที่ไม่ยืดหยุ่น จึงอาจไม่พอขึ้นอยู่กับ use casehttps://developer.mozilla.org/en-US/docs/Web/CSS/:user-inval...
เราสามารถใช้สคริปต์อ้อมได้ แต่เมื่อถึงจุดนั้น ฟีเจอร์นี้ก็แทบไม่ได้ช่วยอะไรแล้ว ผมว่านี่คือเหตุผลใหญ่ที่สุดที่มันไม่ถูกนำไปใช้อย่างแพร่หลายกว่านี้