這篇文章主要整理一下這次移動端項目中遇到的一些問題,以及相應的解決方案。閑話不多說了,看問題!
-
手機上輸入內容的長度截斷
具體的需求是這樣的,輸入框輸入的字母和漢字都不能超過 7 個,而且需要實時判斷,超過限制就截斷,並彈出提示彈窗。
原本計划的解決方案:
通過Html5的oninput對輸入框的內容進行監聽,同時動態計算輸入內容的長度(由於這里對漢字和字母的長度做了統一要求,都是7,所以這里只是簡單計算了字符串的長度,並沒有針對字符長度進行計算,PS: 一個中文字符長度為2,一個英文字母字符長度為1)。
然后如果得到的長度超過7,我就對接下來輸入的內容進行判斷,如果是刪除按鈕,就允許輸入;否則就禁止用戶的輸入,我是用的是 return false;
但是理想很豐滿啊,return false 這里並不起作用,並不能阻止用戶的默認輸入行為。至於這里為什么不起作用,還沒有搞懂,各位要是知道,不妨提點一下啊!
於是想到了字符串的截取,具體就一行代碼
this.value = this.value.substr(0, 7); -
手機上中文輸入法的虛擬拼音也被 oninput 事件監聽
上面的問題搞定了英文字母的輸入,但是手機上中文輸入的時候,輸入法會自動提供虛擬拼音。由於前面的字符截斷,使得輸入的中文 比如 "黃曉明",虛擬拼音卻是huang'xiao'ming 這里就超過了 7,結果就出現了提示彈窗,以及字符截斷。。。。

於是就百度到了 compositionstart, compositionend 這兩個事件!他們能夠判斷到中文輸入開始和結束,這里主要參考了 手機上限制字符長度的正確姿勢
和 經驗總結:應對中文輸入法的字符串截斷方案(帶代碼示例)具體解決方案,兩篇文章介紹的很詳細,我就不多介紹了。這里發下,我和他們差不多的處理代碼吧,主要就是參考了他們代碼,才使得我的項目問題得到解決。
$( '.input').on( 'input', function( e ) { if ( $( this ).attr( 'inputstart' ) === 'no' ) { return false; } $( '.sure' ).attr( 'lengthok', 'yes' ); if( getTextLength( this.value ) > 7 ) { if ( e.keyCode !== 8 ) { $( '.tiptext' ).html( '關鍵詞長度不能超過7' ); $( '.tip' ).show(); setTimeout( function(){ $( '.tip' ).hide(); }, 1500 ); this.value = this.value.substr( 0, 7 ); } } } ).on( 'compositionstart', function() { // 判斷中文輸入開始 $( this ).attr( 'inputstart', 'no' ); } ).on( 'compositionend', function() { // 判斷中文輸入結束,在此期間不觸發 input 事件 $( this ).attr( 'inputstart', 'yes' ); } ); -
禁止頁面的全局滾動
移動端頁面交互,通常有彈出層,背景需要遮罩。但出現這樣情景的時候,我們其實應該禁止頁面的整體滾動。
關於這一點,剛開始我還沒考慮太好,但和組里的同事請教,才明白!
出現彈出層,我們是希望用戶關注彈出層的內容和交互,所以用戶不應該還能滾動遮罩層后面的內容。通過這個問題,我想我們平常做項目,實現交互的時候,其實除了溝通正常需求之外,還應該多站在用戶的角度去思考問題。
這個問題比較容易解決,當出現彈出層的時候,我們設置
document.addEventListaner('touchmove',stopTouchMove,false);當彈出層被關閉的時候,再設置
document.removeEventListaner('touchmove',stopTouchMove,false);這里還有一個小知識點,就是 removeEventListaner 這個事件,必須傳入函數名,而不是具體的匿名函數才能正確執行。
所以我們加一個處理函數就可以function stopTouchMove( e ) { e.preventDefault(); }
### 今天就先寫到這里了,后面要是還有其他的問題,我再來更新
更新,因為出現了新的問題,和新的解決方案
之前寫的處理滾動方案,太簡單了,隨后我就遇到了更加復雜的問題,這里再做一下補充。。。
我們上面 3中的解決方案,遇到這種情況就不使用了。。。
圖片來自http://www.haorooms.com/post/webapp_bodyslidebcdiv
因為3中的解決方案,會使得全局禁止滑動,這樣容器自身的滑動也不能實現了。因為我要處理的彈層是需要底部固定的,所以。。。
第一種思路
它來自於 移動端的touch事件處理,可以利用 event 這個工具去計算滑動的方向以及距離,當比如滑動到這部分的最上邊和最下邊的時候就有
event.preventDefault()
來組織容器內部的滑動。
這里我使用的思路和這個文章寫的一樣,但是具體 event 的用法不太一樣,因為直接 event.pageY 這樣使用會報錯 undefined 的 所以,我列出一下我的代碼
var start_pos;
$( '.container' ).on( 'touchstart', function( e ) {
var touch = e.targetTouches[0];
start_pos = touch.pageY;
} ).on( 'touchmove', function( e ) {
var touch = e.targetTouches[0];
var down_or_up = ( touch.pageY - start_pos > 0 );
var top_distance = $( this ).scrollTop();
if ( down_or_up && top_distance <= 0 ) {
e.preventDefault();
}
} );
這里能夠實現容器內部滑動頂部和底部禁止頁面滾動,但是滑動容器過程中,如果我滑動遮罩層,還是能夠上下滑動我的頁面,因為我的頁面高度一屏不夠的,所以會看到我的彈層也在上下滑動。。。所以這種方案我並不適用
說說最終解決方案
看到了這個提問,移動端禁止遮罩層以下屏幕滑動,給我提供了一種新奇的思路,出現彈層的時候,設置頁面最外層容器,也就是 body 內的第一層容器為 position fixed,取消彈層的時候,再修改為 position absolute 或者 relative 。這種方式果然一下就搞定了,由於外層都固定了,所以里面的容器自己滑動也不會影響整個頁面的滑動了。
仔細想想,還是我的思路一直定位在了js 通過 e.preventDefault() 或 3中的解決方案。
其他遇到的問題有
輸入框,一定要多考慮特殊的輸入,比如空格啊,特殊字符啊!!!等等。。
輸入框,一定要多考慮特殊的輸入,比如空格啊,特殊字符啊!!!等等。。
輸入框,一定要多考慮特殊的輸入,比如空格啊,特殊字符啊!!!等等。。
