jQ進階篇–jQuery封裝placeholder效果,讓低版本瀏覽器支援該效果

風雨後見彩虹發表於2017-07-07

頁面中的輸入框預設的提示文字一般使用placeholder屬性就可以了,即:

<input type="text" name="username"  placeholder="請輸入使用者名稱" value="" id="username"/>

最多加點樣式控制下預設文字的顏色

input::-webkit-input-placeholder{color:#AAAAAA;}

但是在低版本的瀏覽器卻不支援這個placeholder屬性,那麼真的要在低版本瀏覽器也要實現跟placeholder一樣的效果,就需要寫個外掛來相容下,下面就細講一下怎樣用jquery來實現這個模擬效果。

實現這個模擬效果,頁面的一般呼叫方式:

$(`input`).placeholder();

首先,先寫jquery外掛的一般結構:

;(function($){
    $.fn.placeholder = function(){
        //實現placeholder的程式碼
    }
})(jQuery)

下面我們就要判斷瀏覽器是否支援placeholder屬性

;(function($){
    $.fn.placeholder = function(){

        this.each(function(){
            var _this = this;
            var supportPlaceholder = `placeholder` in document.createElement(`input`);
            if(!supportPlaceholder){
                //不支援placeholder屬性的操作

            }
        });
    }
})(jQuery)

我們要支援鏈式操作,如下:

;(function($){
    $.fn.placeholder = function(){

         return this.each(function(){
            var _this = this;
            var supportPlaceholder = `placeholder` in document.createElement(`input`);
            if(!supportPlaceholder){
                //不支援placeholder屬性的操作

            }
        });
    }
})(jQuery)

預設配置項:

options = $.extend({
    placeholderColor:`#aaaaaa`,
    isSpan:false, //是否使用插入span標籤模擬placeholder的方式,預設是不需要
    onInput:true //實時監聽輸入框
},options);
        

如果不需要通過span來模擬placeholder效果,那麼就需要通過輸入框的value值來判斷,如下程式碼:

if(!options.isSpan){
    $(_this).focus(function () {
        var pattern = new RegExp("^" + defaultValue + "$|^$");
        pattern.test($(_this).val()) && $(_this).val(``).css(`color`, defaultColor);
    }).blur(function () {
        if($(_this).val() == defaultValue) {
            $(_this).css(`color`, defaultColor);
        }
        else if($(_this).val().length == 0) {
            $(_this).val(defaultValue).css(`color`, options.placeholderColor)
        }
    }).trigger(`blur`);
}

如果需要同span標籤來模擬placeholder效果,程式碼如下:

var $simulationSpan = $(`<span class="wrap-placeholder">`+defaultValue+`</span>`);
$simulationSpan.css({
    `position`:`absolute`,
    `display`:`inline-block`,
    `overflow`:`hidden`,
    `width`:$(_this).outerWidth(),
    `height`:$(_this).outerHeight(),
    `color`:options.placeholderColor,
    `margin-left`:$(_this).css(`margin-left`),
    `margin-top`:$(_this).css(`margin-top`),
    `padding-left`:parseInt($(_this).css(`padding-left`)) + 2 + `px`,
    `padding-top`:_this.nodeName.toLowerCase() == `textarea` ? parseInt($(_this).css(`padding-top`)) + 2 : 0,
    `line-height`:_this.nodeName.toLowerCase() == `textarea` ? $(_this).css(`line-weight`) : $(_this).outerHeight() + `px`,
    `font-size`:$(_this).css(`font-size`),
    `font-family`:$(_this).css(`font-family`),
    `font-weight`:$(_this).css(`font-weight`)
});

//通過before把當前$simulationSpan新增到$(_this)前面,並讓$(_this)聚焦
$(_this).before($simulationSpan.click(function () {
    $(_this).trigger(`focus`);
}));

//當前輸入框聚焦文字內容不為空時,模擬span隱藏
$(_this).val().length != 0 && $simulationSpan.hide();

if (options.onInput) {
    //繫結oninput/onpropertychange事件
    var inputChangeEvent = typeof(_this.oninput) == `object` ? `input` : `propertychange`;
    $(_this).bind(inputChangeEvent, function () {
        $simulationSpan[0].style.display = $(_this).val().length != 0 ? `none` : `inline-block`;
    });
}else {
    $(_this).focus(function () {
        $simulationSpan.hide();
    }).blur(function () {
        /^$/.test($(_this).val()) && $simulationSpan.show();
    });
};

整體程式碼:

;(function($){
    $.fn.placeholder = function(options){
        options = $.extend({
            placeholderColor:`#aaaaaa`,
            isSpan:false, //是否使用插入span標籤模擬placeholder的方式,預設是不需要
            onInput:true //實時監聽輸入框
        },options);

         return this.each(function(){
            var _this = this;
            var supportPlaceholder = `placeholder` in document.createElement(`input`);
            if(!supportPlaceholder){
                //不支援placeholder屬性的操作
                var defaultValue = $(_this).attr(`placeholder`);
                var defaultColor = $(_this).css(`color`);
                if(!options.isSpan){
                    $(_this).focus(function () {
                        var pattern = new RegExp("^" + defaultValue + "$|^$");
                        pattern.test($(_this).val()) && $(_this).val(``).css(`color`, defaultColor);
                    }).blur(function () {
                        if($(_this).val() == defaultValue) {
                            $(_this).css(`color`, defaultColor);
                        }
                        else if($(_this).val().length == 0) {
                            $(_this).val(defaultValue).css(`color`, options.placeholderColor)
                        }
                    }).trigger(`blur`);
                }else{
                    var $simulationSpan = $(`<span class="wrap-placeholder">`+defaultValue+`</span>`);
                    $simulationSpan.css({
                        `position`:`absolute`,
                        `display`:`inline-block`,
                        `overflow`:`hidden`,
                        `width`:$(_this).outerWidth(),
                        `height`:$(_this).outerHeight(),
                        `color`:options.placeholderColor,
                        `margin-left`:$(_this).css(`margin-left`),
                        `margin-top`:$(_this).css(`margin-top`),
                        `padding-left`:parseInt($(_this).css(`padding-left`)) + 2 + `px`,
                        `padding-top`:_this.nodeName.toLowerCase() == `textarea` ? parseInt($(_this).css(`padding-top`)) + 2 : 0,
                        `line-height`:_this.nodeName.toLowerCase() == `textarea` ? $(_this).css(`line-weight`) : $(_this).outerHeight() + `px`,
                        `font-size`:$(_this).css(`font-size`),
                        `font-family`:$(_this).css(`font-family`),
                        `font-weight`:$(_this).css(`font-weight`)
                    });

                    //通過before把當前$simulationSpan新增到$(_this)前面,並讓$(_this)聚焦
                    $(_this).before($simulationSpan.click(function () {
                        $(_this).trigger(`focus`);
                    }));

                    //當前輸入框聚焦文字內容不為空時,模擬span隱藏
                    $(_this).val().length != 0 && $simulationSpan.hide();

                    if (options.onInput) {
                        //繫結oninput/onpropertychange事件
                        var inputChangeEvent = typeof(_this.oninput) == `object` ? `input` : `propertychange`;
                        $(_this).bind(inputChangeEvent, function () {
                            $simulationSpan[0].style.display = $(_this).val().length != 0 ? `none` : `inline-block`;
                        });
                    }else {
                        $(_this).focus(function () {
                            $simulationSpan.hide();
                        }).blur(function () {
                            /^$/.test($(_this).val()) && $simulationSpan.show();
                        });
                    };
                }
            }
        });
    }
})(jQuery);

呼叫方式,需要通過span標籤來模擬:

$("#username").placeholder({
    isSpan:true
});

相關文章