设置内容可编辑元素的最大长度

问题描述 投票:0回答:8

我有这个代码

<div id="IIYBAGWNBC" contenteditable="true"></div>

这在 jquery 中

$("#IIYBAGWNBC").text(function(index, currentText) {
  return currentText.substr(0, 100);
});

如何防止用户在

contenteditable
div

中输入超过100个字符
jquery html contenteditable
8个回答
16
投票

这非常简单,在

keydown
上,计算元素字符串的长度并阻止用户尝试输入超过 100 个字符

$('div').on('keydown paste', function(event) { //Prevent on paste as well

  //Just for info, you can remove this line
  $('span').text('Total chars:' + $(this).text().length); 

  //You can add delete key event code as well over here for windows users.
  if($(this).text().length === 100 && event.keyCode != 8) { 
    event.preventDefault();
  }
});

演示

说明:

keydown
paste
上的
contenteditable
div
事件上,我们检查
length
div
是否达到
100
,以及用户是否未单击退格键而不是阻止用户输入更多字符单击任意键,甚至右键单击粘贴。


8
投票

我通过使用上面提到的答案来概括代码做了类似的事情,以便您可以设置任何 contenteditable div 的最大长度

$("div[contenteditable='true'][maxlength]").on('keydown paste', function (event) {
     var cntMaxLength = parseInt($(this).attr('maxlength'));

     if ($(this).text().length === cntMaxLength && event.keyCode != 8) {
         event.preventDefault();
     }
});

HTML 如下

<div id="IIYBAGWNBC" contenteditable="true" maxlength="500"></div>

这样您就可以向任何内容可编辑的 Div 元素提及最大长度。 希望这对您有帮助。


3
投票

这段代码完成了这项工作,请注意“keyup”而不是“keydown”以正确处理 ctrl-v 事件,此外,此代码不包括箭头键,最后请注意如果达到限制则剪切文本的代码:

$("div[contenteditable='true'][maxlength]").on('keyup paste', function (event) {
     var cntMaxLength = parseInt($(this).attr('maxlength'));

     if ($(this).text().length >= cntMaxLength && event.keyCode != 8 && 
         event.keyCode != 37 && event.keyCode != 38 && event.keyCode != 39 && 
         event.keyCode != 40) {
         
         event.preventDefault();

         $(this).html(function(i, currentHtml) {
             return currentHtml.substring(0, cntMaxLength-1);
         });
     }
});

然后,在你的html中:

<div contenteditable="true" maxlength="1024"></div>

0
投票

简单地你可以在没有 javascript 的 html 中完成。

<div contenteditable="true" onkeypress="return (this.innerText.length <= 26)">
</div>


0
投票
<div id="your-id" contenteditable="true" maxlength="10" onkeydown="onKeyDown(event)"></div>
function onKeyDown(event) {

  /* Any Shortcut except Ctrl + V */
  const isValidShortcut = (event.ctrlKey && event.keyCode != 86 );

  /* Backspace - Delete - Arrow Keys - Ctrl - Shift */
  const isValidKeyCode = [8, 16, 17, 37, 38, 39, 40, 46].includes(event.keyCode);

  const maxLength = parseInt(event.srcElement.getAttribute("maxlength"));

  const text = event.srcElement.innerText;

  if ( text.length >= maxLength && !isValidKeyCode && !isValidShortcut ) {
    event.preventDefault();
  }
}

0
投票

以下代码使用正则表达式模式限制输入,适用于输入类型='text'、内容可编辑的div和文本区域,防止粘贴和拖/放不匹配的文本。只需添加pattern='^.{0,10}$'属性来限制最大长度(或^[\s\S]{0,10}$来支持新行)。您可以将此代码复制到 test.html 文件中并在浏览器中打开它以进行快速测试。我想知道在哪些用例下它不起作用,请在评论中反馈。

<html>
<script language='javascript'>
function patternify() {
    //Restricts input using regexp pattern
    for (const el of document.querySelectorAll("[pattern]")) {
        el.dataset.beforeinputvalue = el.innerText.replaceAll("\n", "&n;")
        format = function(evt) {
            const pattern = el.getAttribute("pattern")
            const accept = new RegExp(pattern, "g")

            var input_match
            var el_div_value
            if (el.tagName == "DIV") {
                el_div_value = el.innerText
                input_match = el_div_value.match(accept)
            } else {
                input_match = el.value.match(accept)
            }

            if (input_match == null) {

                if (el.tagName == "DIV") {
                    var sel = document.getSelection();
                    //var bo = sel.baseOffset
                    var eo = sel.extentOffset
                    var cp = getCaretPosition(el)[0];
                    el.innerHTML = el.dataset.beforeinputvalue.replaceAll("&n;","<br>")
                    var antienter=0

                    if (window.fix_pattern_key === "Enter") antienter=1
                    setCurrentCursorPosition(el, cp-1+antienter)
                    
                } else {
                    var ss = el.selectionStart
                    var se = el.selectionEnd
                    el.value = el.dataset.beforeinputvalue
                    el.selectionStart = ss - 1
                    el.selectionEnd = se - 1
                }

            } else {
                if (el.tagName == "DIV") {
                    el.dataset.beforeinputvalue = el_div_value.replaceAll("\n","&n;")
                } else {
                    el.dataset.beforeinputvalue = el.value
                }
            }
        };

        //let back = false;
        el.addEventListener("keydown", function(e) { window.fix_pattern_key=e.key });
        el.addEventListener("input", format);
        //el.addEventListener("focus", format);
        //el.addEventListener("blur", () => el.value === pattern && (el.value = ""));
        //format()
    }
}





// node_walk: walk the element tree, stop when func(node) returns false
function node_walk(node, func) {
  var result = func(node);
  for(node = node.firstChild; result !== false && node; node = node.nextSibling)
    result = node_walk(node, func);
  return result;
};

// getCaretPosition: return [start, end] as offsets to elem.textContent that
//   correspond to the selected portion of text
//   (if start == end, caret is at given position and no text is selected)
function getCaretPosition(elem) {
  var sel = window.getSelection();
  var cum_length = [0, 0];

  if(sel.anchorNode == elem)
    cum_length = [sel.anchorOffset, sel.extentOffset];
  else {
    var nodes_to_find = [sel.anchorNode, sel.extentNode];
    if(!elem.contains(sel.anchorNode) || !elem.contains(sel.extentNode))
      return undefined;
    else {
      var found = [0,0];
      var i;
      node_walk(elem, function(node) {
        for(i = 0; i < 2; i++) {
          if(node == nodes_to_find[i]) {
            found[i] = true;
            if(found[i == 0 ? 1 : 0])
              return false; // all done
          }
        }

        if(node.textContent && !node.firstChild) {
          for(i = 0; i < 2; i++) {
            if(!found[i])
              cum_length[i] += node.textContent.length;
          }
        }
      });
      cum_length[0] += sel.anchorOffset;
      cum_length[1] += sel.extentOffset;
    }
  }
  if(cum_length[0] <= cum_length[1])
    return cum_length;
  return [cum_length[1], cum_length[0]];
}

function setCurrentCursorPosition(el, chars) {
    if (chars >= 0) {
        var selection = window.getSelection();

        range = createRange(el, { count: chars });

        if (range) {
            range.collapse(false);
            selection.removeAllRanges();
            selection.addRange(range);
        }
    }
};

function createRange(node, chars, range) {
    if (!range) {
        range = document.createRange()
        range.selectNode(node);
        range.setStart(node, 0);
    }

    if (chars.count === 0) {
        range.setEnd(node, chars.count);
    } else if (node && chars.count > 0) {
        if (node.nodeType === Node.TEXT_NODE) {
            if (node.textContent.length < chars.count) {
                chars.count -= node.textContent.length;
            } else {
                range.setEnd(node, chars.count);
                chars.count = 0;
            }
        } else {
            for (var lp = 0; lp < node.childNodes.length; lp++) {
                range = createRange(node.childNodes[lp], chars, range);

                if (chars.count === 0) {
                    break;
                }
            }
        }
    }

    return range;
};

document.addEventListener('DOMContentLoaded', function () {
    patternify();
}, false);

</script>
<body>

input type='text' (maxlength=5)<br>
<input type='text' pattern='^.{0,5}$'><br>

div contenteditable (maxlength=10)
<div contenteditable='true' pattern='^[\s\S]{0,10}$' style='width:500px;height:200px;border:1px solid black'></div>

textarea (maxlength=15)<br>
<textarea pattern='^[\s\S]{0,15}$' style='width:500px;height:200px;'></textarea>

</body>
</html>

0
投票

此答案可防止将内容粘贴到元素。

通过向元素添加

oncontextmenu="return false;"
来防止鼠标右键单击。

通过检查是否按下 ctrl 的布尔变量来防止 ctrl+V

问题:如果您按了ctrl+V,则无法立即再次按v,只能在按另一个按钮后才能使用。

var ControlPressed = false;

$('#div-contenteditable').on('keydown', function (event) {
  if (event.key === "Control")
    ControlPressed = true;
  else if (ControlPressed && event.keyCode === 86)
    event.preventDefault();
  else
    ControlPressed = false;
    
  const isValidKeyCode = [8, 16, 17, 37, 38, 39, 40, 46].includes(event.keyCode);

  const MaxLength = parseInt($(this).attr('maxlength'));

  if (!isValidKeyCode && $(this).text().length >= MaxLength) {
    event.preventDefault();
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="div-contenteditable" oncontextmenu="return false;" contenteditable="plaintext-only"maxlength="5" style="border: 1px solid"></div>


-1
投票

如果你正在使用react。用这个 反应文本内容可编辑

© www.soinside.com 2019 - 2024. All rights reserved.