input標籤根據輸入字元動態自適應寬度的實現(解決字母數字顯示佔位大小不同問題)
專案中想做個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使用宋體
這樣看起來就沒有任何問題了,唯一缺點是宋體不好看,美觀問題還有待研究