0

I'm having a bit of trouble with some code I put into a page. I want to have every textarea element auto-grow when altered and auto-resize when the page first loads. The code I've got is as follows:

function auto_grow(element) {
    element.style.height = '5px';
    element.style.height = (element.scrollHeight) + 'px';
    console.log(element + ' changed to ' + element.style.height);
}

window.addEventListener('load', function () {
    var e = document.getElementsByTagName('textarea');
    for (var i = 0; i < e.length; i++) {
        auto_grow(e[i]);
        e[i].addEventListener('change', function () {
            auto_grow(e[i])
        });
    }
})

It resizes on load with no problems, but not on change. I assume I'm missing something simple, but I can't work out what it is. Can anyone shed some light on what I'm missing?

edit: based on the input received, I came up with the following solution that works for me:

window.addEventListener("load", function () {
        var e = document.getElementsByTagName('textarea');
        var a = Array.prototype.slice.call(e,0);
        a.forEach(function(x) {
            auto_grow(x);
            x.addEventListener("keyup", function(){auto_grow(this)});
            })
        }
    )

I used keyup as it seemed to be more consistent. forEach reminded me more of the iterative loops I'm used to from python, so I went with that option instead others.

Asa Stallard
  • 322
  • 1
  • 14
  • Have you tries `input` or `keyup` events? – Rajesh Dec 21 '16 at 08:21
  • The problem is that when the `change` event occurs, `i` is beyond the end of the array (see the linked question and its answers for why). Note that in this particular case, you can just use `this` instead of `e[i]` inside the handler (e.g., `auto_grow(this)`). Separately: `change` only fires when the control loses focus. If you want to call your `auto_grow` while it still has focus, look at the `input` event. – T.J. Crowder Dec 21 '16 at 08:23
  • @T.J.Crowder that can be 1 possible issue, but change event is not triggered even if you have 1 textarea. [JSFiddle](https://jsfiddle.net/RajeshDixit/xpLmab7s/1/). So this is not duplicate. Also **Asa Stallard**, a pointer, inside event handler, `this` is pointing to element itself. You dont need `e[i]`, just use `this` – Rajesh Dec 21 '16 at 08:30
  • @Rajesh: Yes, it's a duplicate, `e[i]` won't work inside the handler (which is why I also pointed him at `this`). Re your fiddle: `change` fires even when there's only one `textarea`. The relevant thing is the text area losing focus, not how many of them there are. – T.J. Crowder Dec 21 '16 at 08:42
  • Thanks for the input guys. I added my solution to the question in case anyone else has the same dilemma and doesn't search for closure inside loops. – Asa Stallard Dec 21 '16 at 08:46

0 Answers0