zoukankan      html  css  js  c++  java
  • [转载]自适应高度输入框

    初步实现代码如下:

    textarea {
         100%;
        height: 92px;
        padding: 20px;
        line-height: 50px;
        resize: none;
        outline: none;
        border: 1px solid #ccc;
        background: #eee;
        font-size: 32px;
        box-sizing: border-box;
    }
    复制代码
    <textarea id="textarea"></textarea>
    复制代码
    var $textarea = document.getElementById('textarea');
    
    $textarea.addEventListener('input', function() {
        // 总高度 = scrollHeight + 上下边框的宽度(1px * 2)
        $textarea.style.height = $textarea.scrollHeight + 2 + 'px';
    });
    复制代码

    然而,当内容高度缩减时,输入框的高度并没有跟随缩减。

    输入框的高度有误

    由于根据scrollHeight设置的元素高度的存在,即使内容高度缩减,此时scrollHeight也不会低于元素高度。所以,在做自适应高度缩减时就无法直接通过同步scrollHeight来实现,而是要先清掉高度样式:

    $textarea.addEventListener('input', function() {
        // 清除原来高度
        $textarea.style.height = '';
    
        $textarea.style.height = $textarea.scrollHeight + 2 + 'px';
    });
    复制代码

    实现后发现,输入到临近换行处,内容高度提前增高了。

    临界点异常

    调试后发现,清掉高度样式后,textarea恢复到原来的高度,此时内容超过textarea高度,因此会出现滚动条。滚动条会占据一定的空间,导致一行能容纳的字符减少,于是就提前换行了(如下图所示)。而因为在清理高度样式后,又立刻把高度设为新的scrollHeight,所以在界面上没有体现出现。

    原因

    要解决这个问题,只需要把滚动条隐藏掉。

    textarea {
        overflow: hidden;
    }
    复制代码

    虽然功能是做出来了,但是性能上还有优化的余地。因为当前的做法,相当于每次输入都要同步高度。如果高度没有发生变化,这个同步操作是没有意义的。所以,优化的思路就在于如何检查内容高度是否发生了变化:

    • 内容增加时,scrollHeight有可能会发生变化,所以可以记录上一次的scrollHeight,并与当前的scrollHeight对比,有变化时才设置高度样式。
    • 内容减少时,没有有效的方式可以知道内容高度是否有变更(scrollHeight不会减少),所以这种情况目前无法优化。

    实现代码如下:

    var $textarea = document.getElementById('textarea');
    var lastLength = 0;
    var lastHeight = 0;
    
    $textarea.addEventListener('input', function() {
        var currentLength = $textarea.value.length;
    
        // 判断字数如果比之前少了,说明内容正在减少,需要清除高度样式,重新获取
        if (currentLength < lastLength) {
            $textarea.style.height = '';
        }
    
        var currentHeight = $textarea.scrollHeight;
    
        // 如果内容高度发生了变化,再去设置高度值
        if (lastHeight !== currentHeight || !$textarea.style.height) {
            $textarea.style.height = currentHeight + 2 + 'px';
        }
    
        lastLength = currentLength;
        lastHeight = currentHeight;
    });
    自己写的一个,有点bug,聚焦的时候输入框没清空
    
    <div class="list-group-textarea" id="groupAreaEle" :value="desc" placeholder="填写聚会介绍,详细介绍主题、费用、流程等" v-on:input="onInputDesc  | debounce 500" contenteditable="true"></div>
    <div class="list-blank"></div>
    <span class="counter" v-html="teatareaWordCount"></span>
    
    .list-group-textarea {
            100%;
            min-height:shift(138);
            font-size:shift(26);
            font-weight:400;
            color:rgba(50,51,51,1);
            line-height:shift(37);
            padding-top:shift(27);
            background:rgba(249,249,249,1);
            outline: 0 none;
            overflow:hidden;
            box-sizing:border-box;
            -webkit-user-select:text;
            -webkit-user-select:auto;
            &:empty:before {
                content: attr(placeholder);
                letter-spacing: 0;
                text-align: justify;
                font-size:shift(26);
                font-weight:400;
                color:rgba(205,205,205,1);
            }
            &:focus {
                content: none;
            }
        }
        .list-blank{
            100%;
            height:shift(102);
            margin:0;
            padding:0;
        }
        .counter {
            position: absolute;
            right: 0;
            font-size: shift(24);
            line-height: shift(33);
            color: #aaaaaa;
            font-weight:400;
        }
  • 相关阅读:
    PIL PNG格式通道问题的解决方法
    opencv-python 学习初探2 去图片水印
    Appium、selenium与Robot Framework
    性能监控0
    XML
    Python3 读取和写入excel
    Python识别字符型图片验证码
    python进程、线程、协程
    算法和程序
    Zigbee
  • 原文地址:https://www.cnblogs.com/sybboy/p/9493572.html
Copyright © 2011-2022 走看看