文档章节

textarea 高度自适应

l
 lerner
发布于 2016/12/08 18:02
字数 737
阅读 33
收藏 0
点赞 0
评论 0

前段时间做了一个textarea多行输入框,输入文本自动上顶,到第5行高度固定,且可滑动查看输入内容。(类似微信聊天输入框功能)

开始的思路是取出textarea的value值,然后将这个值放到一个隐藏域(div或者span)中。然后通过比较textarea与隐藏域的width值,来人为的追加"\n",(其实textarea中的折行并没有真正的换行,只有enter键才会触发换行)最后split("\n"),得到一个数组,该数组的长度即为textarea的行数。

试过之后,发现这种方法存在精度上的误差,根本原因是textarea的属性和span不同,比如说字符间距。

项目需求是这样的: 

源文件:


(function (root, factory) {
    'use strict';

//根据项目的实际情况,不同的引入方式
    if (typeof define === 'function' && define.amd) {
        define([], factory);
    } else if (typeof exports === 'object') {
        module.exports = factory();
    } else {
        root.autosize = factory();
    }
}(this, function () {
    function main(ta) {
        if (!ta || !ta.nodeName || ta.nodeName !== 'TEXTAREA' || ta.hasAttribute('data-autosize-on')) { return; }

        var maxHeight;
        var heightOffset;

        function init() {
            var style = window.getComputedStyle(ta, null); // 详细介绍getComputedStyle函数  http://www.zhangxinxu.com/wordpress/2012/05/getcomputedstyle-js-getpropertyvalue-currentstyle/

            if (style.resize === 'vertical') {
                ta.style.resize = 'none';
            } else if (style.resize === 'both') {
                ta.style.resize = 'horizontal';
            }

            ta.style.wordWrap = 'break-word';// horizontal overflow 设置为hidden,所以用 word-wrap:break-word 来控制textarea 的宽度是必要的

            // 当 textarea 的 overflow-y:hidden, Chrome/Safari浏览器不会由空格引起页面的回流
            // 可以通过去除滚动条来禁止页面回流
            var width = ta.style.width;
            ta.style.width = '0px';

            ta.offsetWidth;//这里会触发页面回流

            ta.style.width = width;

            maxHeight = style.maxHeight !== 'none' ? parseFloat(style.maxHeight) : false;//未设置最大高度,高度可以一直自适应

            if (style.boxSizing === 'content-box') {
                heightOffset = -(parseFloat(style.paddingTop)+parseFloat(style.paddingBottom));
            } else {
                heightOffset = parseFloat(style.borderTopWidth)+parseFloat(style.borderBottomWidth);
            }

            adjust();
        }

        function adjust() {
            var startHeight = ta.style.height;
            var htmlTop = document.documentElement.scrollTop;
            var bodyTop = document.body.scrollTop;
            var fontSize = parseFloat($('html')[0].style.fontSize) * 1.75 + "px";//行高
            ta.style.height = fontSize;

            var endHeight = ta.scrollHeight+heightOffset;

            if (maxHeight !== false && maxHeight < endHeight) {
                endHeight = maxHeight;
                if (ta.style.overflowY !== 'scroll') {
                    ta.style.overflowY = 'scroll';
                }
            } else if (ta.style.overflowY !== 'hidden') {
                ta.style.overflowY = 'hidden';
            }

            ta.style.height = endHeight +'px';

            // 防止滚动条位置跳跃
            document.documentElement.scrollTop = htmlTop;
            document.body.scrollTop = bodyTop;

            if (startHeight !== ta.style.height) {
                var evt = document.createEvent('Event');
                evt.initEvent('autosize.resized', true, false);
                ta.dispatchEvent(evt);
            }
        }

        //兼容IE9
        if ('onpropertychange' in ta && 'oninput' in ta) {
            ta.addEventListener('keyup', adjust);
        }

        window.addEventListener('resize', adjust);
        ta.addEventListener('input', adjust);

        ta.addEventListener('autosize.update', adjust);

        ta.addEventListener('autosize.destroy', function(style){
            window.removeEventListener('resize', adjust);
            ta.removeEventListener('input', adjust);
            ta.removeEventListener('keyup', adjust);
            ta.removeEventListener('autosize.destroy');

            Object.keys(style).forEach(function(key){
                ta.style[key] = style[key];
            });

            ta.removeAttribute('data-autosize-on');
        }.bind(ta, {
            height: ta.style.height,
            overflow: ta.style.overflow,
            overflowY: ta.style.overflowY,
            wordWrap: ta.style.wordWrap,
            resize: ta.style.resize
        }));

        ta.setAttribute('data-autosize-on', true);
        ta.style.overflow = 'hidden';
        ta.style.overflowY = 'hidden';

        init();
    }

    // IE8不支持
    if (typeof window.getComputedStyle !== 'function') {
        return function(elements) {
            return elements;
        };
    } else {
        return function(elements) {
            if (elements && elements.length) {
                Array.prototype.forEach.call(elements, main);
            } else if (elements && elements.nodeName) {
                main(elements);
            }
            return elements;
        };
    }
}));

引入:

var $dom = this.$dom;
        var oldElHeight = null;
        Array.prototype.forEach.call(document.querySelectorAll('textarea'), function(el){
            oldElHeight = el.style.height;
            el.addEventListener('autosize.resized',function(){
                if ($("#hasSended").html() == "") {//最后一次oldElHeight会一直保存在这里,所以点击发送之后,两边按钮
                                                   //样式会发生错乱,这里用来记录点击发送后,初始化oldElHeight的高度,第一次不会监听。
                    oldElHeight = "";
                }
                var nowElHeight = this.style.height;
                if(!!oldElHeight && !!nowElHeight && oldElHeight != nowElHeight){
                //样式设置
                    var adjust = parseFloat(nowElHeight) - parseFloat(oldElHeight);
                    $dom.speakBottomK.css("height",parseFloat($dom.speakBottomK.css("height")) + adjust + 'px');
                    $dom.speakInputCot.css("height",parseFloat($dom.speakInputCot.css("height")) + adjust + 'px');
                    $dom.toVoiceSwitch.css("margin-top",parseFloat($dom.toVoiceSwitch.css("margin-top")) + adjust + 'px');

                    $dom.sendQues.css("margin-top",parseFloat($dom.sendQues.css("margin-top")) + adjust + 'px');
                }
                oldElHeight = nowElHeight;
                $("#hasSended").html("已发送");//两个js文件 设置隐藏域来判断是否点击了发送按钮
            });
        });

        factory(document.querySelectorAll('textarea'));

 

© 著作权归作者所有

共有 人打赏支持
l
粉丝 0
博文 15
码字总数 3170
作品 0
DWZ框架的HTML扩展

DWZ框架HTML扩展 支持HTML扩展方式来调用DWZ组件 Ajax链接扩展使用方法 <a href=”xxx” target=“ajax” [rel=“boxId”]> 示例: <a href="w_alert.html" target="ajax" rel="container">提......

张慧华 ⋅ 2010/04/27 ⋅ 0

textarea自适应高度插件--textareaAutoHeight

使用方法: 0. 检查CSS文件中所有textarea的line-height值, 若是纯数字, 给它加上单位em, 如: 1.5em. 否则IE(6|7|8)下插件失效. 1. 加载jQuery库(1.4+) 2. 加载textareaAutoHeight.js 3. 使用...

JE ⋅ 2011/11/15 ⋅ 0

freemarker模板文件中文本域(textarea)的高度自适应实现

freemarker模板文件中实现文本域(textarea)的高度自适应实现。 从网上找的大部分办法中很多方法兼容性并不好,要么这个可以用,到了另外一个浏览器或者其他环境又不行了。下面的方式是比较通...

sprouting ⋅ 2016/05/28 ⋅ 0

textarea自动调整高宽

css: #textarea { display: block; margin:0 auto; overflow: hidden; width: 550px; font-size: 14px; height: 18px; line-height: 24px; padding:2px; } textarea { outline: 0 none; bord......

365850153 ⋅ 2016/01/12 ⋅ 0

CSS3常用知识

1.文本超出部分显示为... white-space:nowrap;text-overflow:ellipsis;-o-text-overflow:ellipsis;overflow: hidden; 2.文本超出多行结尾部分展示为... height: 46px; //它的值为行高乘以显示...

kouxiaomou ⋅ 2017/02/24 ⋅ 0

iframe 高度自适应

网站中常用到富文本编辑器来编辑一些网站信息来保持信息显示时和编辑时的样式一致,有时会因复制内容使编辑的信息中含有末闭合的 HTML 标签导致在网页中输出时影响了整个页面的结构,此时我们...

frylan ⋅ 2012/07/24 ⋅ 0

Ant Design 2.12.0 发布,阿里企业级 UI 设计语言

Ant Design 2.12.0 已发布,Ant Design 是蚂蚁金服开发和正在使用的一套企业级的 UI 设计语言和 React 实现。 本次更新如下: 新增 Card 属性以及 Card.Grid 组件。 DatePicker、MonthPicker...

王练 ⋅ 2017/07/10 ⋅ 9

超级简单:在一个TextArea中如何限制行数和字符数

在网上,已经有很多关于在一个textbox限制允许的字符数量。但是如果需要,在textbox中如何去统计和限制行数呢。这里有一个解决方案,使用客户端的Javascript去限制TextArea的内容为指定的字符...

王二狗子11 ⋅ 01/01 ⋅ 0

textarea自动扩展高度(jquery实现)

项目中用到了textarea自动扩展高度的功能,网上查了几个都不太完善,稍微修改了一下,主要是添加了当内容删除时候的自动减少高度功能。如需指定textarea,修改选择器即可。

在别处的老张头 ⋅ 2014/11/13 ⋅ 0

jquery----TextArea高度自适应

//最小高度和最大高度默认$("#textarea1").textareaAutoHeight();//最大高度为100px$("#textarea2").textareaAutoHeight({ maxHeight:100 });//最小高度为50px,最大高度为200px$("#textarea......

douya_love ⋅ 2013/04/15 ⋅ 1

没有更多内容

加载失败,请刷新页面

加载更多

下一页

如何使用serverchan微信推送告警

之前实现推送告警信息到微信的方法有如下几种: 1、通过企业公众号实现----收费: 2、通过QQ邮箱,在微信平台上开启收到邮件进行提醒; 3、第三方告警平台API,一般也是收费的; 不过最近看文...

问题终结者 ⋅ 30分钟前 ⋅ 0

TCP的RPC

RPC就是远程方法调用(Remote Process Call ),包含了客户端和服务端,涉及了对象的序列化传输。 1.服务端启动,注册远程调用的类2.客户端发送请求信息包含类、方法、参数的一些信息、序列化传...

Cobbage ⋅ 51分钟前 ⋅ 0

IOS-UI UI初步代码布局添加事件

ISO开发界面,UI是必须学习的一部分,其实很早之前想学来了,一直没有沉下心来学习。看到IOS的代码风格和布局就别扭的不行,跟java代码和android布局比较显得不是那么方便,所以一直到现在。...

京一 ⋅ 今天 ⋅ 0

浅谈OpenDaylight的二次开发

OpenDaylight作为一款开源SDN网络控制器,依托于强大的社区支持以及功能特性,成为了目前主流的SDN网络控制器开发平台。在比较稳定的OpenDaylight Helium版本中,已经为开发者提供了大量的网...

wangxuwei ⋅ 今天 ⋅ 0

API 开发中可选择传递 token 接口遇到的一个坑

在做 API 开发时,不可避免会涉及到登录验证,我使用的是jwt-auth 在登录中会经常遇到一个token过期的问题,在config/jwt.php默认设置中,这个过期时间是一个小时,不过为了安全也可以设置更...

等月人 ⋅ 今天 ⋅ 0

Java NIO之文件处理

程序要操作本地操作系统的一个文件,可以分为以下三个部分: 对文件位置的操作 对文件的操作 对文件内容的操作 其中,对文件内容的操作在 Java NIO之Channel 中已经有了介绍,通过FileChann...

士别三日 ⋅ 今天 ⋅ 0

Maven的pom.xml配置文件详解

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.......

小海bug ⋅ 今天 ⋅ 0

解决httpclient超时设置不生效的问题

最近公司有项目需要通过http调用第三方服务,且第三方服务偶有超时,故需要设置一定的超时时间防止不响应的情况出现。 初始设置如下: [java] view plain copy //超时设置 RequestConfig re...

Mr_Tea伯奕 ⋅ 今天 ⋅ 0

过滤器Filter和拦截器HandlerInterceptor

过滤器 依赖于servlet容器。在实现上基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的是用来做一些过滤操作,获取我们想要...

hutaishi ⋅ 今天 ⋅ 0

Redis入门详解(转)

Redis入门详解 Redis简介 Redis安装 Redis配置 Redis数据类型 Redis功能 持久化 主从复制 事务支持 发布订阅 管道 虚拟内存 Redis性能 Redis部署 Redis应用场景 Redis总结 Redis简介: Redi...

xiaoyaoyoufang ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部