使 html 文本输入字段在我键入时增长?
Posted
技术标签:
【中文标题】使 html 文本输入字段在我键入时增长?【英文标题】:make html text input field grow as I type? 【发布时间】:2011-11-02 09:08:36 【问题描述】:我可以在 css 中设置初始文本输入大小,如下所示:
width: 50px;
但我希望它在我输入时增长,直到达到例如 200 像素。 这可以直接用css、html完成吗,最好不用javascript?
当然也要发布您的 js/jquery 解决方案,但如果没有它们也可行 - 那太好了。
我在这里尝试:
http://jsfiddle.net/jszjz/2/
【问题讨论】:
我认为这个 SO 问题会对您有所帮助:***.com/questions/1288297/… 为了记录,不是我。似乎是一个有效的问题,尽管与我链接的问题相似。 Andre:请尽量让 cmets 保持建设性。 您可以使用带有 contenteditable 的段落。当您自己输入时,它会扩展。 【参考方案1】:这是一个只有 CSS 和 Content Editable 的示例:
jsFiddle Example
CSS
span
border: solid 1px black;
div
max-width: 200px;
HTML
<div>
<span contenteditable="true">sdfsd</span>
</div>
关于contenteditable
的重要说明
制作 HTML 元素 contenteditable
允许用户将复制的 HTML 元素粘贴到该元素中。这可能不适合您的用例,因此在选择使用它时请记住这一点。
【讨论】:
耶。我刚刚在 IE6-9、最新的 Opera、Firefox 和 Chrome - 和 OMG - 它在任何地方都可以使用! 对于 Chrome 中的我来说,当元素达到最大宽度时,它会将元素向下延伸一行。如果输入是表单的一部分,它也不会起作用。 对于多行输入字段(自定义换行符),将span
替换为div
。请注意,word-wrap: break-word
是必需的,否则超过 max-width
的字词会溢出 div 框:jsfiddle.net/YZPmC/157
确保清除不需要的 html,这些 html 可能通过复制和粘贴进入 contenteditable 范围。
这是否与表格一起发送?【参考方案2】:
我只是为你写的,希望你喜欢 :) 不能保证它是跨浏览器的,但我认为它是 :)
(function()
var min = 100, max = 300, pad_right = 5, input = document.getElementById('adjinput');
input.style.width = min+'px';
input.onkeypress = input.onkeydown = input.onkeyup = function()
var input = this;
setTimeout(function()
var tmp = document.createElement('div');
tmp.style.padding = '0';
if(getComputedStyle)
tmp.style.cssText = getComputedStyle(input, null).cssText;
if(input.currentStyle)
tmp.style.cssText = input.currentStyle.cssText;
tmp.style.width = '';
tmp.style.position = 'absolute';
tmp.innerHTML = input.value.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'")
.replace(/ /g, ' ');
input.parentNode.appendChild(tmp);
var width = tmp.clientWidth+pad_right+1;
tmp.parentNode.removeChild(tmp);
if(min <= width && width <= max)
input.style.width = width+'px';
, 1);
)();
JSFiddle
【讨论】:
感谢这个。我决定用 contenteditable 属性来做,虽然它不需要 js。 “我刚刚为你写了这个”。 +1 努力:) 我如何允许它使用id='adjinput'
定位超过 1 (4) 个输入
非常有创意我喜欢它
这假定内容更改仅通过使用键盘发生。【参考方案3】:
如果将 span 设置为 display: inline-block,自动水平和垂直调整大小效果很好:
<span contenteditable="true"
style="display: inline-block;
border: solid 1px black;
min-width: 50px;
max-width: 200px">
</span>
【讨论】:
【参考方案4】:以编程方式修改输入的 size 属性怎么样?
在语义上(imo),这个解决方案比公认的解决方案更好,因为它仍然使用输入字段进行用户输入,但它确实引入了一点 jQuery。 Soundcloud 为他们的标记做了类似的事情。
<input size="1" />
$('input').on('keydown', function(evt)
var $this = $(this),
size = parseInt($this.attr('size'), 10),
isValidKey = (evt.which >= 65 && evt.which <= 90) || // a-zA-Z
(evt.which >= 48 && evt.which <= 57) || // 0-9
evt.which === 32;
if ( evt.which === 8 && size > 0 )
// backspace
$this.attr('size', size - 1);
else if ( isValidKey )
// all other keystrokes
$this.attr('size', size + 1);
);
http://jsfiddle.net/Vu9ZT/
【讨论】:
如果您突出显示文本并按退格键,这将不起作用,因为它仅计为 size-1 而不是 size- $('input').val().length 我想计数value.length
会更容易也更可靠。
删除键使这个增长【参考方案5】:
我想到了几件事:
在您的文本字段中使用onkeydown
处理程序,测量文本*,并相应地增加文本框大小。
将:focus
css 类附加到具有较大宽度的文本框。然后你的盒子在聚焦时会更大。这不是您所要求的,但类似。
* 在 javascript 中测量文本并不简单。查看this question 了解一些想法。
【讨论】:
迄今为止的最佳答案。:focus width: 100%
【参考方案6】:
发件人:Is there a jQuery autogrow plugin for text fields?
在此处查看演示:http://jsbin.com/ahaxe
插件:
(function($)
$.fn.autoGrowInput = function(o)
o = $.extend(
maxWidth: 1000,
minWidth: 0,
comfortZone: 70
, o);
this.filter('input:text').each(function()
var minWidth = o.minWidth || $(this).width(),
val = '',
input = $(this),
testSubject = $('<tester/>').css(
position: 'absolute',
top: -9999,
left: -9999,
width: 'auto',
fontSize: input.css('fontSize'),
fontFamily: input.css('fontFamily'),
fontWeight: input.css('fontWeight'),
letterSpacing: input.css('letterSpacing'),
whiteSpace: 'nowrap'
),
check = function()
if (val === (val = input.val())) return;
// Enter new content into testSubject
var escaped = val.replace(/&/g, '&').replace(/\s/g,' ').replace(/</g, '<').replace(/>/g, '>');
testSubject.html(escaped);
// Calculate new width + whether to change
var testerWidth = testSubject.width(),
newWidth = (testerWidth + o.comfortZone) >= minWidth ? testerWidth + o.comfortZone : minWidth,
currentWidth = input.width(),
isValidWidthChange = (newWidth < currentWidth && newWidth >= minWidth)
|| (newWidth > minWidth && newWidth < o.maxWidth);
// Animate width
if (isValidWidthChange)
input.width(newWidth);
;
testSubject.insertAfter(input);
$(this).bind('keyup keydown blur update', check);
);
return this;
;
)(jQuery);
【讨论】:
【参考方案7】:在这里你可以尝试这样的事情
编辑:修订示例(添加了一个新解决方案) http://jsfiddle.net/jszjz/10/
代码说明
var jqThis = $('#adjinput'), //object of the input field in jQuery
fontSize = parseInt( jqThis.css('font-size') ) / 2, //its font-size
//its min Width (the box won't become smaller than this
minWidth= parseInt( jqThis.css('min-width') ),
//its maxWidth (the box won't become bigger than this)
maxWidth= parseInt( jqThis.css('max-width') );
jqThis.bind('keydown', function(e) //on key down
var newVal = (this.value.length * fontSize); //compute the new width
if( newVal > minWidth && newVal <= maxWidth ) //check to see if it is within Min and Max
this.style.width = newVal + 'px'; //update the value.
);
而且css也很简单
#adjinput
max-width:200px !important;
width:40px;
min-width:40px;
font-size:11px;
编辑:另一种解决方案是让用户输入他想要的内容并模糊(聚焦),抓住字符串(以相同的字体大小)将它放在一个 div 中 - 计算 div 的宽度 - 然后用一个漂亮的动画用很酷的缓动效果更新输入字段的宽度。唯一的缺点是在用户键入时输入字段将保持“小”。或者你可以添加一个超时:)你也可以在上面的小提琴上检查这种解决方案!
【讨论】:
font-size
不是一个完美的解决方案。不错,当然不值得投反对票,但是尝试多次输入字母i
,您会看到大小非常不准确的结果。请参阅我的答案以解决此问题。
请参阅我的小提琴中的第二个示例,它不使用字体大小并选择平滑度。第一个是为了速度和速度而添加的——同时保持提问者想要的。对于我来说,每次都必须创建一个 div 附加文本、计算其宽度等,这对我来说似乎“很重”。
我不知道为什么,但你的第二个例子对我来说根本没有调整大小。还要记住,我的解决方案(它确实创建了一个临时 div 等)可以在现代浏览器中平均每秒运行大约 800 次,并且在 99.5 上可能不会比每秒 100 次慢很多目前仍在使用的计算机的百分比)【参考方案8】:
我知道这是一篇很老的帖子 - 但无论如何我的回答可能对其他人有用,所以就这样吧。 我发现如果我对 contenteditable div 的 CSS 样式定义的最小高度为 200 而不是高度为 200 ,那么 div 会自动缩放。
【讨论】:
【参考方案9】:如果您只是对增长感兴趣,您可以将width
更新为scrollWidth
,只要input
元素的内容发生变化。
document.querySelectorAll('input[type="text"]').forEach(function(node)
node.onchange = node.oninput = function()
node.style.width = node.scrollWidth+'px';
;
);
但这不会缩小元素。
【讨论】:
【参考方案10】:当然,您使用哪种方法取决于您的最终目标是什么。如果您想使用表单提交结果,那么使用本机表单元素意味着您不必使用脚本来提交。此外,如果关闭脚本,则回退仍然有效,没有花哨的增长-收缩效果。如果你想从 contenteditable 元素中获取纯文本,你也可以随时使用像 node.textContent 这样的脚本来去除浏览器在用户输入中插入的 html .
此版本使用原生表单元素,对之前的一些帖子进行了细微的改进。
它也允许内容缩小。
将此与 CSS 结合使用以获得更好的控制。
<html>
<textarea></textarea>
<br>
<input type="text">
<style>
textarea
width: 300px;
min-height: 100px;
input
min-width: 300px;
<script>
document.querySelectorAll('input[type="text"]').forEach(function(node)
var minWidth = parseInt(getComputedStyle(node).minWidth) || node.clientWidth;
node.style.overflowX = 'auto'; // 'hidden'
node.onchange = node.oninput = function()
node.style.width = minWidth + 'px';
node.style.width = node.scrollWidth + 'px';
;
);
你可以在
document.querySelectorAll('textarea').forEach(function(node)
var minHeight = parseInt(getComputedStyle(node).minHeight) || node.clientHeight;
node.style.overflowY = 'auto'; // 'hidden'
node.onchange = node.oninput = function()
node.style.height = minHeight + 'px';
node.style.height = node.scrollHeight + 'px';
;
);
这在 Chrome 上不会闪烁,其他浏览器的结果可能会有所不同,所以测试一下。
【讨论】:
【参考方案11】:您可以使用display: inline-grid
:
const dummy = document.querySelector(".dummy");
const input = document.querySelector("input");
const update = () => dummy.innerText = input.value;
input.oninput = update;
update();
.growing-input
display: inline-grid;
.growing-input .dummy,
.growing-input input
grid-area: 1 / 1;
/* Following properties just need to be consistent,
to ensure the .dummy and the input take up the same space */
font: inherit;
padding: 0 0.25em;
margin: 0;
border: 1px solid grey;
border-radius: 2px;
.growing-input .dummy
visibility: hidden;
white-space: pre-wrap;
Here's an
<span class="growing-input">
<input type="text" value="auto-resizing input" size="1" />
<span class="dummy"></span>
</span>; have fun!
这个想法是创建一个包含与input
相同内容的虚拟元素,然后设置input
的宽度以匹配虚拟元素的宽度。上面我们使用 JavaScript 来同步文本,并使用 display: inline-grid
技巧来设置 input
的宽度以匹配。
(此方法取自this article;我已将其浓缩为基本要素。)
【讨论】:
【参考方案12】:这是一种对我有用的方法。当您在字段中键入时,它会将文本放入隐藏范围,然后获取其新宽度并将其应用于输入字段。它会随着您的输入而增长和缩小,当您删除所有输入时,它可以防止输入几乎消失。在 Chrome 中测试。 (编辑:在编辑时适用于 Safari、Firefox 和 Edge)
function travel_keyup(e)
if (e.target.value.length == 0) return;
var oSpan=document.querySelector('#menu-enter-travel span');
oSpan.textContent=e.target.value;
match_span(e.target, oSpan);
function travel_keydown(e)
if (e.key.length == 1)
if (e.target.maxLength == e.target.value.length) return;
var oSpan=document.querySelector('#menu-enter-travel span');
oSpan.textContent=e.target.value + '' + e.key;
match_span(e.target, oSpan);
function match_span(oInput, oSpan)
oInput.style.width=oSpan.getBoundingClientRect().width + 'px';
window.addEventListener('load', function()
var oInput=document.querySelector('#menu-enter-travel input');
oInput.addEventListener('keyup', travel_keyup);
oInput.addEventListener('keydown', travel_keydown);
match_span(oInput, document.querySelector('#menu-enter-travel span'));
);
#menu-enter-travel input
width: 8px;
#menu-enter-travel span
visibility: hidden;
position: absolute;
top: 0px;
left: 0px;
<div id="menu-enter-travel">
<input type="text" pattern="^[0-9]1,4$" maxlength="4">KM
<span>9</span>
</div>
【讨论】:
【参考方案13】:如果您被允许使用 ch 测量(等宽),它完全解决了我想要做的事情。
onChange(e =>
e.target.style.width = `$e.target.lengthch`;
)
这正是我需要的,但我不确定它是否适用于动态宽度字体系列。
【讨论】:
【参考方案14】:对于那些严格寻找适用于输入或文本区域的解决方案的人,this 是我遇到的最简单的解决方案。只有几行CSS和一行JS。
JavaScript 在元素上设置一个 data-* 属性等于 输入值。输入设置在 CSS 网格中,其中 grid 是一个伪元素,它使用 data-* 属性作为它的 内容。该内容是将网格扩展到适当的 大小基于输入值。
【讨论】:
【参考方案15】:您需要做的就是,获取您想要在输入和 CSS 中增长的输入字段的元素,将输入的宽度设置为自动并将最小宽度设置为 50 像素。
【讨论】:
欢迎来到 Stack Overflow。请阅读如何回答。 ***.com/questions/how-to-answer以上是关于使 html 文本输入字段在我键入时增长?的主要内容,如果未能解决你的问题,请参考以下文章