达到像素宽度后防止文本区域输入

preventing Textarea input after pixel width is reached

我正在构建一个工具,您可以在其中预览 Google 将如何显示您的结果。 当用户输入超过 920 像素的字符时,结果应该将其截断并添加“...”。

我不能使用最大长度来做到这一点,因为每个字母和字体都有不同的宽度。 在 javascript 中,我使输出等于输入,然后我创建了第二个没有换行符的输出。如果我使用第一个输出,则 innerWidth 不会 return 字符串的像素宽度,而是整个块的像素宽度。第二个输出是不可见的,因为它仅用于测量目的。

当 innerWidth 等于或大于 920px 时,我尝试使用 preventDefault 方法。但它一直没有为我工作。 在输出 div 上使用文本溢出 属性 不能在这里使用,因为我不希望容器宽度是动态的,而不是 460px * 2 行或 306px * 3 行等的宽度...

此处使用的正确 if 函数是什么?如何防止进一步输入?

感谢您的帮助。

旁注:请忽略写得不好的部分 CSS 我已经从我无法显示的文档中快速复制了它。

 function snippet()
{
  //copies input to output
var metaIn = document.getElementById('metaIn');
  var metaOut = document.getElementById('metaOut');
  metaOut.value = metaIn.value;

  //copies input to counting space
  var metaOutPix = document.getElementById('metaOutPix');
  metaOutPix.value = metaIn.value;

  //pixel countdown
  document.getElementById('metaOutPix').innerHTML = document.getElementById('metaIn').value
  var span1 = $( "span#metaOutPix" );
  $( "#metaCountPixel" ).text(span1.innerWidth() + "px / 920px");

  //character countdown
  var metaNum = metaIn.value
  var metaCount = metaNum.length;
  document.getElementById("metaCount").innerHTML = metaCount + " Char";

  //stop input by pixel ??
  
}
@import url("https://fonts.googleapis.com/css?family=Raleway");
html, body {
  font-family: Raleway, sans-serif;
  margin: 3px;
  max-width: 80em;
  overflow-x: hidden; }

h1 {
  margin-top: 1em;
  text-align: center; }

.input-wrap {
  width: 100%; }
  .input-wrap h3 {
    font-size: 20px;
    text-transform: lowercase;
    background: #254e61;
    color: #ffffff;
    padding: 0.5em;
    margin: 0;
    line-height: .2em;}
  .input-wrap textarea {
    margin: 0 0 10px 0;
    width: 100%;
    height: 5em;
    resize: none;
    border: solid 2px #254e61;
    padding: 5px;
    font-size: 14px;
    font-family: arial; }
  .input-wrap #metaIn {
    height: 8em; }

#preview {
  width: 100%;
  border: solid 2px #5badff;
  margin-top: 1.5em; }
  #preview h3 {
    font-size: 22px;
    padding: 0.5em;
    background-color: #5badff;
    color: #ffffff;
    margin: 0;
    line-height: .4em; }

.outputs {
  padding: 4px; }

#metaOut {
  border: none;
  width: 100%;
  resize: none;
  overflow: hidden; }

#metaOut, #metaOutPix {
  font-family: arial, sans-serif;
  color: #545454;
  line-height: 20px;
  font-size: 13px;
}
#metaOut{
  max-width: 460px;
  height: 100px;
}

.countspace{
  white-space: nowrap;
  display: none;
}

.countdown {
  color: white;
  margin-top: -22px;
  padding-right: 5px;
  font-size: 18px; }

#metaCount{
  text-align: center;
}
#metaCountPixel{
  text-align: right;
}



@media (min-width: 750px) {
  body, html {
    width: 80%;
    margin: auto; } }
@media (min-width: 1280px) {
  .inputs {
    display: grid;
    margin-top: 30px;
    grid-gap: 8px;
    grid-template-areas: ". tworow" ". tworow"; }

  .input-wrap:nth-child(3) {
    grid-area: tworow; }
    .input-wrap:nth-child(3) #metaIn {
      height: 192px !important; }

  .input-wrap textarea {
    margin: 0 0 0 0; }

 }
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div class="inputs">
    <div class="input-wrap" id="meta-div">
        <h3>Description</h3>
        <div class="countdown" id="metaCount">0 Char</div>
        <div class="countdown" id="metaCountPixel">0px / 920px</div>
        <textarea type="text" name="metaIn" id="metaIn" onkeyup="snippet()" onkeypress="snippet()" maxlength="320" onkeyup="displayTextWidth()"></textarea>
    </div>
</div>

    <div id="preview">
        <h3>Snippet Preview</h3>
        <div class="outputs">
            <textarea type="text" name="metaOut" id="metaOut" placeholder="Lorem ipsum dolor sit amet consectetur adipisicing elit. Dignissimos ipsum voluptatem nemo reiciendis asperiores accusamus suscipit aliquid eveniet quo vero." readonly></textarea>
            <span class="countspace" id="metaOutPix"></span>
        </div>
    </div>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

你是说我下面的代码片段中的类似内容吗?

我在 textarea 中添加了一个 keydown 侦听器,当它达到 920px 或更大时,在这个侦听器中我设置只有 BackspaceDelete 键会允许,任何其他键将被忽略 return false.

(仅供测试,我限制为 50px 而不是 920)

var ellipsisAdded = false
function snippet(){
  var metaIn = document.getElementById('metaIn');
  var metaOut = document.getElementById('metaOut');
  metaOut.value = metaIn.value;

  var metaOutPix = document.getElementById('metaOutPix');
  metaOutPix.value = metaIn.value;

  document.getElementById('metaOutPix').innerHTML = document.getElementById('metaIn').value
  var span1 = $( "span#metaOutPix" );
  $( "#metaCountPixel" ).text(span1.innerWidth() + "px / 50px");

  var metaNum = metaIn.value
  var metaCount = metaNum.length;
  document.getElementById("metaCount").innerHTML = metaCount + " Char";

  if (span1.innerWidth() >= 50){
    let txtArea = $("#metaIn")
    txtArea.on("keydown", (ev) => {
        console.clear()
        if (ev.key != "Backspace" && ev.key != "Delete"){
          console.log("max Pixels reached!");
          if (!ellipsisAdded){
            ellipsisAdded = true
            let currentText = txtArea.val()
            let newTxt = currentText.substring(0, currentText.length - 1) + "..."
            txtArea.val(newTxt)
          }
          return false
        }
      })      
  }else{
    $("#metaIn").off("keydown")
    ellipsisAdded = false;
  }
}
@import url("https://fonts.googleapis.com/css?family=Raleway");
html, body {
  font-family: Raleway, sans-serif;
  margin: 3px;
  max-width: 80em;
  overflow-x: hidden; }

h1 {
  margin-top: 1em;
  text-align: center; }

.input-wrap {
  width: 100%; }
  .input-wrap h3 {
    font-size: 20px;
    text-transform: lowercase;
    background: #254e61;
    color: #ffffff;
    padding: 0.5em;
    margin: 0;
    line-height: .2em;}
  .input-wrap textarea {
    margin: 0 0 10px 0;
    width: 100%;
    height: 5em;
    resize: none;
    border: solid 2px #254e61;
    padding: 5px;
    font-size: 14px;
    font-family: arial; }
  .input-wrap #metaIn {
    height: 8em; }

#preview {
  width: 100%;
  border: solid 2px #5badff;
  margin-top: 1.5em; }
  #preview h3 {
    font-size: 22px;
    padding: 0.5em;
    background-color: #5badff;
    color: #ffffff;
    margin: 0;
    line-height: .4em; }

.outputs {
  padding: 4px; }

#metaOut {
  border: none;
  width: 100%;
  resize: none;
  overflow: hidden; }

#metaOut, #metaOutPix {
  font-family: arial, sans-serif;
  color: #545454;
  line-height: 20px;
  font-size: 13px;
}
#metaOut{
  max-width: 460px;
  height: 100px;
}

.countspace{
  white-space: nowrap;
  display: none;
}

.countdown {
  color: white;
  margin-top: -22px;
  padding-right: 5px;
  font-size: 18px; }

#metaCount{
  text-align: center;
}
#metaCountPixel{
  text-align: right;
}



@media (min-width: 750px) {
  body, html {
    width: 80%;
    margin: auto; } }
@media (min-width: 1280px) {
  .inputs {
    display: grid;
    margin-top: 30px;
    grid-gap: 8px;
    grid-template-areas: ". tworow" ". tworow"; }

  .input-wrap:nth-child(3) {
    grid-area: tworow; }
    .input-wrap:nth-child(3) #metaIn {
      height: 192px !important; }

  .input-wrap textarea {
    margin: 0 0 0 0; }

 }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>   
<div class="inputs">
<div class="input-wrap" id="meta-div">
    <h3>Description</h3>
    <div class="countdown" id="metaCount">0 Char</div>
    <div class="countdown" id="metaCountPixel">0px / 50px</div>
    <textarea type="text" name="metaIn" id="metaIn" onkeyup="snippet()" onkeypress="snippet()" maxlength="320" onkeyup="displayTextWidth()"></textarea>
</div>
</div>

<div id="preview">
    <h3>Snippet Preview</h3>
    <div class="outputs">
        <textarea type="text" name="metaOut" id="metaOut" placeholder="Lorem ipsum dolor sit amet consectetur adipisicing elit. Dignissimos ipsum voluptatem nemo reiciendis asperiores accusamus suscipit aliquid eveniet quo vero." readonly></textarea>
        <span class="countspace" id="metaOutPix"></span>
    </div>
</div>

编辑:添加了您在评论中谈论的功能,将最后一个字符替换为 "..."。 但是注意三个点会占用一些像素,比单个字符多