使用文本动态扩展<input />元素

时间:2016-01-14 20:34:27

标签: javascript html css

我觉得这应该很容易。我一直在寻找/尝试至少一周,但仍无济于事。

我想要一个带有占位符文字的<input>元素。我希望元素只与占位符文本一样宽。当您点击<input>时,我希望宽度保持不变。在您输入内容时,如果您的输入文字超出了原始占位符文字的宽度(因此超出了<input>元素本身的宽度),我希望展开<input>以容纳文字。

想法,那么?

2 个答案:

答案 0 :(得分:1)

这是一个尝试(在香草javascript)的一个尝试解决方案,考虑到不同的字体大小,不同的字符宽度等:

&#13;
&#13;
function reviewWidth(startWidth) {

/* Grab various elements */
var hiddenSpan = document.getElementsByClassName('hidden')[0];
var inputValue = document.getElementsByTagName('input')[0].value;

/* Update text content of hiddenSpan */
hiddenSpan.innerHTML = inputValue;

/* Update <input> width */
var hiddenSpanStyles = getComputedStyle(hiddenSpan);
var newWidth = parseInt(hiddenSpanStyles.getPropertyValue('width'));

if (newWidth > startWidth) {
    input.style.width = newWidth + 'px';
}

else {
    input.style.width = startWidth + 'px';	
}

}

/* Grab various elements */
var body = document.getElementsByTagName('body')[0];
var input = document.getElementsByTagName('input')[0];
var placeholder = input.getAttribute('placeholder');

/* Create hiddenSpan */
var hiddenSpan = document.createElement('span');
var placeholderText = document.createTextNode(placeholder);
hiddenSpan.appendChild(placeholderText);

/* Style hiddenSpan */
var inputStyles = getComputedStyle(input);
hiddenSpan.style.fontFamily = inputStyles.getPropertyValue('font-family');
hiddenSpan.style.fontSize = inputStyles.getPropertyValue('font-size');
hiddenSpan.style.borderLeftWidth = inputStyles.getPropertyValue('border-left-width');
hiddenSpan.style.paddingLeft = inputStyles.getPropertyValue('padding-left');
hiddenSpan.style.paddingRight = inputStyles.getPropertyValue('padding-right');
hiddenSpan.style.borderRightWidth = inputStyles.getPropertyValue('border-right-width');
hiddenSpan.style.display = 'inline-block';
hiddenSpan.style.opacity = '0';
hiddenSpan.classList.add('hidden');

/* Add hiddenSpan to document body */
body.appendChild(hiddenSpan);

/* Initialise <input> width */
var hiddenSpanStyles = getComputedStyle(hiddenSpan);
var startWidth = parseInt(hiddenSpanStyles.getPropertyValue('width'));
input.style.width = startWidth + 'px';

/* Run reviewWidth() function once */
if (input.value != '') {
    reviewWidth(startWidth);
}


/* Add Event Listener to <input> to trigger reviewWidth() function */
input.addEventListener('input',function(){reviewWidth(startWidth);},false);
&#13;
input {
font-family: arial, sans-serif;
font-size: 0.8em;
padding: 2px;
}
&#13;
<input type="text" placeholder="Example Placeholder" />
&#13;
&#13;
&#13;

答案 1 :(得分:0)

我对@ Rounin的答案进行了一些小的改进,以便我自己尝试:

  • 解析HTML中的连续空格会压缩到一个空格,除非它们没有中断,因此我将&nbsp映射到<。另外,我将&lt;映射到textContent以转义HTML。我没有使用innerHTML而不是textContent的原因是因为没有办法将不间断的空格注入width
  • 隐藏的跨度在不需要时不再是DOM的一部分,因此当它太宽时不会触发父元素滚动。
  • parseFloat的像素值实际上是浮点数,而不是整数,因此使用parseInt代替<input/>会使/* Set up */ var regExp = /[ <]/g; function replacer(c) { return { ' ': '&nbsp;', '<': '&lt;' }[c]; } /* Grab various elements */ var body = document.querySelector('body'); var input = document.querySelector('input'); var placeholder = input.getAttribute('placeholder'); /* Create hiddenSpan */ var hiddenSpan = document.createElement('span'); hiddenSpan.innerHTML = placeholder.replace(regExp, replacer); /* Style hiddenSpan */ var inputStyles = getComputedStyle(input); ['font', 'padding', 'border', 'display'].forEach(function(prop) { hiddenSpan.style[prop] = inputStyles.getPropertyValue(prop); }); hiddenSpan.style.visibility = 'hidden'; hiddenSpan.style.pointerEvents = 'none'; var hiddenSpanStyles = getComputedStyle(hiddenSpan); /* Initialise <input> width */ body.appendChild(hiddenSpan); var startWidth = parseFloat(hiddenSpanStyles.getPropertyValue('width')); body.removeChild(hiddenSpan); function reviewWidth() { var inputValue = input.value; /* Update text content of hiddenSpan */ hiddenSpan.innerHTML = inputValue.replace(regExp, replacer); body.appendChild(hiddenSpan); /* Update <input> width */ var newWidth = parseFloat(hiddenSpanStyles.getPropertyValue('width')); body.removeChild(hiddenSpan); if (newWidth > startWidth) { input.style.width = newWidth + 'px'; } else { input.style.width = startWidth + 'px'; } } reviewWidth(); /* Add Event Listener to <input> to trigger reviewWidth() function */ input.addEventListener('input', reviewWidth, false);宽度更精确。
  • 我试着保持可读性,但是我减少了一些代码以减少冗长。

input {
  font-family: arial, sans-serif;
  font-size: 0.8em;
  padding: 2px;
}
<input type="text" placeholder="Example Placeholder" />
d-block d-md-none

如果您有任何问题或建议可以改进此答案,请随时发表评论。