【问题标题】:Increase size of input field as text is entered输入文本时增加输入字段的大小
【发布时间】:2015-04-22 18:40:05
【问题描述】:

我有一个相当简单的 CSS 问题。我有一个输入文本字段,在页面加载时我希望它的宽度为 150 像素。

但是,当用户输入一些文本时,如果文本的宽度大于 150 像素,那么宽度应该会自动调整。

这是一个笨蛋:

http://plnkr.co/edit/ig0BQrJDiEtXKV8zJ2w2?p=preview

HTML:

<input class="input-class" type="text" placeholder="Placeholder">

CSS:

.input-class-2 {
  -moz-border-bottom-colors: none;
  -moz-border-left-colors: none;
  -moz-border-right-colors: none;
  -moz-border-top-colors: none;
  border-color: -moz-use-text-color -moz-use-text-color #ef8e80;
  border-image: none;
  border-style: none none dashed;
  border-width: 0 0 1px;
  color: #ef8e80;
  cursor: pointer;
  font-family: Gotham-Book;
  font-size: 18px;
  min-width: 150px;
}

我认为 min-width 会这样做。

【问题讨论】:

  • 您可以使用 javascript 查看键盘事件,并在用户输入内容时调整输入大小。
  • 使用自动扩展文本区域/输入的库或插件可能会更好。这是一个有帮助的问题:stackoverflow.com/questions/931207/…
  • 就像@Morb 说的我怀疑你可以在不使用javascript的情况下实现这种效果
  • @Akshay - 是的,jQuery 很好用。

标签: javascript html css


【解决方案1】:

目前没有办法用纯CSS来实现,也许曾经calcattr可以组合使用,但目前还不行。所以我们不得不回退到 JavaScript。

没有任何真正的理由为此使用 jQuery。您可以争辩说您的“关注点应该分开”,即代码应该与标记分开,但使用addEventListener 很容易做到这一点。但是,如果我正在处理一小段 JavaScript,它往往会更快——在实现、页面渲染方面,甚至对于那些试图追踪导致输入行为异常的人来说——使用内联事件侦听器。

<input type="text" 
       style="min-width: 150px;" 
       onkeyup="this.size = Math.max(this.value.length, 1)" 
/>

或:

<input type="text" 
       style="width: 150px;" 
       onkeyup="
         this.style.width = '1px';
         this.style.width = (
             this.scrollWidth &gt; 140
           ? this.scrollWidth + 10
           : 150
         )+'px';
       " 
/>

免责声明:显然,如果您要实现其中的许多输入,最好编写一个通用函数来处理它们。另外,使用样式表避免内联样式总是要好得多。

/**
 * Directly setting the size attribute, with minWidth
 */
function autosize(elm, minWidth){
  var keyup = function(e){
    var t = e.target || e.srcElement;
    var v = Math.max(t.value.length, 1);
    t.setAttribute
      ? t.setAttribute('size', v)
      : (t['size'] = v)
    ;
  };
  elm.style.minWidth = minWidth+'px';
  elm.addEventListener
    ? elm.addEventListener('keyup', keyup)
    : elm.attachEvent('onkeyup', keyup)
  ;
};

size 属性是迄今为止最明显的选择,尽管您可以直接设置宽度(如果您愿意的话)使用scrollWidth

/**
 * Directly setting width, with minWidth
 */
function autosize(elm, minWidth){
  var keyup = function(e){
    var t = e.target || e.srcElement;
    t.style.width = '1px';
    t.style.width = t.scrollWidth + 'px';
  };
  elm.style.minWidth = minWidth+'px';
  elm.addEventListener
    ? elm.addEventListener('keyup', keyup)
    : elm.attachEvent('onkeyup', keyup)
  ;
};

您可以通过将目标元素作为第一个参数传入来触发这些函数中的任何一个。有很多方法可以找到你的元素,最简单和最通用的是getElementById。尽管只有在浏览器解析过元素时才能找到元素,但您使用的脚本标签(用于运行以下代码)要么必须放在标记中的元素下方,即 @ 的底部987654330@(首选),或者在等待窗口加载或 DOM 就绪之后。

autosize( document.getElementById('myinput'), 150 );

/**
 * Directly setting width, with minWidth
 */
function autosize1(elm, minWidth){
  var keyup = function(e){
    var t = e.target || e.srcElement;
    t.style.width = '1px';
    t.style.width = t.scrollWidth + 'px';
  };
  elm.style.minWidth = minWidth+'px';
  elm.addEventListener
    ? elm.addEventListener('keyup', keyup)
    : elm.attachEvent('onkeyup', keyup)
  ;
};

/**
 * Directly setting the size attribute, with minWidth
 */
function autosize2(elm, minWidth){
  var keyup = function(e){
    var t = e.target || e.srcElement;
    var v = Math.max(t.value.length, 1);
    t.setAttribute
      ? t.setAttribute('size', v)
      : (t['size'] = v)
    ;
  };
  elm.style.minWidth = minWidth+'px';
  elm.addEventListener
    ? elm.addEventListener('keyup', keyup)
    : elm.attachEvent('onkeyup', keyup)
  ;
};

autosize1( document.getElementById('a'), 150 );
autosize2( document.getElementById('b'), 150 );
<p>Each input is using a different implementation:</p>
<input type="text" 
       style="min-width: 150px;" 
       onkeyup="this.size = Math.max(this.value.length, 1)" 
/><br />
<input type="text" 
       style="width: 150px;" 
       onkeyup="
         this.style.width = '1px';
         this.style.width = (
             this.scrollWidth &gt; 140
           ? this.scrollWidth + 10
           : 150
         )+'px';
       " 
/><br />
<input type="text" id="a" /><br />
<input type="text" id="b" /><br />

【讨论】:

  • 问题你为什么使用 keyup 和 keydown 输入而不是 oninput?
  • @Persijn ~ 好问题。纯粹为了支持,oninput 从 IE9 开始支持。我仍然不得不为我的一些项目支持 IE8(谢天谢地不再支持 IE6)。你可以很高兴地切换到使用 oninput 或两者兼而有之。
【解决方案2】:

你可以这样试试:

function resizeInput() {
    $(this).attr('size', $(this).val().length);
}

$('input[type="text"]')
    .keyup(resizeInput)
    .each(resizeInput);

JSFIDDLE DEMO

还有另一种使用方法

<span contenteditable="true">Some Text</span>

而不是使用Input 标签。

JSFIDDLE DEMO

【讨论】:

    【解决方案3】:

    你可以试试这样的

    $('.input-class').keyup(function(){
        var textlength=$('.input-class').val().length
        $(this).width(textlength * 8)
    })
    .input-class{
      -moz-border-bottom-colors: none;
      -moz-border-left-colors: none;
      -moz-border-right-colors: none;
      -moz-border-top-colors: none;
      border-color: -moz-use-text-color -moz-use-text-color #ef8e80;
      border-image: none;
      border-style: none none dashed;
      border-width: 0 0 1px;
      color: #ef8e80;
      cursor: pointer;
      font-family: Gotham-Book;
      font-size: 18px;
      min-width: 150px;
        width:auto;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
    <input class="input-class" type="text" placeholder="Placeholder">

    【讨论】:

    • 这个解决方案没问题,除了你硬编码了字体的宽度。这可以随着设备的变化而变化,字体支持也可以,因此自动测量所需宽度的版本会更好。
    • 不过,您的距离并不远,在大多数情况下,像您所做的那样猜测字体的宽度就足够了。您可能可以使用此新措施(如果您感兴趣)改进您的版本(至少对于现代浏览器)developer.mozilla.org/en/docs/Web/CSS/length#ch
    • @Pebbl 谢谢我会看看它
    【解决方案4】:

    尝试使用纯 JavaScript。 我隐藏了一个未向用户显示的 span 元素 (visibility:hidden;)。 然后我计算跨度元素呈现的宽度,并将其设置为输入的容器。
    并将输入设置为width:100%; 使其增长到其父级的大小。

    var field = document.getElementById("grow");
    field.oninput = function() {
      var ruler = document.getElementById("ruler");
      ruler.innerHTML = field.value.replace(/ /g,"&nbsp;");
      var outer = document.getElementById("outer");
      if (ruler.offsetWidth > 100) {
        outer.setAttribute('style', "width:" + (ruler.offsetWidth + 5) + "px;");
      } else {
        outer.setAttribute('style', "");
      }
    };
    #grow {
      height: 100%;
      width: 100%;
      font-size: inherit;
      font-family: inherit;
    }
    #outer {
      width: 100px;
      font-size: 1rem;
      font-family: Serif, "Times New Roman", Georgia;
    }
    .hidden {
      position: absolute;
      display: inline;
      visibility: hidden;
      padding: 0;
      font-size: inherit;
      font-family: inherit;
      white-space: nowrap;
    }
    <div id="outer">
      <span id="ruler" class="hidden"></span>
      <input id="grow" type="text/plain"/>
    </div>
    <p>+ Expands</p>
    <p>+ shrinks</p>
    <p>+ whitespace handling</p>

    【讨论】:

    • 测量的好主意,但是为了使其正常工作,输入和跨度的字体和字体大小必须相同。不能将默认值从一种元素类型应用到另一种元素类型对我来说一直很烦人。所以解决这个问题的唯一方法(因为你不能从不支持子元素的元素继承,即输入)是专门指定字体和字体大小,使用固定或类似的缩放单位。您可能还想让代码允许输入变小,目前如果您删除字符,它不会变小。
    猜你喜欢
    • 1970-01-01
    • 2018-01-16
    • 1970-01-01
    • 2015-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-01
    相关资源
    最近更新 更多