Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/413.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何检测可以精确匹配预定义文本框长度的字符数?_Javascript_Html - Fatal编程技术网

Javascript 如何检测可以精确匹配预定义文本框长度的字符数?

Javascript 如何检测可以精确匹配预定义文本框长度的字符数?,javascript,html,Javascript,Html,假设我添加了一个长度为50px的文本框,我想计算完全适合该文本框的确切字符数(包括空格),我的意思是不允许在文本框内键入需要将整行向左滑动的字符;我的意思是,换句话说,我们需要禁止打字员在行至文本框长度时进一步插入任何字母。我们能用JavaScrip解决这个问题吗?提前感谢您的帮助,我们将不胜感激。整个逻辑都有缺陷,因为它还取决于输入中文本的大小。我会设置一个不超过的字符数限制。使用maxlengthinput属性 不管怎样,如果你真的想走这条路,我认为这是一种过度使用,不需要,那么你可以:

假设我添加了一个长度为50px的文本框,我想计算完全适合该文本框的确切字符数(包括空格),我的意思是不允许在文本框内键入需要将整行向左滑动的字符;我的意思是,换句话说,我们需要禁止打字员在行至文本框长度时进一步插入任何字母。我们能用JavaScrip解决这个问题吗?提前感谢您的帮助,我们将不胜感激。

整个逻辑都有缺陷,因为它还取决于输入中文本的大小。我会设置一个不超过的字符数限制。使用
maxlength
input属性

不管怎样,如果你真的想走这条路,我认为这是一种过度使用,不需要,那么你可以:

  • 使用CanvasRenderingContext2D.measureText
  • 为了做到这一点,你必须创建一个隐藏的位置来模拟你的输入文本
  • 之后,如果文本超出输入宽度,则需要检查输入,并避免任何进一步的击键,但仍允许删除
请参阅附件中我所说内容的示例片段(未优化)

const form=document.querySelector(“#form”),
input=form.querySelector('input')
const createAppendCanvas=form=>{
const canvas=document.createElement('canvas')
form.appendChild(画布)
}
createAppendCanvas(表单)
常量getTextMetrics=inputText=>{
const canvas=document.querySelector('canvas'),
textWidth=Math.ceil(canvas.getContext('2d').measureText(inputText.width)+10
返回文本宽度
}
const disableTyping=(事件,输入)=>{
常量inputText=event.target.value,
inputWidth=input.clientWidth
if(getTextMetrics(inputText)>=inputWidth){
event.preventDefault()
返回错误
}
}
input.addEventListener('keypress',event=>disableTyping(event,input))
输入{
宽度:50px;
}
帆布{
显示:无;
}

正如@mel macaluso正确指出的,这是一个非常大的兔子洞,标准做法是使用属性限制字符数

*编辑:您还可以使用设置
输入的宽度,该宽度与字体大小成比例。(em这个名字最初是指所用字体中大写字母M的宽度和大小,通常与点大小相同)em
中的宽度和maxlength中的宽度组合将给出您可能尝试实现的大致近似值

但是,如果您真的希望能够限制基于输入的文本长度,那么这将是一个非常简单的示例,说明如何开始

编辑:我推荐@mel macaluso的答案:他添加了一个使用的示例,我怀疑这比
getBoundingClientRect
更有效。 首先是一些免责声明:

  • 此示例不考虑剪贴板操作。这是一个相当大的问题,您可能会谈论更多的代码来解释它(远远超出了这里可以合理完成的范围)

  • 它也是相当资源密集型的。执行
    getBoundingClientRect
    的过程会强制浏览器额外回流文档内容。取决于页面的大小,这可能是一件大事,而且这不是一件容易做到的事情

var inp=document.getElementById('test');
//获取输入字体
var style=getComputedStyle(inp);
var maxWidth=inp.getBoundingClientRect().width;
var sizeTest=document.createElement('span');
//为span设置字体以匹配输入
sizeTest.style.font=style.font;
inp.addEventListener('keydown',函数(e){
如果(e.ctrlKey | | e.altKey)返回;
if(e.key&&e.key.length==1){
sizeTest.textContent=inp.value;
document.body.append(sizeTest);
var w=sizeTest.getBoundingClientRect().width;
sizeTest.remove();
console.log(最大宽度,w,e.key,e.code);
如果(w>maxWidth)e.preventDefault();
}
})

这里有一个简洁的解决方案,使用嵌套的span(带有
contenteditable
内部span)作为代理输入

//标识符和动态样式
const innerSpan=document.querySelector(“span.inner”),
outerSpan=document.querySelector(“span.outer”);
/*阈值应至少比outerSpan小一个字符宽度。
(这个公式在我的几次测试中非常接近;
为了获得更高的精度和更少的灵活性,您可以硬编码一个值。)*/
const estMaxCharWidth=innerSpan.offsetHeight/1.7,
thresholdWidth=outerSpan.offsetWidth-estMaxCharWidth;
innerSpan.style.minWidth=`${Math.floor(thresholdWidth)-3}px`;//默认为0
innerSpan.style.minHeight=`${Math.floor(outerSpan.offsetHeight)-2}px`
//听众
addEventListener(“焦点”,自定义大纲);
innerSpan.addEventListener(“向下键”,checkKeyAndWidth);
innerSpan.addEventListener(“模糊”,removeOutlineAndHandleText);
//功能
功能检查键和宽度(e){
//当用户按键时运行,有条件地阻止输入
如果(e.code==“输入”| | e.keyCode==13){
e、 preventDefault();//不插入新行
e、 target.blur();/(在制作中,将焦点设置为另一个元素)
}
否则{
//除Enter键外,还有一些键很重要,可以添加更多
const whitelistCodes=[“退格”、“制表符”、“转义”、“箭头左”、“箭头右”、“插入”、“删除”];
常量whitelistKeyCodes=[8,9,27,37,39,45,46];
//如果内部跨距足够宽,请停止接受字符

让acceptingCharacters=e.target.offsetWidth@David784嗨,伙计,现在看看,你觉得怎么样?不过,我不会鼓励人们进行不好的练习