placeholder的兼容處理(jQuery下)

這是一個老問題,結合前輩們的經驗,需要處理的問題有一下幾個。

  1.只有輸入框(input/textarea)下的palaceholder屬性存在的時候才需要處理這類兼容

  2.處理好輸入框上焦點和是焦點的文本顯示

  3.密碼輸入框比較特殊,因爲爲其設置顯示文本時顯示的是一串“***”。這個問題後面分析。處理好前兩點還是比較簡單的,處理源碼爲如下

var browserSupport = {
    placeholder: 'placeholder' in document.createElement('input')
}

$(function() {
    //模擬placeholder
    if( !browserSupport.placeholder){
        $('input[placeholder],textarea[placeholder]').each(function(){
            var that = $(this),
                text= that.attr('placeholder'),
                oldType; 
            if(that.val()===""){
                that.val(text).addClass('placeholder');                
            }   
            that.focus(function(){
                //ie8下readonly依然可以上焦點的處理
                if(that.attr('readonly')){
                    that.blur();
                    return;
                }
                
                that.removeClass('placeholder');
                
                if(that.val()===text){   
                    that.val("");   
                }   
            }).blur(function(){
                if(that.val()===""){ 
                    that.val(text).addClass('placeholder');
                //防止異常情況:當有placeholder類,且值不爲空(代碼設置值時容易出現)
                }else{
                    that.removeClass('placeholder');
                }   
            }).closest('form').submit(function(){   
                if(that.val() === text){   
                    that.val('');   
                }   
            });   
        });
    }
});    

  可以看出處理還是比較簡單的。在不支持placeholder的瀏覽器下沒有上焦點的爲placeholder的空白輸入框添加class placeholder並設置其內容爲placeholder值。上焦點的placeholder的輸入框判斷其值是否是手動設置的placeholder值,如果是則重置輸入框爲空白。當然免不了提交表單的時候要清除兼容placeholder的影響。

  這裏面有一個細節事件是綁定在標籤對應的緩存中,而不是委託document等祖先節點,爲什麼?有兩個考慮:1.避免有設置事件禁止冒泡導致綁定到document上的事件沒法處理。2.事件執行的先後順序是先執行綁定到自身節點的事件,然後在冒泡到document節點執行事件源委託到document的事件

  

  至於第3點密碼輸入框的問題。我們首先考慮是當密碼輸入框失焦的時候先更改輸入框的type爲text類型然後按照正常的設置其值爲placeholder值;聚焦的時候將type值設置回來並恢復其值。但是這個存在問題是IE8不允許更改type類型。沒招了,只能額外的添加一個元素來展示密碼輸入框的placeholder值。結果完整的源碼就變成了如下

/*
.placeholder{    
    color: #aaa!important;
}
span.placeholder{
    position: absolute;
    left: 0;
    line-height: 34px;
    padding-left: 12px;
}
*/
var browserSupport = {
    placeholder: 'placeholder' in document.createElement('input')
}

/* ajax請求發現未登錄時,服務端返回401錯誤,然後此處統一處理401錯誤,跳轉到登錄頁面 */
$(document).ready(function() {
    //模擬placeholder
    if( !browserSupport.placeholder){
        $('input[placeholder],textarea[placeholder]').each(function(){
            var that = $(this),
                text= that.attr('placeholder'),
                oldType; 
            if(that.val()===""){
                if(that.attr('type') != 'password'){
                    that.val(text).addClass('placeholder');  
                }else{
                    that.before('<span class="placeholder">請輸入密碼</span>');
                }
            }   
            that.focus(function(){
                //ie8下readonly依然可以上焦點的處理
                if(that.attr('readonly')){
                    that.blur();
                    return;
                }
                //清除span.placeholder
                that.prev("span.placeholder").remove();
                that.removeClass('placeholder');
                
                if(that.val()===text){   
                    that.val("");   
                }   
            }).blur(function(){
                if(that.val()===""){
                    if(that.attr('type') != 'password'){   
                        that.val(text).addClass('placeholder');
                    }else{
                        that.before('<span class="placeholder">請輸入密碼</span>');
                    }
                //防止異常情況:當有placeholder類,且值不爲空(代碼設置值時容易出現)
                }else{
                    that.removeClass('placeholder');
                }   
            }).closest('form').submit(function(){   
                if(that.val() === text){   
                    that.val('');   
                }   
            });   
        });
        $(document).on('click','span.placeholder',function(){
            $(this).next("[placeholder]").focus();
            //刪除span.placeholder會在[placeholder]的focus中進行
        })
    }
})

  我自己專門添加了一個span.placeholder來顯示密碼輸入框的佔位符顯示。然後添加了一個監聽器監聽span.placeholder被點擊。

  功能是完成了,在測試的時候還是會遇到一個問題,瀏覽器有自動填寫表單的時候初始化可能會出現異常,現在爲止還沒有什麼好的方法捕獲自動填寫表單事件,結果可能導致密碼輸入框的placeholder顯示和內容一起顯示。所以如果要使用這種密碼輸入框的placeholder兼容方式,最好讓瀏覽器不自動填充,也有利於信息保密:給密碼input設置autocomplete=off即可

  需要注意的是autocomplete=off在chrome下也有兼容問題,不過這裏是專門給IE下用的到沒有什麼問題,只不過chrome下是沒有保密而已。更多的信息自行百度。

 

  如果覺得本文不錯,請點擊右下方【推薦】!

發佈了73 篇原創文章 · 獲贊 1 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章