创建一个用文本量调整大小的textarea(vanilla JS,no JQuery)

时间:2018-01-27 01:19:14

标签: javascript

服务器端开发人员,希望能够学习一些香草JS来学习绳索。

这个问题是关于创建一个表单,其中textareas最初隐藏在按钮点击后面,并且随着输入其中的文本变大而调整大小。对于我这个级别的人来说,这是一个具有挑战性的问题,而我自己也是为了学习目的而编写代码。

这是我到目前为止所做的事情。

想象一下用户提交文字内容的论坛。每个提交都有一个"回复"它下面的按钮。按下可打开一个简单的textarea,可以输入他们的响应。我写了简单的JS来实现这个目标:

var replyBtns = document.querySelectorAll('[id=rep]');

for(var i = 0; i < replyBtns.length; i++) {
 replyBtns[i].addEventListener('click', function(e) {
   e.preventDefault();
   var textarea = document.getElementById("reply-message");
   if (textarea) { textarea.parentNode.removeChild(textarea); }
   var replyBox = document.createElement('textarea');
    replyBox.setAttribute('id', 'reply-message');
    replyBox.setAttribute('placeholder', 'Reply');
   this.parentNode.insertAdjacentElement('beforeend', replyBox);
 }, false);
}

如您所见,此JS创建了一个文本区域并将其添加到HTML中。与它一起使用的CSS是:

textarea#reply-message {
  display: block;
  border: none;
  color:#306654;
  font-size:120%;
  padding: 5px 10px;
  line-height: 20px;
  width:550px;
  height: 20px;
  border-radius: 6px;
  overflow: hidden;
  resize: none;
}

这很有效。

我的下一个努力是在文本开始溢出时使textarea调整大小。为此,我采取了这条路线:

  • 抓取加载到textarea

  • 的内容
  • 创建一个不可见的克隆div

  • 为克隆提供与textarea

  • 相同的宽度和印刷属性
  • 将内容放入克隆

  • 获取克隆的高度

  • 将克隆的高度应用到textarea

    的高度

此策略使用任何div元素自然拉伸以适合其内容高度的属性(假设没有浮动或绝对定位的元素)。我将此技术归功于this博文。

这是用于实施上述技术的JS:

let txt = document.getElementById('reply-message'),
    hiddenDiv = document.createElement('div'),
    content = null;

hiddenDiv.classList.add('hiddendiv');

document.body.appendChild(hiddenDiv);

txt.addEventListener('keyup', function () {

  content = this.value;
  hiddenDiv.innerHTML = content + '\n\n';
  this.style.height = hiddenDiv.getBoundingClientRect().height + 'px';

}, false);

hiddendiv的位置:

.hiddendiv {
  position: absolute;
  left: -9999px;
  visibility: hidden;
  white-space: pre-wrap;
  width: 550px;
  height: 20px;
  font-size: 120%;
  padding: 5px 10px;
  word-wrap: break-word;
  overflow-wrap: break-word;
}

但事实是,我需要这个JS片段只在textarea实际存在时运行。

目前,我在页面加载时运行,因为textareas尚未存在,所以无法生效。我如何确保它只在创建后运行?作为JS的新手,这完全是我的想法。请指教。

4 个答案:

答案 0 :(得分:1)

这并没有完全回答你的问题,但重新调整你的代码以达到相同的效果。

您应该在创建事件监听器时将其添加到textarea,然后再将其添加到页面中。

在第一个javascript:

中插入这样的代码
replyBox.setAttribute('placeholder', 'Reply');
replyBox.addEventListener('keyup', function () {
    /* do event handling here */
}, false);

处理所有这些问题的一种更简洁的方法是将与设置textarea s相关的所有代码移动到单独的函数中。

function setUpReplyBox(replyBox) {
    replyBox.setAttribute('id', 'reply-message');
    replyBox.setAttribute('placeholder', 'Reply');

    hiddendiv.createElement('div');
    content = null;

    hiddendiv.classList.add('hiddendiv');
    document.body.appendChild(hiddenDiv);

    replyBox.addEventListener('keyup', function () {
        content = this.value;
        hiddenDiv.innerHTML = content + '\n\n';
        this.style.height = hiddenDiv.getBoundingClientRect().height + 'px';
    }, false);
}

创建项目后立即调用此方法
var replyBox = document.createElement('textarea');
setUpReplyBox(replyBox);
this.parentNode.insertAdjacentElement('beforeend', replyBox);

答案 1 :(得分:0)

收听domContentLoaded事件

document.addEventListener("DOMContentLoaded", function(event) {
    console.log("DOM fully loaded and parsed");
});

参考链接 https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded

答案 2 :(得分:0)

使用contenteditable而不是textarea的div可能会让您的生活更轻松一些。

&#13;
&#13;
#textarea {
    -moz-appearance: textfield-multiline;
    -webkit-appearance: textarea;
    border: 1px solid gray;
    padding: 2px;
    width: 400px;
}
&#13;
<div id="textarea" contenteditable>dummy textarea</div>
&#13;
&#13;
&#13;

答案 3 :(得分:0)

autosize

的插件

检查github处的src,您将了解如何操作。

如果您的代码在页面加载中工作而不在文本更新中,则需要在每个键盘调用调整大小函数,调整大小和输入事件。

window.addEventListener('resize', yourFunc);
textarea.addEventListener('paste', yourFunc);
textarea.addEventListener('keyup', yourFunc);

有更简单的方法here

function auto_grow(element) {
    element.style.height = "5px";
    element.style.height = (element.scrollHeight)+"px";
}
textarea {
    resize: none;
    overflow: hidden;
    min-height: 50px;
}
<textarea onkeyup="auto_grow(this)"></textarea>