Как я могу прочитать текущее значение textarea.rows и cols?

Я ожидал, что свойства .rows и .cols элемента textarea в javascript сообщат мне текущие значения, но они не сообщают мне только начальные значения атрибута разметки, даже после изменения размера textarea.

function howBigAmI(){
  let el= document.getElementById("textarea")
  
    document.getElementById("output").innerHTML=
    `${el.rows} rows by ${el.cols} cols, text length=${el.value.length}`  
    
}
howBigAmI()
<p>
How can I read the current textarea rows and cols?
</p>
<textarea oninput = "javascript:howBigAmI()" id = "textarea">
how big am I?
</textarea>
<div id = "output">size</div>

Как я могу получить текущие значения?

(На свойство lineHeight нельзя полагаться, если я не установил его явно, так что это не решение.)

(Я хочу вычислить, сколько строк необходимо, чтобы отобразить все текущее содержимое текстовой области, если ширина остается неизменной. Но я не хочу устанавливать какое-либо из свойств, чтобы иметь возможность выполнить расчет.)

Аналогичный stackoverflow.com/questions/57919005/… в решающей степени зависит от установки свойства line-height (в противном случае оно не установлено), поэтому у меня это не работает.

Chris F Carroll 22.07.2024 15:58

Проголосовали за открытие. Связанный вопрос был задуман только как предложение и содержал только строки.

fdomn-m 22.07.2024 16:02
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
2
79
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Может ли «необходимая высота» быть в пикселях или она вам абсолютно необходима в «единицах строк»?

Если возможен вариант с пикселями, используйте el.scrollHeight, например:

function howBigAmI(){
    let el= document.getElementById("textarea")
    document.getElementById("output").innerHTML = 'textarea should be ' + el.scrollHeight + ' pixels high to fit all the content';
}
Ответ принят как подходящий

Наверное, лучшим вариантом было бы вычислить scrollHeight / offsetHeight в том же <textarea>, но с row = "1"

const getRows = textarea => {
  const computedStyle = getComputedStyle(textarea);
  const { offsetWidth: realOffsetWidth, scrollWidth: realScrollWidth } =
    getSize(textarea);
  const realScrollbarWidth = realOffsetWidth - realScrollWidth;

  const tempElement = document.createElement('textarea');

  tempElement.rows = 1;
  tempElement.style.font = computedStyle.font;
  tempElement.style.border = computedStyle.border;
  tempElement.style.padding = computedStyle.padding;
  tempElement.style.lineHeight = computedStyle.lineHeight;
  tempElement.style.overflowY = 'scroll';
  tempElement.style.position = 'absolute';
  tempElement.style.visibility = 'hidden';

  document.body.appendChild(tempElement);

  const { offsetWidth, scrollWidth } = getSize(tempElement);
  const scrollbarWidth = offsetWidth - scrollWidth;
  tempElement.style.width = realScrollbarWidth
    ? realOffsetWidth + 'px'
    : realOffsetWidth + scrollbarWidth + 'px';

  tempElement.textContent = textarea.value;

  const { offsetHeight, scrollHeight } = getSize(tempElement);

  document.body.removeChild(tempElement);

  return Math.floor(scrollHeight / offsetHeight);
};

const getSize = el => {
  const computedStyle = getComputedStyle(el);
  const paddingTop = parseFloat(computedStyle.paddingTop);
  const paddingBottom = parseFloat(computedStyle.paddingBottom);
  const paddingLeft = parseFloat(computedStyle.paddingLeft);
  const paddingRight = parseFloat(computedStyle.paddingRight);
  const borderTop = parseFloat(computedStyle.borderTopWidth);
  const borderBottom = parseFloat(computedStyle.borderBottomWidth);
  const borderLeft = parseFloat(computedStyle.borderLeftWidth);
  const borderRight = parseFloat(computedStyle.borderRightWidth);

  const offsetHeight =
    el.offsetHeight - paddingTop - paddingBottom - borderTop - borderBottom;
  const scrollHeight = el.scrollHeight - paddingTop - paddingBottom;
  const offsetWidth =
    el.offsetWidth - paddingLeft - paddingRight - borderLeft - borderRight;
  const scrollWidth = el.scrollWidth - paddingLeft - paddingRight;

  return { offsetHeight, scrollHeight, offsetWidth, scrollWidth };
};

output.textContent = getRows(textarea);

textarea.addEventListener('input', function () {
  output.textContent = getRows(this);
});

const resizeObserver = new ResizeObserver(() => {
  output.textContent = getRows(textarea);
});
resizeObserver.observe(textarea);
<p>
How can I read the current textarea rows and cols?
</p>
<textarea id = "textarea">how big
am I?</textarea>
<div id = "output"></div>

Мне грустно, что это так сложно, но похоже, что расчет правильный, спасибо.

Chris F Carroll 25.07.2024 10:18

Однако я изменил свой ответ, потому что первый вариант с line-height был неточным...

imhvost 25.07.2024 12:41

Другие вопросы по теме