專案中想做個input隨著打字,input的寬隨著字數變化而長度變化

看了有人說用onkeydown,onkeyup配合使用

<input type="text" onkeydown="this.onkeyup();" onkeyup="this.size=(this.value.length>4?this.value.length:4);" size="4">

還有這麼說的


<input class="aa" type="text" value id="a" name="ss">來點>我1
<input class="aa" type="text" value id="s" name="ss" />來點/>我2
<input class="aa" type="text" value id="d" name="ss">來點<></>我3</input>
<script> 
$(function(){
                //propertychange監聽input裡面的字元變化,屬性改變事件
                $('.aa').bind('input propertychange', function() {
                    var $this = $(this);
                    console.log($this);
                    var text_length = $this.val().length;//獲取當前文字框的長度
                    var current_width = parseInt(text_length) *16;//該16是改變前的寬度除以當前字串的長度,算出每個字元的長度
                    console.log(current_width)
                    $this.css("width",current_width+"px");
                });
            })
</script>

還有這麼說的(此方法靠譜,但也有問題)

//獲取文字寬度
    var textWidth = function(text){ 
        var sensor = $('<pre>'+ text +'</pre>').css({display: 'none'}); 
        $('body').append(sensor); 
        var width = sensor.width();
        sensor.remove(); 
        return width;
    };

//input寬度自適應
    $("input").unbind('keydown').bind('keydown', function(){
        $(this).width(textWidth($(this).val()));
    });

以上脫離css單獨用js控制的方法,都有一個嚴重的弊端,那就是忽略了不同字母和數字實際佔位寬度不一致。

也就是說,在使用系統預設字型、設定font-size相同的情況下,一個漢字佔一個font-size的大小,一個字母佔半個font-size的大小,而數字佔font-size的大小不知道是啥規律,既不是一個也不是半個font-size,但是在input中實際顯示佔的位置卻不一樣

比如font-size為12px,我打三個漢字

寬度為36px;

我再打三個字母

因為字母寬度為半個font-size,所以寬度為18px,但是明顯看出兩邊出現空白,字母多了看的更明顯

所以上述方法打中文沒啥問題,一旦出現中英文數字混打就出現問題

解決辦法: 

要設定好css的字型大小和字型family,我目前發現宋體中字母和數字都遵循寬度和實際佔位都是半個font-size,所以暫且使用字型為宋體,但宋體不太好看,其他字型還有待測試

jQuery計算文字寬度的原理是利用html提供的<pre>標籤,向dom中動態新增<pre>標籤,標籤裡的內容就是要測試長度的文字,獲取完長度之後再刪除剛才新增的<pre>標籤,從而可取到文字的大概長度了。為什麼要用標籤而不用其他標籤呢,那來看看<pre>標籤的特性吧:pre 元素可定義預格式化的文字。被包圍在 pre 元素中的文字通常會保留空格和換行符;而文字也會呈現為等寬字型。 <pre>標籤的一個常見應用就是用來表示計算機的原始碼。需要注意的地方是,計算文字長度時文本里面最好不要有其他標籤。以下是實現程式碼:可以直接複製引入jq看效果

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title></title>
    <script src="js/jquery-3.2.1.min.js" type="text/javascript" charset="utf-8"></script>
    <style type="text/css">
        body{
        }
        input{
            background:#ddd;border:0;
            -webkit-border-radius:5px;
            -moz-border-radius:5px;
            border-radius:5px;
            height:22px;padding: 0 10px;
            text-align: center;font-size:14px;width: 2px;
            font-family:simsun
        }
        pre{
            font-family:simsun;font-size:14px;
        }
    </style>
</head>
<body>
<input type="text" >
<script type="text/javascript">
    $("input").unbind("input").bind("input",function(){
        var width=textWidth($(this).val());
        $(this).width(width)
    })

    //獲取文字寬度
    var textWidth = function(text){
        var sensor = $('<pre>'+ text +'</pre>').css({display: 'none'});
        $('body').append(sensor);
        var width = sensor.width();
        sensor.remove();
        return width;
    };
</script>
</body>
</html>

pre和input的font-size和font-family要設定相同,font-family使用宋體

這樣看起來就沒有任何問題了,唯一缺點是宋體不好看,美觀問題還有待研究