Edited at

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


やりたいこと

値の長さに応じて幅が変わる 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.


参考