<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" />
<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
属性为输入内容的长度,您可以轻松地完成此操作:
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/
这似乎会在右侧添加一些填充,我怀疑这取决于浏览器。如果您想让它与输入框非常紧密地结合在一起,您可以使用类似我在此相关回答中描述的技术,使用 jQuery 计算文本的像素大小。
我见过几种做法,但计算字体宽度并不总是100%准确,它只是一个估计。
我成功地创建了一种像素完美的方式来通过隐藏的占位符进行测量来调整输入框的宽度。
jQuery
$(function() {
$('#hide').text($('#txt').val());
$('#txt').width($('#hide').width());
}).on('input', function() {
$('#hide').text($('#txt').val());
$('#txt').width($('#hide').width());
});
body,
#txt,
#hide {
font: inherit;
margin: 0;
padding: 0;
}
#txt {
border: none;
color: #888;
min-width: 10px;
}
#txt:focus-visible {
outline: none;
}
#hide {
display: none;
white-space: pre;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Lorem ipsum
<span id="hide"></span><input id="txt" type="text" value="type here ..."> egestas arcu.
</p>
纯JavaScript
我无法确定jQuery如何计算隐藏元素的宽度,因此需要对css进行轻微调整以适应该解决方案。
const hide = document.getElementById('hide');
const txt = document.getElementById('txt');
resize();
txt.addEventListener("input", resize);
function resize() {
hide.textContent = txt.value;
txt.style.width = hide.offsetWidth + "px";
}
body,
#txt,
#hide {
font: inherit;
margin: 0;
padding: 0;
}
#txt {
border: none;
color: #888;
min-width: 10px;
}
#txt:focus-visible {
outline: none;
}
#hide {
position: absolute;
height: 0;
overflow: hidden;
white-space: pre;
}
<p>Lorem ipsum
<span id="hide"></span><input id="txt" type="text" value="type here ..."> egestas arcu.
</p>
height: 0;
部分将无法正常工作。解决此问题的方法是使用position: fixed; top: -100vh;
,你也可以添加opacity: 0;
以确保安全。 - Kamil Bęben<span contenteditable="true">dummy text</span>
contenteditable
用于设置富文本所见即所得的文本编辑器,而不是用于调整输入大小。 - Joseph Nields编辑: 感谢@JavaSpyder指出,该插件现在可以处理末尾空白字符。
由于大多数其他答案不符合我所需(或根本不起作用),我将Adrian B的答案修改为一个适当的jQuery插件,它能够在不要求你更改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});
font
是CSS缩写(奇怪的是,FF [无法处理它](https://dev59.com/VHTYa4cB1Zd3GeqPxKRX#17737539)),因此它不适用于Firefox浏览器。您可以通过在第一个函数中定义以下内容来解决此问题:`var _this_font = [this.css('font-style'), this.css('font-variant'), this.css('font-weight'), 'normal', this.css('font-size') + ' / ' + this.css('line-height'), this.css('font-family')].join(' ');。然后将
this.css('font')更改为
_this_font`。 - Garrett我找到了另一种不涉及JS的解决此问题的方法。 我只需在HTML中放置类似于以下内容:
<div>
<input class="input" value={someValue} />
<div class="ghost-input">someValue</div>
</div>
只需要在ghost-input上设置visibility: hidden,在输入框本身上设置width: 100%即可。这样做是因为输入框会按照其容器的100%缩放,其宽度由浏览器本身计算(基于同样的文本)。
如果您在输入框中添加一些填充和边框,则必须相应地调整您的ghost-input类(或在输入框类中使用calc()函数)。
div
上放置display: inline-block
并且在输入标签内部放置size="1"
,它将缩小默认宽度,至少在Chrome中是如此。这不是完美的,特别是如果您不删除默认填充,但对我来说足够接近了,比这里的任何其他答案都容易得多!
`.my-input {width: 100%;}
.ghost-input {visibility: hidden;}
.outer-div {display: inline-block;}
<input class="my-input" value="small string" size="1" /><div class="ghost-input">small string</div>` - Andrei Cleland<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 设置最小/最大宽度并在宽度上使用过渡即可。
你可以在输入元素的 data-autosize-input 属性中使用 JSON 表示法指定到末尾的空格 / 距离。
当然,你也可以使用 jQuery 进行初始化。
$("selector").autosizeInput();
这里已经有很多好的答案了。为了好玩,我基于其他答案和我的想法实现了以下解决方案。
<input class="adjust">
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, ' '));
// 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);
.adjust {
transition: width .15s;
}
不要试图创建一个div并测量其宽度,我认为更可靠的方法是直接使用canvas元素测量宽度,这样更准确。
function measureTextWidth(txt, font) {
var element = document.createElement('canvas');
var context = element.getContext("2d");
context.font = font;
return context.measureText(txt).width;
}
// 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";
<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
属性效果并不理想。有时会出现过多空间和过少空间的情况,这取决于字体的设置。(请查看示例)
如果想要它正常工作,尝试监听输入内容的更改,然后再进行调整大小。您可能需要将其设置为输入的scrollWidth
。我们还需要考虑盒模型的影响。
在以下示例中,我将输入框的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>
我认为这应该可以在IE6上工作,但不要完全相信我的话。
根据你的使用情况,你可能需要将调整函数绑定到其他事件上。例如:通过编程方式更改输入的值,或更改元素样式的display
属性从none
(其中scrollWidth === 0
)更改为block
或inline-block
等。