使html文本输入字段随着我键入而增长?


80

我可以在CSS中设置初始文本输入大小,如下所示:

width: 50px;

但是我希望它在输入时会不断增长,直到达到200px。可以直接在CSS,HTML中完成此操作,最好在没有JavaScript的情况下进行此操作吗?

当然也发布您的js / jquery解决方案,但是如果没有它们也是可行的-那太好了。

我在这里尝试:

http://jsfiddle.net/jszjz/2/


我认为这个SO问题会为您提供帮助: stackoverflow.com/questions/1288297/…–
Curt

根据记录,不是我。似乎是一个有效的问题,尽管与我所链接的问题相似。
Curt

安德烈:请尽量保持评论的建设性。
赛斯

1
您可以使用具有contenteditable的段落。当您自己输入时,它会扩展。
哥斯达黎加

Answers:


105

这是仅CSS和Content Editable的示例:

jsFiddle示例

的CSS

span 
{
    border: solid 1px black;
}
div 
{
    max-width: 200px;   
}

的HTML

<div>
    <span contenteditable="true">sdfsd</span>
</div>

4
好极了。我刚刚在IE6-9,最新的Opera,Firefox和Chrome和OMG中进行了尝试,它在任何地方都可以使用!
斯坦,

4
对我来说,在Chrome中,当元素达到最大宽度时,它将元素向下延伸。如果输入旨在作为表单的一部分,则也将不起作用。
保罗

5
对于多行输入字段(自定义换行符),请替换spandiv。请注意,word-wrap: break-word这是必要的,或者比max-width溢出div框的单词长的单词:jsfiddle.net/YZPmC/157
CodeManX 2014年

6
确保您清理不想要的html,这些html可能会通过复制和粘贴进入contenteditable范围。
Brian Peacock 2014年

3
这是否以表格发送?
托马什Zato -恢复莫妮卡

38

我只是为您写了这篇文章,希望您喜欢它:)不保证它是跨浏览器的,但我认为是:)

(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, "&amp;")
                                       .replace(/</g, "&lt;")
                                       .replace(/>/g, "&gt;")
                                       .replace(/"/g, "&quot;")
                                       .replace(/'/g, "&#039;")
                                       .replace(/ /g, '&nbsp;');
            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。
斯坦,

33
“我只是为你写的”。+1 :)
Kevin Martin Jose

我如何允许它针对超过1(4)个输入,这与id='adjinput'
教学专家

我非常喜欢我的创造力
Deryck

2
假定仅通过使用键盘即可进行内容更改。
ceving

6

如何以编程方式修改输入的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/


2
如果您突出显示文本并按退格键,这将不起作用,因为它仅算作size-1而不是size- $('input')。val()。length
Abadaba 2014年

3
我猜想计数value.length会更加容易和可靠。
托马什Zato -恢复莫妮卡

1
删除密钥使之不断增长
里卡

5

如果将跨度设置为显示:内联块,则自动调整水平和垂直大小的效果很好:

<span contenteditable="true" 
      style="display: inline-block;
             border: solid 1px black;
             min-width: 50px; 
             max-width: 200px">
</span>


3

我想到了几件事:

onkeydown在文本字段中使用处理程序,测量文本*,并相应地增加文本框的大小。

:focusCSS类附加到具有较大宽度的文本框中。这样,当您聚焦时,您的盒子就会更大。这并不是您所要的,而是类似的。

*在javascript中测量文本并非易事。查看此问题以获取一些想法。


到目前为止最好的答案。:focus { width: 100% }
oldboy

3

来自:是否有用于文本字段的jQuery自动增长插件?


在此处查看演示: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, '&amp;').replace(/\s/g,'&nbsp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
                    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);

2

在这里您可以尝试这样的事情

编辑:修订示例(添加了一个新解决方案) 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几次键入字母,您会看到大小偏斜的结果。请参阅我的答案以解决此问题。
Paul

请参阅我的提琴中的第二个示例,该示例不使用font-size并选择平滑度。添加了第一个只是为了提高速度和速度-同时保持了问询者想要的。每次都必须创建一个div附加文本,计算其宽度等,这对我来说似乎很“繁重”,这很简单。
Pantelis

我不确定为什么,但是您的第二个示例对我来说根本不调整大小。还要记住,我的解决方案(确实创建了一个临时div等)可以在现代浏览器中在一台平均最新的计算机上每秒运行约800次,并且在99.5上可能不会比每秒运行100次慢得多%今天仍在使用的计算机)
保罗,

2

我知道这是一篇很老的文章-但无论如何,我的回答可能对其他人有用。我发现,如果我的contenteditable div的CSS样式定义的最小高度为200而不是200,则div自动缩放。


1

如果你只是兴趣越来越大,你可以更新widthscrollWidth,无论何时的内容input元素的变化。

document.querySelectorAll('input[type="text"]').forEach(function(node) {
  node.onchange = node.oninput = function() {
    node.style.width = node.scrollWidth+'px';
  };
});

但这不会缩小元素。


1

当然,您使用哪种方法取决于您的最终目标。如果要使用表单提交结果,则使用本机表单元素意味着您不必使用脚本来提交。另外,如果关闭脚本,则后备仍然有效,没有花哨的伸缩效果。如果要从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';
  };
});

您可以对<textarea>元素使用类似的东西

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上这不会闪烁,结果在其他浏览器上可能会有所不同,因此请进行测试。


0

这是一种对我有用的方法。当您在字段中键入内容时,它将把该文本放入隐藏的跨度中,然后获取其新的宽度并将其应用于输入字段。它随您的输入而增长和缩小,当您擦除所有输入时,防止输入消失的保护措施就不会出现。在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>


0

如果您被允许使用ch测量(等距),它将完全解决我想做的事情。

onChange(e => {
    e.target.style.width = `${e.target.length}ch`;
})

这正是我需要的,但是我不确定它是否适用于动态宽度字体系列。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.