ฉันเพิ่งทำงานในโปรเจ็กต์แชท H5 เมื่อเร็ว ๆ นี้ และฉันได้พบหนึ่งในข้อผิดพลาดที่ใหญ่ที่สุด: กล่องอินพุตได้รับการโฟกัส แป้นพิมพ์ลัดปรากฏขึ้น และกล่องอินพุตจำเป็นต้องถูกดูดซับ (หรือเติมไว้) ในวิธีการป้อนข้อมูล กล่อง. ข้อกำหนดมีความชัดเจนและดูเรียบง่าย แต่จริงๆ แล้วไม่เป็นเช่นนั้น หลังจากทดลองใช้บางรุ่นแล้วพบว่ามีปัญหาหลักๆ ดังนี้
มาสำรวจแนวทางแก้ไขปัญหาที่กล่าวมาข้างต้นทีละรายการ
รับป๊อปอัปและสถานะการถอนกลับของซอฟต์คีย์บอร์ดสิ่งสำคัญคือต้องทราบว่าซอฟต์คีย์บอร์ดขึ้นหรือลง และการประมวลผลความเข้ากันได้ในภายหลังจะต้องเป็นไปตามนี้ อย่างไรก็ตาม H5 ไม่ได้ตรวจสอบเหตุการณ์ดั้งเดิมของซอฟต์คีย์บอร์ดโดยตรง แต่จะสามารถตรวจสอบประสิทธิภาพด้านอื่น ๆ ของเพจทางอ้อมได้โดยการเปิดหรือถอนซอฟต์คีย์บอร์ดกลับเท่านั้น เพื่อช่วยประเทศ นอกจากนี้ประสิทธิภาพบน IOS และ Android ยังแตกต่างกัน
ประสิทธิภาพป๊อปอัปคีย์บอร์ดอ่อนของ IOSบน iOS เมื่อกล่องอินพุต (อินพุต พื้นที่ข้อความ หรือ Rich Text) ได้รับโฟกัส แป้นพิมพ์จะปรากฏขึ้น หน้า (webview) จะไม่ถูกบีบอัด หรือความสูง (ความสูง) จะไม่เปลี่ยนแปลง แต่หน้า (webview) เป็น เลื่อนขึ้นทั้งหมด และความสูงเลื่อนสูงสุด (scrollTop) คือความสูงของแป้นพิมพ์นุ่ม
ประสิทธิภาพป๊อปอัปคีย์บอร์ดนุ่มของ Androidในทำนองเดียวกัน บน Android กล่องป้อนข้อมูลจะได้รับการโฟกัสและแป้นพิมพ์ปรากฏขึ้น แต่ความสูงของหน้า (webview) จะเปลี่ยนไป โดยทั่วไปแล้ว ความสูงคือความสูงของพื้นที่ที่มองเห็น (ความสูงเดิมลบด้วยความสูงของแป้นพิมพ์นุ่ม) ) ยกเว้นเนื่องจากเนื้อหาของหน้ากำลังขยายสามารถสร้างการเลื่อนได้ แต่ webview เองไม่สามารถเลื่อนได้
ประสิทธิภาพการยุบคีย์บอร์ดอ่อนของ IOSเมื่อปุ่มถอนกลับบนคีย์บอร์ดอ่อนหรือพื้นที่หน้านอกกล่องป้อนข้อมูลถูกทริกเกอร์ กล่องป้อนข้อมูลจะสูญเสียโฟกัสและคีย์บอร์ดนุ่มจะถอยกลับ
ประสิทธิภาพการยุบคีย์บอร์ดนุ่มของ Androidเมื่อพื้นที่ภายนอกกล่องป้อนข้อมูลถูกทริกเกอร์ กล่องอินพุตจะสูญเสียโฟกัสและซอฟต์คีย์บอร์ดจะหดกลับ อย่างไรก็ตาม เมื่อปุ่มถอนกลับบนแป้นพิมพ์ถูกทริกเกอร์ กล่องป้อนข้อมูลจะไม่สูญเสียโฟกัส และซอฟต์คีย์บอร์ดก็จะถูกถอนกลับด้วย
ตรวจสอบป๊อปอัปและการยุบของซอฟต์คีย์บอร์ดจากประสิทธิภาพที่แตกต่างกันข้างต้นของป๊อปอัปและการยุบแป้นพิมพ์บน IOS และ Android เราสามารถดำเนินการต่อไปนี้แยกกันเพื่อตรวจสอบป๊อปอัปและการยุบของซอฟต์คีย์บอร์ด:
// ตัดสินประเภทอุปกรณ์ varพิพากษาDeviceType = function () { var ua = window.navigator.userAgent.toLocaleLowerCase(); var isIOS = /iphone|ipad|ipod/.test(ua); ( ua); return { isIOS: isIOS, isAndroid: isAndroid }}()// ฟังป๊อปอัปคีย์บอร์ดนุ่มและยุบฟังก์ชันเหตุการณ์ของกล่องอินพุต ListenKeybord($input) { if (judgeDeviceType.isIOS) { // แป้นพิมพ์ IOS ปรากฏขึ้น: กล่องอินพุต IOS และ Android ได้รับโฟกัส และแป้นพิมพ์ปรากฏขึ้น $input.addEventListener('focus', function () { console.log(' แป้นพิมพ์ IOS ปรากฏขึ้น! '); // การทำงานหลังจากแป้นพิมพ์ IOS ปรากฏขึ้น}, false) // แป้นพิมพ์ IOS หดกลับ: IOS หากคุณคลิกนอกช่องป้อนข้อมูลหรือคลิกปุ่มถอนกลับ กล่องป้อนข้อมูลจะสูญเสียโฟกัสและแป้นพิมพ์จะถอนกลับ $input.addEventListener('blur', () => { console.log('IOS keyboard retracted!') ; // การทำงานหลังจากพับแป้นพิมพ์ IOS }) } // แป้นพิมพ์ Andriod ถูกพับ: เมื่อแป้นพิมพ์ Andriod ปรากฏขึ้นหรือพับ ความสูงของหน้าจะเปลี่ยนไป และจากนี้ แป้นพิมพ์จะถูกพับถ้า (judgeDeviceType.isAndroid) { var originHeight = document.documentElement.clientHeight ||. document.body.clientHeight; window.addEventListener('resize', function () { var resizeHeight = document.documentElement.clientHeight || document.body.clientHeight; ถ้า (originHeight < ปรับขนาดความสูง) { console.log('แป้นพิมพ์ Android ถูกย้าย!'); // การทำงานหลังจากแป้นพิมพ์ Android ถูกย้ายออกไป} else { console.log('แป้นพิมพ์ Android ปรากฏขึ้น! '); // การดำเนินการหลังจากแป้นพิมพ์ Android ปรากฏขึ้น} originHeight = resizeHeight; }, false) }}var $inputs = document.querySelectorAll('.input');for (var i = 0; i < $inputs.length; i++) { ListenKeybord($อินพุต[i]);}เมื่อเปิดคีย์บอร์ดอ่อน กล่องป้อนข้อมูลจะเลื่อนไปยังพื้นที่ที่มองเห็นได้เสมอ
บางครั้งเราจะสร้างแบบฟอร์มป้อนข้อมูลที่มีรายการป้อนข้อมูลจำนวนมาก กล่องป้อนข้อมูลจะได้รับการโฟกัสและแป้นพิมพ์อ่อนจะปรากฏขึ้น เมื่อกล่องอินพุตอยู่ที่ส่วนล่างของหน้า บน IOS มุมมองเว็บทั้งหมดจะถูกม้วนขึ้นไปตามระยะที่กำหนด เพื่อให้กล่องอินพุตที่โฟกัสอยู่ในพื้นที่ที่มองเห็นได้โดยอัตโนมัติ อย่างไรก็ตาม กรณีนี้จะไม่เกิดขึ้นบน Android จะเปลี่ยนเฉพาะความสูงของหน้า โดยไม่ต้องเลื่อนไปยังองค์ประกอบที่โฟกัสอยู่ในพื้นที่ที่มองเห็นได้
เนื่องจากสิ่งที่กล่าวมาข้างต้นถูกนำมาใช้เพื่อตรวจสอบป๊อปอัปและการถอนคีย์บอร์ด IOS และ Android ที่นี่ คุณเพียงแค่ต้องเลื่อน (scrollIntoView()) องค์ประกอบโฟกัสไปยังพื้นที่ภาพหลังจากที่แป้นพิมพ์ Android ปรากฏขึ้น หากต้องการดูผลกระทบคุณสามารถคลิกที่นี่
// รับองค์ประกอบโฟกัสและเลื่อนไปที่ฟังก์ชันพื้นที่มองเห็นได้ activeElementScrollIntoView(activeElement, ความล่าช้า) { var editable = activeElement.getAttribute('contenteditable') // ช่องป้อนข้อมูล พื้นที่ข้อความ หรือ Rich Text จะไม่เลื่อนไปยังพื้นที่ที่มองเห็นได้หลังจากได้รับ พื้นที่โฟกัสถ้า (activeElement.tagName == 'INPUT' || activeElement.tagName == 'TEXTAREA' || แก้ไขได้ === '' || แก้ไขได้) { setTimeout(function () { activeElement.scrollIntoView(); }, Delay) }}// ...// ดำเนินการ activeElementScrollIntoView($input, 1000);// ... หลังจากที่แป้นพิมพ์ Android ปรากฏขึ้นชวนให้นึกถึงคีย์บอร์ดอ่อนตัวเลขล้วนๆ
ช่องป้อนแบบฟอร์มด้านบนกำหนดให้คุณต้องป้อนหมายเลขโทรศัพท์ ในลักษณะนี้ แป้นพิมพ์ตัวเลขจะปรากฏขึ้นมา เนื่องจากเราพูดถึงความเข้ากันได้ของแป้นพิมพ์นุ่ม เราจึงใส่ไว้ที่นี่ ทางออกที่ดีกว่ามีดังนี้:
<p>กรุณากรอกหมายเลขโทรศัพท์มือถือของคุณ</p><input type=tel novalidate=novalidate pattern=[0-9]* class=input>
หากคุณใช้เบราว์เซอร์ WeChat เวอร์ชัน IOS12 และ V6.7.4+ เพื่อเปิดการสาธิตการป้อนข้อมูลแบบฟอร์มด้านบน คุณจะประหลาดใจที่พบว่าหลังจากที่หดแป้นพิมพ์กลับ หน้าที่เดิมถูกเลื่อนขึ้นจะไม่กลับไปที่ตำแหน่งด้านล่าง ส่งผลให้ แป้นพิมพ์เดิมที่จะเด้งตำแหน่งเริ่มต้นว่างเปล่า
นี่เป็นข้อบกพร่องของ Apple ใน iOS และจะปรากฏบนอุปกรณ์ IOS12 ทั้งหมดที่มาพร้อมกับ Xcode10 WeChat ได้ให้วิธีแก้ปัญหาอย่างเป็นทางการแล้ว เพียงเลื่อนหน้า (webview) กลับไปที่ตำแหน่งด้านล่างของหน้าต่าง (ตำแหน่ง clientHeight) หลังจากปิดคีย์บอร์ดอ่อนแล้ว สามารถคลิกการสาธิตการป้อนข้อมูลแบบฟอร์มด้านบนที่ได้รับการซ่อมแซมแล้วได้ที่นี่
console.log('IOS keyboard is put away!');// เบราว์เซอร์ WeChat เวอร์ชัน 6.7.4+IOS12 จะแสดงว่าหลังจากวางคีย์บอร์ดแล้ว มุมมองจะถูกผลักขึ้นแต่ไม่ลง var wechatInfo = window.navigator.userAgent .match( /MicroMessenger//([/d/.]+)/i);if (!wechatInfo) return;var wechatVersion = wechatInfo[1];var version = (navigator.appVersion).match(/OS (/d+)_(/d+)_?(/d+)?/);if (+wechatVersion.replace(//./g, '') >= 674 && +version[1] >= 12) { window.scrollTo(0, Math.max(document.body.clientHeight, document.documentElement.clientHeight));}เข้ากันได้กับวิธีการป้อนข้อมูลของบุคคลที่สาม
อย่างที่กล่าวไปข้างต้น ความจริงแล้วมากกว่าครึ่งหนึ่งของข้อผิดพลาดของกล่องป้อนข้อมูลแชท H5 ได้ถูกเติมเต็มแล้ว ต่อไป มาดูโครงสร้าง HTML พื้นฐานของกล่องป้อนข้อมูลแชทกัน
<div class=chat__content> <div> <p>เนื้อหาแชทบางส่วน 1</p> </div> <!--ละเว้นเนื้อหาแชทนับพันบรรทัด--></div><div class=input__content> <div class =input contenteditable=true></div> <button>ส่ง</button></div>
สไตล์
/* ละเว้นบางสไตล์ */.chat__content { ความสูง: calc (100% - 40px); ขอบล่าง: 40px; overflow-y: อัตโนมัติ; ตำแหน่ง: สัมบูรณ์; ซ้าย: 0; ขวา: 0; ด้านล่าง: 0; align-items: center;}/* ละเว้นบางสไตล์*/
ง่ายมาก เพียงแบ่งพื้นที่เนื้อหาและพื้นที่อินพุตออกจากกัน ตามวิธีการสาธิตอินพุตของแบบฟอร์มข้างต้น เบราว์เซอร์ Android ส่วนใหญ่ใช้งานได้ดี แต่การทดสอบนั้นทำได้บน UC Browser วิธีการป้อนข้อมูลดั้งเดิมและสำหรับวิธีการป้อนข้อมูลของบุคคลที่สาม (เช่น วิธีการป้อนข้อมูล Sogou) ช่องป้อนข้อมูลจะถูกบล็อกโดยสิ้นเชิง สำหรับเบราว์เซอร์ QQ หรือเบราว์เซอร์ WeChat ด้วยวิธีป้อนข้อมูลของบุคคลที่สาม กล่องป้อนข้อมูลจะถูกบล็อกครึ่งหนึ่ง ด้วยเบราว์เซอร์ Baidu ด้วยวิธีป้อนข้อมูลของบุคคลที่สาม กล่องอินพุตจะถูกบล็อก และจะถูกปกปิดอย่างสมบูรณ์เช่นกัน หากต้องการดูเอฟเฟกต์ คุณสามารถไปที่นี่ในเบราว์เซอร์ที่เกี่ยวข้อง
บน UC Browser หลังจากที่ซอฟต์คีย์บอร์ดป็อปอัพ ความสูงของแถบหัวเรื่องเหนือเบราว์เซอร์จะมีเอฟเฟกต์ไดนามิกดีเลย์จากความสูงที่ลดลง ซึ่งทำให้ webview เลื่อนลงเล็กน้อยและช่องป้อนข้อมูลด้านล่างเพื่อเลื่อนไปที่ตำแหน่งที่ไม่ใช่ พื้นที่ที่มองเห็นได้
สำหรับวิธีการป้อนข้อมูลของบริษัทอื่น คาดว่าการวางตำแหน่งการเลื่อนเริ่มต้นของ webview นั้นไม่ถูกต้อง เนื่องจากการคำนวณความสูงไม่ถูกต้องหลังจากที่แผงวิธีการป้อนข้อมูลปรากฏขึ้น ที่จริงแล้ว สองประเด็นนี้เกิดจากการที่ WebView ไม่ได้เลื่อนเข้าที่ หลังจากที่ซอฟต์คีย์บอร์ดป็อปอัพ คุณสามารถเลื่อนองค์ประกอบโฟกัสไปยังพื้นที่ที่มองเห็นได้อีกครั้ง เพื่อบังคับให้ WebView ม้วนเข้าที่
console.log('แป้นพิมพ์ Android ปรากฏขึ้น!');activeElementScrollIntoView($input, 1,000);โซลูชันแฮ็คที่เข้ากันได้กับเบราว์เซอร์ Android Xiaomi
บนเบราว์เซอร์ Xiaomi ของ Android หลังจากใช้วิธีแก้ปัญหาข้างต้น ฉันพบว่าช่องป้อนข้อมูลแชทยังคงถูกบล็อกอย่างแน่นหนา และ scrollIntoView() ยังคงนิ่งอยู่ ดังนั้นฉันเดาว่าจริงๆ แล้วเป็นเพราะซอฟต์คีย์บอร์ดถูกเลื่อนไปที่ด้านล่าง และความสูงของหน้านั้นมากกว่าความสูงของพื้นที่ภาพเมื่อซอฟต์คีย์บอร์ดปรากฏขึ้น ด้วยวิธีนี้ ความสูงของหน้าจะสามารถเพิ่มขึ้นได้หลังจากนั้นเท่านั้น แป้นพิมพ์อ่อนจะปรากฏขึ้นเพื่อให้สามารถแสดงกล่องอินพุตได้ จากข้อมูลข้างต้น สามารถใช้งานร่วมกับวิธีการป้อนข้อมูลของบุคคลที่สาม หากต้องการดูเอฟเฟกต์ คุณสามารถคลิกที่นี่
// การถอนแป้นพิมพ์ Andriod: ความสูงของหน้าจะเปลี่ยนเมื่อแป้นพิมพ์ Andriod ปรากฏขึ้นหรือหดกลับ ตามนี้ การถอนแป้นพิมพ์จะทราบได้ว่า (judgeDeviceType.isAndroid) { var originHeight = document.documentElement.clientHeight || document. body.clientHeight ; window.addEventListener ('ปรับขนาด', ฟังก์ชั่น () { var resizeHeight = document.documentElement.clientHeight || document.body.clientHeight; if (originHeight < resizeHeight) { console.log('Android keyboard is close!'); // แก้ไขปัญหาที่กล่องอินพุตยังคงถูกบล็อกโดยวิธีการป้อนข้อมูลในเบราว์เซอร์ Xiaomi if (judgeDeviceType.isMiuiBrowser ) { document.body.style.marginBottom = '0px'; } } else { console.log('แป้นพิมพ์ Android ปรากฏขึ้น!'); แก้ไขปัญหาที่กล่องอินพุตยังคงถูกบล็อกโดยวิธีการป้อนข้อมูลในเบราว์เซอร์ Xiaomi if (judgeDeviceType.isMiuiBrowser) { document.body.style.marginBottom = '40px'; } activeElementScrollIntoView($input, 1000 } originHeight = resizeHeight; }, เท็จ )}สรุป
ฝั่ง H5 มีเส้นทางข้างหน้าอีกยาวไกลและมีหลุมพรางมากมาย ดังนั้นคุณจึงต้องพยายามต่อไป การทำความเข้าใจความแตกต่างด้านประสิทธิภาพระหว่างหน้าป๊อปอัปคีย์บอร์ดอ่อนบน IOS และ Android ถือเป็นข้อกำหนดเบื้องต้น ขั้นตอนที่สองคือการเลื่อนองค์ประกอบโฟกัสไปยังพื้นที่ที่มองเห็นได้ ในเวลาเดียวกัน ความแตกต่างในวิธีการป้อนข้อมูลของบุคคลที่สามและเบราว์เซอร์บางตัว จะต้องนำมาพิจารณา
ข้างต้นคือเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการศึกษาของทุกคน ฉันหวังว่าทุกคนจะสนับสนุน VeVb Wulin Network