借鉴Element-ui中源码方法实现H5页面中textarea自适应高度方法

借鉴Element-ui中源码方法实现H5页面中textarea自适应高度方法
直接上方法和使用吧(vue项目)
  • 方法(在项目的公共方法中,添加一个js文件)

    let hiddenTextarea;
    
    const HIDDEN_STYLE = `
      height:0 !important;
      visibility:hidden !important;
      overflow:hidden !important;
      position:absolute !important;
      z-index:-1000 !important;
      top:0 !important;
      right:0 !important
    `;
    
    const CONTEXT_STYLE = [
      'letter-spacing',
      'line-height',
      'padding-top',
      'padding-bottom',
      'font-family',
      'font-weight',
      'font-size',
      'text-rendering',
      'text-transform',
      'width',
      'text-indent',
      'padding-left',
      'padding-right',
      'border-width',
      'box-sizing',
    ];
    
    function calculateNodeStyling(targetElement) {
      const style = window.getComputedStyle(targetElement);
    
      const boxSizing = style.getPropertyValue('box-sizing');
    
      const paddingSize = (
        parseFloat(style.getPropertyValue('padding-bottom')) +
        parseFloat(style.getPropertyValue('padding-top'))
      );
    
      const borderSize = (
        parseFloat(style.getPropertyValue('border-bottom-width')) +
        parseFloat(style.getPropertyValue('border-top-width'))
      );
    
      const contextStyle = CONTEXT_STYLE
        .map((name) => `${name}:${style.getPropertyValue(name)}`)
        .join(';');
    
      return { contextStyle, paddingSize, borderSize, boxSizing };
    }
    
    export default function calcTextareaHeight(
      targetElement,
      minRows = 1,
      maxRows = null,
    ) {
      if (!hiddenTextarea) {
        hiddenTextarea = document.createElement('textarea');
        document.body.appendChild(hiddenTextarea);
      }
    
      let {
        paddingSize,
        borderSize,
        boxSizing,
        contextStyle,
      } = calculateNodeStyling(targetElement);
    
      hiddenTextarea.setAttribute('style', `${contextStyle};${HIDDEN_STYLE}`);
      hiddenTextarea.value = targetElement.value || targetElement.placeholder || '';
    
      let height = hiddenTextarea.scrollHeight;
      const result = {};
    
      if (boxSizing === 'border-box') {
        height = height + borderSize;
      } else if (boxSizing === 'content-box') {
        height = height - paddingSize;
      }
    
      hiddenTextarea.value = '';
      let singleRowHeight = hiddenTextarea.scrollHeight - paddingSize;
    
      if (minRows !== null) {
        let minHeight = singleRowHeight * minRows;
        if (boxSizing === 'border-box') {
          minHeight = minHeight + paddingSize + borderSize;
        }
        height = Math.max(minHeight, height);
        result.minHeight = `${ minHeight }px`;
      }
      if (maxRows !== null) {
        let maxHeight = singleRowHeight * maxRows;
        if (boxSizing === 'border-box') {
          maxHeight = maxHeight + paddingSize + borderSize;
        }
        height = Math.min(maxHeight, height);
      }
      result.height = `${ height }px`;
      hiddenTextarea.parentNode && hiddenTextarea.parentNode.removeChild(hiddenTextarea);
      hiddenTextarea = null;
      return result;
    }
    
  • 使用(我这里是使用vue中watch来触发方法)

    <textarea
      ref="textarea"
      v-model="machine.acceptdtl"
      :style="{'height': height}"
      maxlength="1000"
      @input="inputRule"
      @focus="onFocus('333')"
      @blur="onBlur"
    />
    
    watch: {
        'machine.acceptdtl': {
          handler: function() {
            this.getHeight();
          },
        },
      },
    
    getHeight() {
      this.height = calcTextareaHeight(this.$refs.textarea, 1, null).height;
    },
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值