AngularJS指令输入宽度按键控调整大小

AngularJS指令输入宽度按键控调整大小,angularjs,angularjs-directive,Angularjs,Angularjs Directive,我创建了一个指令,以便在键入时自动调整输入的宽度(如Google Contacts)。但是,它似乎不正常,因为每个字符的宽度都不同。你能帮我提供一个更优化的方法吗?Tks 我以前做过这个。我使用的解决方案是让屏幕外的跨距与文本框中的文本相同,字体与文本框完全相同,并询问其宽度 我可能有这样的想法: <span class="textbox-copy"></span> .textbox-copy { position: absolute; left: -9999p

我创建了一个指令,以便在键入时自动调整输入的宽度(如Google Contacts)。但是,它似乎不正常,因为每个字符的宽度都不同。你能帮我提供一个更优化的方法吗?Tks


我以前做过这个。我使用的解决方案是让屏幕外的跨距与文本框中的文本相同,字体与文本框完全相同,并询问其宽度

我可能有这样的想法:

<span class="textbox-copy"></span>

.textbox-copy {
  position: absolute;
  left: -9999px;
  top: -9999px;
  font: -webkit-small-control;
  font: -moz-field;
  font-size: 13px;
}

.文本框副本{
位置:绝对位置;
左:-9999px;
顶部:-9999px;
字体:-webkit小控件;
字体:-moz字段;
字体大小:13px;
}

然后按下键设置该跨度的
innerHTML
,并检查其当前宽度。请注意,至少在Chrome和Firefox中,未设置样式的文本框有自己的特殊字体。它不只是继承Arial或其他任何东西。

您可以创建一个虚拟span来存储输入文本字段中的相同字符串。
在键控时,您可以刷新跨距内容并获得新的长度。
最好为span和input文本创建一个带有文本样式定义的css规则,以便确保它们具有相同的字体样式

您的指令如下所示:

<span class="textbox-copy"></span>

.textbox-copy {
  position: absolute;
  left: -9999px;
  top: -9999px;
  font: -webkit-small-control;
  font: -moz-field;
  font-size: 13px;
}
.html

<div edit-inline>
  <input type="text" value="hello world">
  <span class="dummy">blbla</span>
</div>
.css

app.directive("editInline", function(){
    return function(scope, element, attr){
      var elInput = element.find('input');
      var elDummy = element.find('span');
      var inputText = elInput.val();
      elDummy.html(inputText);
      elInput.bind("keyup", function(){
        var inputText = elInput.val();
        elDummy.html(inputText);
        elInput.css('width', elDummy[0].offsetWidth + 'px');
      });

    }
});  
input, .dummy {
  font-size: 12px;
  font-family: Arial;
  white-space:pre;
}

.dummy {
  visibility:hidden; // this would prevent the dummy text to be shown without losing its size
} 

在这里,您可以看到基于@notme的回答的,我为自己版本的自动调整输入角度指令创建了以下要点:

代码如下:

模板:

<span>
  <input type="text" ng-model="value">
  <span style="visibility:hidden; position:absolute; left:-1000; top:-1000;">{{value}}</span>
</span>
所以问题是你必须测量输入中的文本。你不能只是猜测你是否想要它合适。 所以这个比听起来要复杂,但我想我有一个可以解决这个问题的方法

基本过程:
  • 创建一个临时跨度
  • 对跨距应用相同的字体样式
  • 将值作为文本放入范围中
  • 测量跨度
  • 删除跨度
  • 代码:
    app.directive(“editInline”),函数($window){
    返回函数(范围、元素、属性){
    //更新输入宽度的方法
    //基于它的价值。
    var updateWidth=函数(){
    //创建一个虚拟跨度,我们将使用它来测量文本。
    var测试器=角度元件(“”),
    //获取输入的计算样式
    elemStyle=$window.document.defaultView
    .getComputedStyle(元素[0],“”);
    //将影响字体的任何样式应用于测试仪范围。
    tester.css({
    “字体系列”:elemStyle.fontFamily,
    “线宽”:elemStyle.lineHeight,
    “字体大小”:elemStyle.fontSize,
    “字体重量”:elemStyle.fontwweight
    });
    //更新测试仪量程的文本
    tester.text(element.val());
    //将测试仪暂时放在输入旁边。
    element.parent().append(tester);
    //量!
    var r=tester[0]。getBoundingClientRect();
    var w=r.宽度;
    //应用新宽度!
    css('width',w+'px');
    //拆下检测仪。
    测试仪。移除();
    };
    //初始化输入
    updateWidth();
    //在按下键时执行此操作,以便“实时”更新
    元素绑定(“keydown”,function()){
    //设置立即超时,以便
    //执行此操作时,输入已更新。
    $window.setTimeout(updateWidth,0);
    });
    }
    });
    

    编辑:此外,我已将其更改为在按下键事件后异步更新输入大小。这将使它在您按下键等操作时更新更流畅。

    我知道这是一个老话题,但我想分享我的解决方案,我相信它比所有给定的答案都好。 我刚刚完成了一个角度指令的编写:

    • 没有jQuery依赖项
    • 简单且高性能(无需$watchers/昂贵的DOM操作)
    • 适用于任何CSS定义(填充/框大小)

    我觉得这样不行。例如,你必须再创建一个跨距,它不能在结尾或键入时使用空格;应该解决这个问题。我已经更新了Plunkers。键入时,文本部分被推到左侧。你能纠正这个错误吗?谢谢,@notmeth问题是您正在绑定keyup上的resize,因此如果按住一个键,字符串会变大,但事件不会触发。如果你能容忍右边10px的空白,你就可以解决绑定keyup和keydown的问题。我已经更新了Plunker。我认为没有空位你是做不到的。您需要将字符串完全写入textfield以更新虚拟范围,并且需要更新范围以更新textfield宽度。在某些毫秒内,字符串大于文本字段。如果不能容忍空格,则必须以其他方式重新编写代码。您应该防止在按下键时更新字符串,用按下的键更新虚拟范围中的字符串,更新文本字段宽度,然后将值更新到文本字段中。但我不确定这样做是否值得,只是为了防止添加10px的填充。请注意,css复制缺少
    字体样式
    ,这会影响使用斜体时的宽度。建议:将字体系列/字体大小/字体重量/字体样式替换为单个
    “font”:elemStyle.font
    。(请注意,感谢@blesh提供的解决方案)我的上述建议意见无效。它在Chrome(v34)中有效,但在FF(v29)中无效。因此,我只想添加
    'font-style':elemStyle.fontStyle
    如果您在宽度方面有问题,可以添加一个额外的内容是
    'text-transform':elemStyle.textTransform