javascript CR 和 CF 的文本区域最大长度问题

javascript textarea maxlength issue with CR and CF

我对 javascript 最大长度计算有疑问。

Javascript

function charCount(characters) {
    document.getElementById('citation').onkeyup = function () {
      var s = this.value;
      document.getElementById('sBann').innerHTML = (characters - s.length) + " characters left.";
    };
}

JSP:

<div class="FormRow">
<textarea class="textAreaLarge" rows="20" cols="180" name="citation" id="citation" maxlength="<%=maxCitationLength%>" onKeyUp="charCount(<%=maxCitationLength%>);"><%=citation%></textarea>
<div id="overDiv" style="position:absolute; visibility:hidden; z-index:1000;"></div>
<strong><div id="sBann" class="minitext"><% if (citation != null) { %><%= (maxCitationLength-citation.length()) %><%} else {%><%= (maxCitationLength) %><%}%> characters left.</div></strong>
</div>

我的文本区域的最大长度为 1650,这也应该包括空格。 我有一个创建页面。 当我在 UI 中输入内容时,它会将行尾视为 1 个字符,并允许最多 1650 个字符,并阻止用户输入更多字符,这很好。 但是在服务器端,CR 和 CF 的行尾被视为 2 个字符,尽管 JS 计算为 1650,但数据被插入 CR 和 CF,并且 DB 中的长度 > 1650,例如 1680。 在数据库方面,这个字段是一个 clob,所以即使它存储 > 1650,我也没有问题。

现在我有一个编辑屏幕,我必须在其中显示相同的文本区域并允许用户进行编辑。 对于上面我输入 1650 但 DB 显示 1680 的相同示例,UI 中的文本区域显示 1680 个字符,因此显示剩余字符数的负载跨度为 -20,因为 CR/CF 值包含在服务器端。

我如何处理客户端验证以包含 CR/CF 的 2 个字符?

考虑以下因素。

$(function() {
  function charactersLeft(el) {
    var max = parseInt($(el).attr("maxLength"));
    var cur = $(el).val().length;
    return max - cur;
  }

  function allowType(el) {
    var result = true;
    if (charactersLeft(el) <= 0) {
      result = false;
    }
    return result;
  }

  function myTrim(el, str) {
    var value = $(el).val();
    value.replace(str, "");
    $(el).val(value);
  }

  $(".minitext > span").html(charactersLeft(".textAreaLarge"));

  $("#citation").on("keyup", function(e) {
    myTrim(this, "\r");
    $(".minitext > span").html(charactersLeft(".textAreaLarge"));
    if (!allowType(this)) {
      return false;
    }
  });

})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="FormRow">
  <textarea class="textAreaLarge" rows="20" cols="180" name="citation" id="citation" maxLength="1650"></textarea>
  <div id="overDiv" style="position:absolute; visibility:hidden; z-index:1000;"></div>
  <strong><div id="sBann" class="minitext"><span></span> characters left.</div></strong>
</div>

使用keyup,我们可以return false 来阻止击键事件。

它的回车 return CR 和换行 LF。在 Windows 上,如果你 console.log() textarea 值它不会 return CR or \r 它只有 \n,我不确定 mac os.

您有重复的活动

onKeyUp="charCount(<%=maxCitationLength%>);"
// and
document.getElementById('citation').onkeyup = function () {

只调用一次,在元素属性或脚本标签中。

并且将 CR/LF 计为两个字符使用正则表达式

document.getElementById('citation').oninput = function(e) {
  var maxChars = 20;
  var sBann = document.getElementById('sBann');
  var s = this.value;

  // count linebreak
  var lineBreaks = s.match(/(?!\n$)\n/g) || '';
  var charCount = s.length + lineBreaks.length;
  if (charCount > maxChars) {
    this.value = s.slice(0, maxChars - lineBreaks.length);
    sBann.innerHTML = "0 characters left.";
    return false;
  }

  sBann.innerHTML = (maxChars - charCount) + " characters left.";

  console.log('s: ' + (s.length - lineBreaks.length), '|', 'line break (x2): ' + lineBreaks.length * 2);
  console.log('total: ' + charCount)
};
<div class="FormRow">
  <textarea class="textAreaLarge" rows="10" cols="40" name="citation" id="citation" maxlength="20"></textarea>
  <div id="overDiv" style="position:absolute; visibility:hidden; z-index:1000;"></div>
  <strong><div id="sBann" class="minitext">20 characters left.</div></strong>
</div>