textarea高度随内容撑大

当textarea里的内容超过一行后,会出现滚动条并隐藏前一行的内容,特别是在移动端使用到textarea多行文本输入的话,这样显示其实是很不友好的。所以要做一个可根据内容改变高度的textarea的组件。由于项目是使用的vue写的所以就用vue举例了。

1.首先创建一个setTextarea.js用于存放设置高度的方法

setTextarea.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;
}

2.使用

引入setTextarea.js


<template>
  <div >
    <textarea ref="textarea" v-model="machine.acceptdtl" :style="{'height': height}" maxlength="1000" @input="inputRule" @blur="onBlur" class="multi-line-input"></textarea>
  </div>
</template>

<script>
import calcTextareaHeight from '@/plugins/setTextarea'
export default {
  name: 'TodayWork',
  data() {
    return {
      height: '',
      machine: {
        acceptdtl: ''
      }
    }
  },
  mounted() {
    this.getHeight();
  },
  methods: {
    getHeight() {
      this.height = calcTextareaHeight(this.$refs.textarea, 1, null).height;
    },
    inputRule() {

    },
    onBlur() { }
  },
  watch: {
    'machine.acceptdtl': {
      handler: function () {
        this.getHeight();
      },
    },
  }
}
</script>

<style scoped lang="scss">
.multi-line-input {
   width: 99%;
   min-height: auto;
   height: auto;
   resize: none;
}
</style>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值