防止文本在输入框中移动

时间:2017-08-01 15:36:34

标签: javascript html css css3 browser

这在主要问题列表中排名很低,但我正在尝试制作一个邮政编码条目输入框,其下面有一个带有五个长划线的边框图像,如下所示:

enter image description here

document.getElementById("zip_entry").focus();
#zip_entry_container {
  text-align: center;
  background-color: black;
  color: white;
  padding-bottom: 30px;
  padding-top: 20px;
}

input {
  font-family: monospace;
  display: block;
  margin: 0 auto;
  color: white;
  background-color: black;
  outline: none;
  padding: 0;
  width: 238px;
  border: none;
  font-size: 80px;
  height: 60px;
  text-align: left;
}

img {
  width: 238px;
}
<div id="zip_entry_container">
  <input id="zip_entry" type="text" maxlength=5 pattern="\d*" />
  <img src="https://i.stack.imgur.com/8kNE4.png" />
</div>

死了简单吧? Here's a CodePen demo

我仔细地将输入和CSS下面的图像对齐,这样,使用等宽字体,数字与它们下面的破折号完全对齐直到输入第五个数字,此时,即使我已设置maxlength到5,数字都向左移动几个像素。这是我的意思的video,或者你可以在CodePen链接中看到它。

我可以忍受这个问题,但我发现它真的很烦人。关于如何防止这种默认行为的任何想法?我已经尝试弄乱keydown并阻止事件冒泡,但它并没有阻止浏览器移动文本 - 当你失去焦点时它会移回到正确的位置。

如果光标在短划线的中心对齐,我也会喜欢它,但我能想到的唯一方法是连续制作五个输入,并尝试这种方法会导致各种各样的头痛。一堆事件监听器将焦点切换到keyup上的下一个兄弟,切换到退格上的前一个兄弟,否则重写输入框的所有功能。

更新:我想我可以通过在输入第五个数字时立即调用.blur()来解决这个问题,但这种转变仍会在一瞬间发生。尔加!

3 个答案:

答案 0 :(得分:1)

一个主要问题(特别是在浏览器兼容性方面)是font-family: monospace导致根据操作系统和浏览器应用不同的字体(请参阅MDN)。在提供的Codepen中,Windows上的Chrome将使用Consolas,而Firefox似乎使用Courier New。如果使用不同的字体,字母将具有不同的宽度,因此会导致字母不对齐。

如果文本输入对于其内容而言太大,则文本将向左移动(如已经提到并由@Vadim Ovchinnikov解释)。为避免这种情况,必须有足够的空间用于光标。使用5ch作为宽度单位看起来对我来说是一个很好的解决方案。

把它们放在一起:

https://codepen.io/MattDiMu/pen/JyKodN

答案 1 :(得分:0)

问题似乎是光标。 如果你在输入的宽度(240px而不是238px)上添加一些额外的像素,它就不会移动:

input {
  font-family: monospace;
  display: block;
  margin: 0 auto;
  color: white;
  background-color: black;
  outline: none;
  padding: 0;
  width: 240px;
  border: none;
  font-size: 80px;
  height: 60px;
  text-align: left;
}

https://codepen.io/anon/pen/WExNgL

答案 2 :(得分:0)

你可以摆脱图像和JavaScript并在这里使用渐变。演示:

&#13;
&#13;
#zip_entry_container {
  background-color: black;
  color: white;
  padding-bottom: 30px;
  padding-top: 20px;
  display: flex;
  justify-content: center;
}

input {
  box-sizing: content-box;
  font-family: Consolas, monospace;
  color: white;
  outline: none;
  padding: 0;
  border: none;
  /* 5 * (1ch + letter-spacing) */ 
  width: 6ch;
  font-size: 80px;
  height: 65px;
  text-align: left;
  background: #000 repeating-linear-gradient(90deg, 
        white 0,
        white 1ch, 
        transparent 0, 
        transparent 1.2ch) 
      0 100%/100% 2px no-repeat;
  /* show background only for content */
  background-clip: content-box;
  /* just add 1px to avoid cursor overflow */
  padding-right: 1px;
  letter-spacing: .2ch;
}
&#13;
<div id="zip_entry_container">
  <input id="zip_entry" type="text" maxlength="5" pattern="\d*" autofocus />
</div>
&#13;
&#13;
&#13;