LoginSignup
2
0

More than 3 years have passed since last update.

[JavaScript] 伸び縮みするテキストボックスを実装する (Vanilla JS)

Last updated at Posted at 2019-05-29

やりたいこと

値の長さに応じて幅が変わる input 要素を実装したい。

実装

/*
 * fromElement から toElement にスタイルをコピーする。
 */
const copyComputedStyle = (fromElement, toElement, except = []) => {
  const computedStyle = getComputedStyle(fromElement);
  Array.from(computedStyle).forEach((key) => {
    if (!except.includes(key)) {
      const value = computedStyle.getPropertyValue(key);
      const priority = computedStyle.getPropertyPriority(key);
      toElement.style.setProperty(key, value, priority);
    }
  });
};

/*
 * 文字列を HTML エスケープする。
 */
const escapeHTML = (text) => {
  if (typeof text !== 'string') {
    return text;
  }

  return text.replace(/[&'`"<> ]/g, (match) => {
    return {
      '&': '&amp;',
      "'": '&#x27;',
      '`': '&#x60;',
      '"': '&quot;',
      '<': '&lt;',
      '>': '&gt;',
      ' ': '&nbsp;'
    }[match]
  });
};

/*
 * 仮の span 要素の innerHTML に input 要素の値を設定して width を計測する。
 */
const getTextWidth = (input) => {
  // span 要素はなるべく input 要素と同じスタイルにする。
  const span = document.createElement('span');
  copyComputedStyle(input, span, ['display', 'width']);
  span.style.maxWidth = '100vw';

 span.innerHTML = escapeHTML(input.value);
  document.body.appendChild(span);
  const width = span.getBoundingClientRect().width;
  document.body.removeChild(span);

  return width;
};

const adjustWidth = (input) => {
  input.style.width = `${getTextWidth(input)}px`;
};

const input = document.querySelector('input');
adjustWidth(input);
input.addEventListener('keyup', adjustWidth.bind(null, input));

デモ

デモ用画面の幅に余裕を持たせるため 0.5x で試すことをおすすめします。

See the Pen 伸び縮みするテキストボックス by QUANON (@quanon) on CodePen.

参考

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0