【问题标题】:Max lines textarea最大线文本区域
【发布时间】:2014-03-29 12:58:53
【问题描述】:

我发现一些脚本会限制文本区域中使用的行,如下所示:

 $(document).ready(function(){

        var lines = 10;
        var linesUsed = $('#linesUsed');
        var newLines=0;

        $('#rev').keydown(function(e) {

            newLines = $(this).val().split("\n").length;
            linesUsed.text(newLines);

            if(e.keyCode == 13 && newLines >= lines) {
                linesUsed.css('color', 'red');
                return false;
            }
            else {
                linesUsed.css('color', '');
            } 
        }); 

当您按 enter 并将其限制为 10 时它工作正常。但是当您键入的句子太长时会出现问题,它们会自动转到没有 \n 的新行,并且当您复制粘贴文本时,它会失败限制使用的行数。

有谁知道如何解决这个问题。

重要提示:解决方案需要适用于文本区域

【问题讨论】:

  • 您是否尝试过计算line-height
  • 我试过了,看看我的答案...
  • 粘贴文字时你想让它做什么,你想让文字切断任何超出限制的东西......?
  • 好的,我更新了我的答案,看看吧!如果您认为它是正确答案,请不要忘记接受它作为正确答案(投票按钮下方的大复选标记)! ;)
  • 不确定你的情况,但我还没有找到任何专门用 textarea 解决这个问题的方法,尽管我通常很擅长搜索...任何理由绝对 需要使用文本区域吗?

标签: javascript textarea


【解决方案1】:

您可以尝试使用以下逻辑:

JS :

var limit = 3; // <---max no of lines you want in textarea
var textarea = document.getElementById("splitLines");
var spaces = textarea.getAttribute("cols");

textarea.onkeyup = function() {
   var lines = textarea.value.split("\n");

   for (var i = 0; i < lines.length; i++) 
   {
         if (lines[i].length <= spaces) continue;
         var j = 0;

        var space = spaces;

        while (j++ <= spaces) 
        {
           if (lines[i].charAt(j) === " ") space = j;  
        }
    lines[i + 1] = lines[i].substring(space + 1) + (lines[i + 1] || "");
    lines[i] = lines[i].substring(0, space);
  }
    if(lines.length>limit)
    {
        textarea.style.color = 'red';
        setTimeout(function(){
            textarea.style.color = '';
        },500);
    }    
   textarea.value = lines.slice(0, limit).join("\n");
};

这里是UPDATED DEMO

【讨论】:

  • 我看到你“人为地”对文本区域应用换行符,但是这将很难使用不同的字体进行管理......不过,我必须承认,这不是一个糟糕的解决方案。跨度>
  • @iCode4U: 干杯队友:)
  • 有没有办法让它到达文本区域的末尾?
【解决方案2】:

好吧,我不知道如何只计算文本区域内文本的高度,所以我改用了contenteditable div。希望你喜欢这个解决方案。

HTML

<div id="container">
    <div id="rev" contenteditable="true"></div>
</div>

CSS

#container {
    height:100px;
    width:300px;
    cursor:text;
    border:1px solid #000
}
#rev {
    line-height:20px;
    outline:none
}

JS

$(document).ready(function () {
    $('#container').click(function() {
        $('#rev').focus();
    });

    var limit = 3;
    var lineHeight = parseInt($('#rev').css('line-height'));

    $('#rev').keydown(function (e) {
    var totalHeight = parseInt($('#rev').height());
    var linesUsed = totalHeight / lineHeight;

        if (e.keyCode == 13 && linesUsed >= limit) {
            $('#rev').css('color', 'red');
            return false;
        } else {
            $('#rev').css('color', '');
        }
    });
});

HERE IS A DEMO YOU CAN FIDDLE WITH

主要编辑

在 OP 指出我实际上忘记解决最重要的问题之后,我更新了我的代码。我基本上删除了对回车键的检查,并允许删除和退格键,以防文本超出限制,如下所示。您可能需要稍微摆弄一下才能使其适合您的确切需求。

$(document).ready(function () {
    $('#container').click(function() {
        $('#rev').focus();
    });

    var limit = 3;
    var lineHeight = parseInt($('#rev').css('line-height'));

    $('#rev').keydown(function (e) {
    var totalHeight = parseInt($('#rev').height());
    var linesUsed = totalHeight / lineHeight;

        if (linesUsed > limit) { // I removed 'e.keyCode == 13 &&' from here
            $('#rev').css('color', 'red');
            if (e.keyCode != 8 && e.keyCode != 46) return false; // I added this check
        } else {
            $('#rev').css('color', '');
        }
    });    
        
    // I added the following lines
    $('#rev').on('paste', function () { 
        if (linesUsed > limit) {
            $('#rev').css('color', 'red');
            if (e.keyCode != 8 && e.keyCode != 46) return false;
        } else {
            $('#rev').css('color', '');
        }
    });
});

UPDATED DEMO HERE

【讨论】:

  • 感谢您的努力,但这并不能解决问题,我仍然无法复制粘贴,而且它不适用于长句子。
  • 很高兴我能帮助你走上正轨……;)
  • 您误会了:您没有将其应用于 textarea,而是将 textarea 替换为此
  • ...如果这甚至可以用 textarea 实现,我不会感到惊讶,但不要指望所有内容都是由其他人编写的,您也必须做功课!
  • 我做了更多的测试和研究,但我根本找不到可以准确计算文本区域中的高度或行数的解决方案...
【解决方案3】:

尝试根据每行中的数字字符和 textarea 宽度来计算有多少行(textarea 是否有环绕?字体大小、不同的字母宽度、空格等...) .最简单的方法是设置两个具有相同宽度和字体样式的文本区域(一个可见,一个不高度设置为 0),并检查不可见文本区域的滚动高度。

这是一个例子http://jsfiddle.net/SKYt4/1/

HTML

<textarea id="visible_textarea"></textarea>
<textarea id="hidden_textarea"></textarea> <!-- hidden by setting the height to 0 -->
<div id="used_lines"></div>

CSS

textarea {line-height:16px; /* line height to calculate number of lines */
    width:150px; /* need to match width */}
#hidden_textarea {height:0px;
    padding:0px;
    border:none;
    margin:0px;
    opacity:0;}

JavaScript

$('#visible_textarea').keyup(function(){
    $('#hidden_textarea').val(this.value);
    // checking how many lines
    var lns = Math.ceil(document.getElementById('hidden_textarea').scrollHeight / parseInt($('#hidden_textarea').css('line-height')));

    if (lns > 10) {
         $('#used_lines').css('color', '#ff0000');
    }
    else {
        $('#used_lines').css('color', '');
    }

    $('#used_lines').html(lns+' lines');
});


$('#visible_textarea').change(function(){
    $(this).keyup();
});

【讨论】:

  • 1.为什么你需要一个隐藏的文本区域来计算高度? 2.您没有提供防止进一步打字的解决方案。 3. 您目前还允许调整 textarea 的大小,这将破坏此代码...
  • 这个脚本的工作方式是将隐藏文本区域的滚动高度除以行高。由于滚动高度最小值是元素高度,因此我们必须将高度设置为 0 才能获得准确的滚动高度。要停止进一步键入,您可以添加一个 keydown 事件来检查行数并阻止用户进一步键入。您可以通过设置 css 规则 resize: none; 来停止调整大小。
  • 我确切地知道我会怎么做,但是你的答案中没有对它的解释,除了“为什么隐藏的文本区域” - 那是为了满足我的好奇心......; )
  • 问题:在某些浏览器上(Chrome 是我注意到这一点的地方),.css('line-height') 返回一个非整数值,例如normal。解决方案:把你知道的东西高一行,然后得到高度:$('#hidden_textarea').val("A"); var text_height = document.getElementById('hidden_textarea').scrollHeight;然后你可以除以text_height得到行数。
  • 另外,隐藏的文本框有一个滚动条,它会在与可见文本框稍有不同的地方换行。将overflow-y: hidden; 添加到#hidden_textbox CSS 以进行修复。
猜你喜欢
  • 2015-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多