Home > database >  backspace increases value of scrollheight
backspace increases value of scrollheight

Time:01-01

I'm trying to implement a simple script to manage resizing the textarea to fit the content. It works perfectly when adding content but every time I press the backspace key the scrollheight value increases by 3px!

document.querySelectorAll('textarea').forEach( element => {
  element.style.height = `${element.scrollHeight}px`
  element.addEventListener('input', event => {
    event.target.style.height = 'auto' // added this line
    event.target.style.height = `${event.target.scrollHeight}px`
  })
})
/* style.css */
main, header {
  max-width: 600px;
  margin: auto;
}

textarea {
  font-family: 'Times New Roman', Times, serif;
  border-style: hidden;
  outline: none;
  padding: 0.1em;
  margin: none;
  resize: none;
  width: 80%;
}

textarea:focus {
  border: 1px solid #DDD;
  border-radius: 0.2em;
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf8" />
    <meta name="viewport" content="width=device-width", initial-scale="1.0" />
    <title>Data Management</title>
    <link href="style.css" rel="stylesheet" type="text/css">
    <script type="module" src="./script.js" defer></script>
  </head>
  <body>
    <header>
      <h1>Data Management</h1>
    </header>
    <main>
      <p><textarea  id="article"></textarea></p>
    </main>
  </body>
</html>

Does anyone know the cause of this annoying behaviour?

CodePudding user response:

Explaining this requires understanding the box model. In this case, you are using scrollHeight, which includes borders and padding of the element - this is why the height is incrementing on any change.

For this I'm assuming you just want the textarea to expand when it's about to overflow, i.e. a scrollbar appears. Rather than having it change on every input event, check only if the scrollHeight exceeds the clientHeight. Whenever that occurs, increase the rows of the textarea in order to expand it.

document.querySelectorAll('textarea').forEach(element => {
  element.addEventListener('input', event => {
    while (event.target.scrollHeight > event.target.clientHeight) {
      event.target.rows  ;
    }
  });
})
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf8" />
  <meta name="viewport" content="width=device-width" , initial-scale="1.0" />
  <title>Data Management</title>
  <link href="style.css" rel="stylesheet" type="text/css">
  <script type="module" src="./script.js" defer></script>
</head>

<body>
  <header>
    <h1>Data Management</h1>
  </header>
  <main>
    <p><textarea  id="article"></textarea></p>
  </main>
</body>

</html>

CodePudding user response:

Problem:

You addEventListener to any input

Solution:

Filter by keycode

this.onkeyup = function(e) {
    if (e.keyCode != 32) {
 // Your code here
}
}

You can use this site to know the for any keyboard input keycode.info


You can find snipt

document.querySelectorAll('textarea').forEach(element => {
  element.style.height = `${element.scrollHeight}px`
  this.onkeyup = function(e) {
    if (e.keyCode != 32) {
      element.addEventListener('input', event => {
        event.target.style.height = `${event.target.scrollHeight}px`
      })
    }
  }

})
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf8" />
  <meta name="viewport" content="width=device-width" , initial-scale="1.0" />
  <title>Data Management</title>
  <link href="style.css" rel="stylesheet" type="text/css">
  <script type="module" src="./script.js" defer></script>
</head>

<body>
  <header>
    <h1>Data Management</h1>
  </header>
  <main>
    <p>
      <textarea  id="article"></textarea>
    </p>
  </main>
</body>

</html>

CodePudding user response:

I finally figured out what the problem was (and how to fix it). The solution was to set the height of the textarea to auto before resizing it to fit the contents (see below). I would be curious to know why this works...

/* script.js */

console.log('script loaded')

document.querySelectorAll('textarea').forEach( element => {
  element.style.height = `${element.scrollHeight}px`
  element.addEventListener('input', event => {
    event.target.style.height = 'auto' // added this line
    event.target.style.height = `${event.target.scrollHeight}px`
  })
})
  • Related