Javascript 将文本区域符号限制为可见部分

Javascript 将文本区域符号限制为可见部分,javascript,html,Javascript,Html,有没有办法将文本区域输入的符号仅限于可见部分 我不想滚动,我已经为它指定了行数列,我希望用户不能输入太多的字符,可能会出现滚动 当然我可以设置溢出:隐藏,但无论如何都会输入符号。限制字符数不是我的情况,因为不同的字符具有不同的宽度:例如W和1。我需要这种逻辑,因为在textarea中输入的数据用于某些打印报告,并且不可能在纸上滚动 我只找到了两种可能的解决方案: 使用一些平均数量的 人物。并受此限制 数字这很粗糙。因为 对于平均数为 大人物比平常大吗 仍将隐藏一些数据 使用输入的数据进行渲染 字

有没有办法将文本区域输入的符号仅限于可见部分

我不想滚动,我已经为它指定了行数列,我希望用户不能输入太多的字符,可能会出现滚动

当然我可以设置溢出:隐藏,但无论如何都会输入符号。限制字符数不是我的情况,因为不同的字符具有不同的宽度:例如W和1。我需要这种逻辑,因为在textarea中输入的数据用于某些打印报告,并且不可能在纸上滚动

我只找到了两种可能的解决方案:

  • 使用一些平均数量的 人物。并受此限制 数字这很粗糙。因为 对于平均数为 大人物比平常大吗 仍将隐藏一些数据

  • 使用输入的数据进行渲染 字符到某个单独的div和 计算其宽度/高度。似乎 我会很慢,不会 确保这是正确的实现


  • 您可以使用JavaScript检查
    滚动高度
    ,如果大于“原始”高度,则截断文本,直到文本不再滚动。这方面的代码是:

    function CheckScroll(oTextarea) {
        if (oTextarea.scrollHeight > oTextarea.offsetHeight) {
            while (oTextarea.scrollHeight > oTextarea.offsetHeight) {
                oTextarea.value = oTextarea.value.substr(0, oTextarea.value.length - 1);
             }
        }
    }
    
    为了触发它:

    <textarea cols="15" rows="3" onkeyup="CheckScroll(this);" onchange="CheckScroll(this);" onpaste="CheckScroll(this);"></textarea>
    
    
    

    实时测试用例:

    您可以使用Courier或其他非比例字体来设置样式。这样,您就可以确切地知道可以容纳多少个字符,因为所有字符的大小都相同,这使得使用几种限制字符串中字符数的著名技术中的任意一种来限制字符串的大小变得非常容易


    缺点是它看起来不好看(除非你碰巧喜欢Courier的样子),但它是一个可行的解决方案,我想不出其他任何东西。

    我想出了一个类似于Shadow Wizard的方法,它使用
    oninput
    检测所有形式的输入(如粘贴、拖放),而不仅仅是键盘输入。它需要使用以下CSS关闭文本区域的滚动条:

    textarea { overflow: hidden; }
    
    您可能需要设置
    resize:none适用于Firefox4和Chrome等浏览器。此外,如果没有空格,Opera的包装不会中断,但它不支持
    wrap:wordbreak正确,因此我不确定您将如何解决此问题。JavaScript涉及每次更改时记住textarea的内容,如果文本超过元素的大小,更改将恢复为以前的值:

    var prev = "",
        tArea = document.getElementById("limit");
    
    // Need to use onpropertychange event for IE8 and lower
    if ("onpropertychange" in tArea && !("oninput" in tArea)) {
        tArea.onpropertychange = function () {
            // Only run code if value property changes
            if (window.event.propertyName == "value")
                this.oninput();
        }
    }
    
    // oninput will fire for all types of input, not just keyboard
    tArea.oninput = function () {
        // Temporarily remove the onpropertychange event to prevent a stack overflow
        var opc = this.onpropertychange;
        this.onpropertychange = null;
    
        // Revert value if the text exceeds the size of the box
        if (this.scrollHeight > this.offsetHeight) {
            this.value = prev;
        }
    
        prev = this.value;
    
        if (opc)
            this.onpropertychange = opc;
    }
    

    工作演示:-在Firefox 4、IE8、Chrome 9、Opera 10中测试。

    仅作总结。我将从讨论中排除Courier字体解决方案。因为在大多数情况下,这是不可接受的。使用向上键/属性更改的两种解决方案都有缺点: 以视觉方式输入文本,然后删除

    当IE中的最后一个符号为\n时,生成substr(0,oTextarea.value.length-1)会出现问题。在这种情况下,它将挂起,因为\r符号为左。因此,如果是最后一个,则应使用oTextarea.value.length-2\n

    对于on属性更改,应使用一些多浏览器解决方案。比如像


    使此类检查对用户友好(不允许输入)的唯一可能方法是为每个文本区域创建另一个隐藏文本区域,并在数据真正显示在原始文本区域之前(如按下键)在事件中对此文本区域进行所有检查。但在这种情况下,它需要处理所有的选择范围,粘贴并重新将其应用于隐藏。逻辑也不会是微不足道的。

    onkeyup
    对于这类事情来说是一种糟糕的方法。这让它变得非常笨重(比如,试着把手指放在钥匙上)。此外,Chrome 9中删除了太多字符。当我输入足够大的文本时,它不会截断最后一个符号,而是截断最后一个字符串的一半(ff 3.6)。@Yau没有更好的主意。。很抱歉我有另一个想法,但更糟糕的是,IMO在另一个下面有单独的文本框,例如,三个文本框,然后使用JS模拟换行。也不工作,因为预期值仍然没有被截断。请看firebug中的屏幕截图:@Yauhen:那么我认为您将很难以完全跨浏览器的方式实现这一点。