(移動端)移動端問題整理(輸入法,字符截斷,禁止頁面滾動)


這篇文章主要整理一下這次移動端項目中遇到的一些問題,以及相應的解決方案。閑話不多說了,看問題!

  1. 手機上輸入內容的長度截斷

    具體的需求是這樣的,輸入框輸入的字母和漢字都不能超過 7 個,而且需要實時判斷,超過限制就截斷,並彈出提示彈窗。

    原本計划的解決方案:

    通過Html5的oninput對輸入框的內容進行監聽,同時動態計算輸入內容的長度(由於這里對漢字和字母的長度做了統一要求,都是7,所以這里只是簡單計算了字符串的長度,並沒有針對字符長度進行計算,PS: 一個中文字符長度為2,一個英文字母字符長度為1)。

    然后如果得到的長度超過7,我就對接下來輸入的內容進行判斷,如果是刪除按鈕,就允許輸入;否則就禁止用戶的輸入,我是用的是 return false;

    但是理想很豐滿啊,return false 這里並不起作用,並不能阻止用戶的默認輸入行為。至於這里為什么不起作用,還沒有搞懂,各位要是知道,不妨提點一下啊!

    於是想到了字符串的截取,具體就一行代碼

        this.value = this.value.substr(0, 7);
    
  2. 手機上中文輸入法的虛擬拼音也被 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' );
        } );
    
  3. 禁止頁面的全局滾動

    移動端頁面交互,通常有彈出層,背景需要遮罩。但出現這樣情景的時候,我們其實應該禁止頁面的整體滾動。

    關於這一點,剛開始我還沒考慮太好,但和組里的同事請教,才明白!
    出現彈出層,我們是希望用戶關注彈出層的內容和交互,所以用戶不應該還能滾動遮罩層后面的內容。

    通過這個問題,我想我們平常做項目,實現交互的時候,其實除了溝通正常需求之外,還應該多站在用戶的角度去思考問題。

    這個問題比較容易解決,當出現彈出層的時候,我們設置

        document.addEventListaner('touchmove',stopTouchMove,false);
    

    當彈出層被關閉的時候,再設置

        document.removeEventListaner('touchmove',stopTouchMove,false);
    

    這里還有一個小知識點,就是 removeEventListaner 這個事件,必須傳入函數名,而不是具體的匿名函數才能正確執行。
    所以我們加一個處理函數就可以

        function stopTouchMove( e ) {
          e.preventDefault();
        }
    

### 今天就先寫到這里了,后面要是還有其他的問題,我再來更新

更新,因為出現了新的問題,和新的解決方案

之前寫的處理滾動方案,太簡單了,隨后我就遇到了更加復雜的問題,這里再做一下補充。。。

我們上面 3中的解決方案,遇到這種情況就不使用了。。。

圖片來自http://www.haorooms.com/post/webapp_bodyslidebcdiv圖片來自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中的解決方案。

其他遇到的問題有

輸入框,一定要多考慮特殊的輸入,比如空格啊,特殊字符啊!!!等等。。
輸入框,一定要多考慮特殊的輸入,比如空格啊,特殊字符啊!!!等等。。
輸入框,一定要多考慮特殊的輸入,比如空格啊,特殊字符啊!!!等等。。

今天先補充到這里,有感覺后面可能會再補充一些flex 布局的內容


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM