自动缩放input为值的宽度?

有没有办法将一个<input type="text">的宽度缩放为实际值的宽度?

 input { display: block; margin: 20px; width: auto; } 
 <input type="text" value="I've had enough of these damn snakes, on this damn plane!" /> <input type="text" value="me too" /> 

您可以通过将size属性设置为input内容的长度来轻松完成此操作:

 function resizeInput() { $(this).attr('size', $(this).val().length); } $('input[type="text"]') // event handler .keyup(resizeInput) // resize on page load .each(resizeInput); 

见: http : //jsfiddle.net/nrabinowitz/NvynC/

这似乎增加了一些填充,我怀疑是依赖于浏览器的权利。 如果你希望它对input非常紧张,你可以使用像我在这个相关的答案中描述的技术,使用jQuery来计算文本的像素大小。

如果由于某种原因,其他解决scheme不适合您,则可以使用contenteditable-span而不是input元素。

 <span contenteditable="true">dummy text</span> 

请注意,这更像是一种黑客行为,其严重缺点是允许用户input(和粘贴)换行符,链接和其他HTML等完全未经过处理的HTMLinput。

所以你可能不应该使用这个解决scheme,除非你非常仔细的消毒input…

更新 :你可能想在下面使用Obsidian的解决scheme 。

编辑 :插件现在与尾随空白字符。 感谢您指出@JavaSpyder

由于大多数其他答案不符合我所需要的(或根本不工作),我修改了阿德里安B的答案到一个适当的jQuery插件,导致像素完美缩放input,而不需要你改变你的CSS或HTML。

例如: https : //jsfiddle.net/587aapc2/

用法: $("input").autoresize({padding: 20, minWidth: 20, maxWidth: 300});

插入:

 //JQuery plugin: $.fn.textWidth = function(_text, _font){//get width of text with font. usage: $("div").textWidth(); var fakeEl = $('<span>').hide().appendTo(document.body).text(_text || this.val() || this.text()).css({font: _font || this.css('font'), whiteSpace: "pre"}), width = fakeEl.width(); fakeEl.remove(); return width; }; $.fn.autoresize = function(options){//resizes elements based on content size. usage: $('input').autoresize({padding:10,minWidth:0,maxWidth:100}); options = $.extend({padding:10,minWidth:0,maxWidth:10000}, options||{}); $(this).on('input', function() { $(this).css('width', Math.min(options.maxWidth,Math.max(options.minWidth,$(this).textWidth() + options.padding))); }).trigger('input'); return this; } //have <input> resize automatically $("input").autoresize({padding:20,minWidth:40,maxWidth:300}); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <input value="i magically resize"> <br/><br/> called with: $("input").autoresize({padding: 20, minWidth: 40, maxWidth: 300}); 

一个简单但像素完美的解决scheme

我已经看到了几种方法来做到这一点,但计算字体的宽度并不总是100%准确,只是一个估计。

我设法创build一个像素完美的方式来调整input宽度,通过一个隐藏的占位符来衡量。

 $(function(){ $('#hide').text($('#txt').val()); $('#txt').width($('span').width()); }).on('input', function () { $('#hide').text($('#txt').val()); $('#txt').width($('span').width()); }); 
 body, #txt, #hide{ font:inherit; margin:0; padding:0; } #txt{ border:none; color:#888; min-width:10px; } #hide{ display:none; white-space:pre; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <p>Lorem ipsum <span id="hide"></span><input id="txt" type="text" value="type here ..."> egestas arcu. </p> 

我有一个GitHub上的jQuery插件: https : //github.com/MartinF/jQuery.Autosize.Input

它镜像input的值,计算宽度并使用它来设置input的宽度。

你可以在这里看到一个生动的例子: http : //jsfiddle.net/mJMpw/2175/

如何使用它的例子(因为发布jsfiddle链接时需要一些代码):

 <input type="text" value="" placeholder="Autosize" data-autosize-input='{ "space": 40 }' /> input[type="data-autosize-input"] { width: 90px; min-width: 90px; max-width: 300px; transition: width 0.25s; } 

你只要使用CSS设置最小/最大宽度,并使用宽度过渡,如果你想要一个很好的效果。

您可以将input元素的data-autosize-input属性的空格/距离指定为json符号中的值。

当然,你也可以使用jQuery来初始化它

 $("selector").autosizeInput(); 

这里已经有很多很好的答案了。 为了好玩,我根据其他答案和我自己的想法,在下面实施了这个解决scheme。

 <input class="adjust"> 

input元素被调整为像素精确,并且可以定义额外的偏移量。

 function adjust(elements, offset, min, max) { // Initialize parameters offset = offset || 0; min = min || 0; max = max || Infinity; elements.each(function() { var element = $(this); // Add element to measure pixel length of text var id = btoa(Math.floor(Math.random() * Math.pow(2, 64))); var tag = $('<span id="' + id + '">' + element.val() + '</span>').css({ 'display': 'none', 'font-family': element.css('font-family'), 'font-size': element.css('font-size'), }).appendTo('body'); // Adjust element width on keydown function update() { // Give browser time to add current letter setTimeout(function() { // Prevent whitespace from being collapsed tag.html(element.val().replace(/ /g, '&nbsp')); // Clamp length and prevent text from scrolling var size = Math.max(min, Math.min(max, tag.width() + offset)); if (size < max) element.scrollLeft(0); // Apply width to element element.width(size); }, 0); }; update(); element.keydown(update); }); } // Apply to our element adjust($('.adjust'), 10, 100, 500); 

调整得到平滑与CSS过渡。

 .adjust { transition: width .15s; } 

这是小提琴 。 我希望这可以帮助其他人寻找一个干净的解决scheme。

你可以在这里解决这个问题:) http://jsfiddle.net/MqM76/217/

HTML:

 <input id="inpt" type="text" /> <div id="inpt-width"></div> 

JS:

 $.fn.textWidth = function(text, font) { if (!$.fn.textWidth.fakeEl) $.fn.textWidth.fakeEl = $('<span>').hide().appendTo(document.body); $.fn.textWidth.fakeEl.text(text || this.val() || this.text()).css('font', font || this.css('font')); return $.fn.textWidth.fakeEl.width(); }; $('#inpt').on('input', function() { var padding = 10; //Works as a minimum width var valWidth = ($(this).textWidth() + padding) + 'px'; $('#'+this.id+'-width').html(valWidth); $('#inpt').css('width', valWidth); }).trigger('input'); 

不幸的是size属性不能很好地工作。 有时会有额外的空间和太小的空间,这取决于字体的设置。 (查看例子)

如果你想这样做,请尝试观察input的变化,然后调整它的大小。 您可能想要将其设置为input的scrollWidth 。 我们也需要考虑箱子尺寸。

在下面的示例中,我将input的size设置为1,以防止它的scrollWidth大于我们的初始宽度(使用CSS手动设置)。

 // (no-jquery document.ready) function onReady(f) { "complete" === document.readyState ? f() : setTimeout(onReady, 10, f); } onReady(function() { [].forEach.call( document.querySelectorAll("input[type='text'].autoresize"), registerInput ); }); function registerInput(el) { el.size = 1; var style = el.currentStyle || window.getComputedStyle(el), borderBox = style.boxSizing === "border-box", boxSizing = borderBox ? parseInt(style.borderRightWidth, 10) + parseInt(style.borderLeftWidth, 10) : 0; if ("onpropertychange" in el) { // IE el.onpropertychange = adjust; } else if ("oninput" in el) { el.oninput = adjust; } adjust(); function adjust() { // reset to smaller size (for if text deleted) el.style.width = ""; // getting the scrollWidth should trigger a reflow // and give you what the width would be in px if // original style, less any box-sizing var newWidth = el.scrollWidth + boxSizing; // so let's set this to the new width! el.style.width = newWidth + "px"; } } 
 * { font-family: sans-serif; } input.autoresize { width: 125px; min-width: 125px; max-width: 400px; } input[type='text'] { box-sizing: border-box; padding: 4px 8px; border-radius: 4px; border: 1px solid #ccc; margin-bottom: 10px; } 
 <label> Resizes: <input class="autoresize" placeholder="this will resize" type='text'> </label> <br/> <label> Doesn't resize: <input placeholder="this will not" type='text'> </label> <br/> <label> Has extra space to right: <input value="123456789" size="9" type="text"/> </label> 

我认为直接使用更精确的canvas元素来测量宽度是比较可靠的,而不是尝试创builddiv并测量它的宽度。

 function measureTextWidth(txt, font) { var element = document.createElement('canvas'); var context = element.getContext("2d"); context.font = font; return context.measureText(txt).width; } 

现在,您可以使用它来测量某个input元素在任何时间点的宽度:

 // assuming inputElement is a reference to an input element (DOM, not jQuery) var style = window.getComputedStyle(inputElement, null); var text = inputElement.value || inputElement.placeholder; var width = measureTextWidth(text, style.font); 

这将返回一个数字(可能是浮点数)。 如果你想考虑填充,你可以试试这个:

  var desiredWidth = (parseInt(style.borderLeftWidth) + parseInt(style.paddingLeft) + Math.ceil(width) + 1 + // extra space for cursor parseInt(style.paddingRight) + parseInt(style.borderRightWidth)) inputElement.style.width = desiredWidth + "px"; 

我的jQuery插件适用于我:

用法:

  $('form input[type="text"]').autoFit({ }); 

jquery.auto-fit.js源代码:

 ; (function ($) { var methods = { init: function (options) { var settings = $.extend(true, {}, $.fn.autoFit.defaults, options); var $this = $(this); $this.keydown(methods.fit); methods.fit.call(this, null); return $this; }, fit: function (event) { var $this = $(this); var val = $this.val().replace(' ', '-'); var fontSize = $this.css('font-size'); var padding = $this.outerWidth() - $this.width(); var contentWidth = $('<span style="font-size: ' + fontSize + '; padding: 0 ' + padding / 2 + 'px; display: inline-block; position: absolute; visibility: hidden;">' + val + '</span>').insertAfter($this).outerWidth(); $this.width((contentWidth + padding) + 'px'); return $this; } }; $.fn.autoFit = function (options) { if (typeof options == 'string' && methods[options] && typeof methods[options] === 'function') { return methods[options].apply(this, Array.prototype.slice.call(arguments, 1)); } else if (typeof options === 'object' || !options) { // Default to 'init' return this.each(function (i, element) { methods.init.apply(this, [options]); }); } else { $.error('Method ' + options + ' does not exist on jquery.auto-fit.'); return null; } }; $.fn.autoFit.defaults = {}; })(this['jQuery']); 

input元素的行为与其他元素的行为不同,如果你给他们float: left (参见http://jsfiddle.net/hEvYj/5/ ),那么这些元素就会做你想要的。 我不认为这是可能的,但没有以某种方式与JavaScript计算(即在框中每个字母的宽度添加5px)。

用户nrabinowitz的解决scheme是伟大的,但我使用keypress事件,而不是keyup 。 这样可以减less用户input缓慢的延迟。

这是我对nrabinowitz解决scheme的修改。 我没有使用size属性,因为@Mark标注的比例字体并不完美。 我的解决scheme放置一个元素后,您的input,并获取宽度浏览器(使用jQuery)。

虽然我不testing它,但我认为只有在所有影响字体的CSS属性都被inheritance的情况下,它才能起作用。

input宽度在聚焦事件中发生变化,这对我更好。 但是你也可以使用keyup / keypress来改变input的宽度。

 function resizeInput() { //Firstly take the content or placeholder if content is missing. var content = $(this).val().length > 0 ? $(this).val() : $(this).prop("placeholder"); //Create testing element with same content as input. var widthTester = $("<span>"+content+"</span>").hide(); //Place testing element into DOM after input (so it inherits same formatting as input does). widthTester.insertAfter($(this)); //Set inputs width; you may want to use outerWidth() or innerWidth() //depending whether you want to count padding and border or not. $(this).css("width",widthTester.width()+"px"); //Remove the element from the DOM widthTester.remove(); } $('.resizing-input').focusout(resizeInput).each(resizeInput); 

使用canvas我们可以计算元素宽度:

 function getTextWidth(text, fontSize, fontName) { let canvas = document.createElement('canvas'); let context = canvas.getContext('2d'); context.font = fontSize + fontName; return context.measureText(text).width; } 

并在选定的事件中使用它:

 function onChange(e) { let width = getTextWidth(this.value, $(this).css('font-size'), $(this).css('font-family')); $(this.input).css('width', width); }