Ответ 1
Вот пример с CSS и Редактируемый контент:
CSS
span
{
border: solid 1px black;
}
div
{
max-width: 200px;
}
HTML
<div>
<span contenteditable="true">sdfsd</span>
</div>
Я могу установить начальный размер ввода текста в css, например:
width: 50px;
Но я бы хотел, чтобы он увеличивался, когда я печатаю, пока он не достигнет, например, 200px. Можно ли это сделать в прямом css, html, желательно без javascript?
Конечно, отправляйте свои js/jquery-решения, но если это выполнимо без них - это будет здорово.
моя попытка здесь:
Вот пример с CSS и Редактируемый контент:
CSS
span
{
border: solid 1px black;
}
div
{
max-width: 200px;
}
HTML
<div>
<span contenteditable="true">sdfsd</span>
</div>
Я просто написал это для вас, надеюсь, вам понравится:) Нет гарантий, что это кросс-браузер, но я думаю, что это:)
(function(){
var min = 100, max = 300, pad_right = 5, input = document.getElementById('adjinput');
input.style.width = min+'px';
input.onkeypress = input.onkeydown = input.onkeyup = function(){
var input = this;
setTimeout(function(){
var tmp = document.createElement('div');
tmp.style.padding = '0';
if(getComputedStyle)
tmp.style.cssText = getComputedStyle(input, null).cssText;
if(input.currentStyle)
tmp.style.cssText = input.currentStyle.cssText;
tmp.style.width = '';
tmp.style.position = 'absolute';
tmp.innerHTML = input.value.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'")
.replace(/ /g, ' ');
input.parentNode.appendChild(tmp);
var width = tmp.clientWidth+pad_right+1;
tmp.parentNode.removeChild(tmp);
if(min <= width && width <= max)
input.style.width = width+'px';
}, 1);
}
})();
Как о программном изменении атрибута размера на входе?
Семантически (imo), это решение лучше, чем принятое решение, потому что оно по-прежнему использует поля ввода для ввода пользователем, но оно вводит немного jQuery. Soundcloud делает что-то похожее на это для их тегов.
<input size="1" />
$('input').on('keydown', function(evt) {
var $this = $(this),
size = parseInt($this.attr('size'), 10),
isValidKey = (evt.which >= 65 && evt.which <= 90) || // a-zA-Z
(evt.which >= 48 && evt.which <= 57) || // 0-9
evt.which === 32;
if ( evt.which === 8 && size > 0 ) {
// backspace
$this.attr('size', size - 1);
} else if ( isValidKey ) {
// all other keystrokes
$this.attr('size', size + 1);
}
});
От: Есть ли плагин jQuery для автозапуска для текстовых полей?
Смотрите демо здесь: http://jsbin.com/ahaxe
Плагин:
(function($){
$.fn.autoGrowInput = function(o) {
o = $.extend({
maxWidth: 1000,
minWidth: 0,
comfortZone: 70
}, o);
this.filter('input:text').each(function(){
var minWidth = o.minWidth || $(this).width(),
val = '',
input = $(this),
testSubject = $('<tester/>').css({
position: 'absolute',
top: -9999,
left: -9999,
width: 'auto',
fontSize: input.css('fontSize'),
fontFamily: input.css('fontFamily'),
fontWeight: input.css('fontWeight'),
letterSpacing: input.css('letterSpacing'),
whiteSpace: 'nowrap'
}),
check = function() {
if (val === (val = input.val())) {return;}
// Enter new content into testSubject
var escaped = val.replace(/&/g, '&').replace(/\s/g,' ').replace(/</g, '<').replace(/>/g, '>');
testSubject.html(escaped);
// Calculate new width + whether to change
var testerWidth = testSubject.width(),
newWidth = (testerWidth + o.comfortZone) >= minWidth ? testerWidth + o.comfortZone : minWidth,
currentWidth = input.width(),
isValidWidthChange = (newWidth < currentWidth && newWidth >= minWidth)
|| (newWidth > minWidth && newWidth < o.maxWidth);
// Animate width
if (isValidWidthChange) {
input.width(newWidth);
}
};
testSubject.insertAfter(input);
$(this).bind('keyup keydown blur update', check);
});
return this;
};
})(jQuery);
Приходит на ум несколько вещей:
Используйте текстовое поле onkeydown
в текстовом поле, измерьте текст * и соответствующим образом увеличьте размер текстового поля.
Прикрепите класс :focus
css к текстовому полю с большей шириной. Тогда ваше поле будет больше, если сфокусироваться. Это не совсем то, о чем вы просите, но похоже.
* Это не просто для измерения текста в javascript. Посмотрите этот вопрос для некоторых идей.
Здесь вы можете попробовать что-то вроде этого
EDIT: ПЕРЕСМОТРЕННЫЙ ПРИМЕР (добавлено одно новое решение) http://jsfiddle.net/jszjz/10/
Обозначение кода
var jqThis = $('#adjinput'), //object of the input field in jQuery
fontSize = parseInt( jqThis.css('font-size') ) / 2, //its font-size
//its min Width (the box won't become smaller than this
minWidth= parseInt( jqThis.css('min-width') ),
//its maxWidth (the box won't become bigger than this)
maxWidth= parseInt( jqThis.css('max-width') );
jqThis.bind('keydown', function(e){ //on key down
var newVal = (this.value.length * fontSize); //compute the new width
if( newVal > minWidth && newVal <= maxWidth ) //check to see if it is within Min and Max
this.style.width = newVal + 'px'; //update the value.
});
и css тоже довольно просто.
#adjinput{
max-width:200px !important;
width:40px;
min-width:40px;
font-size:11px;
}
EDIT: Другое решение состоит в том, чтобы присвоить пользователю тип, который он хочет, и размытие (фокус), захватить строку (в том же размере шрифта), поместить ее в div - подсчитать ширину div - и затем с приятным анимацией с прохладным эффектом ослабления обновите ширину полей ввода. Единственный недостаток заключается в том, что поле ввода останется "маленьким", пока пользователь набирает. Или вы можете добавить таймаут:) вы также можете проверить такое решение на скрипке!
Если вы установите диапазон для отображения: встроенный блок, автоматическое горизонтальное и вертикальное изменение размеров работает очень хорошо:
<span contenteditable="true"
style="display: inline-block;
border: solid 1px black;
min-width: 50px;
max-width: 200px">
</span>
Какой подход вы используете, конечно, зависит от вашей конечной цели. Если вы хотите представить результаты с помощью формы, то использование собственных элементов формы означает, что вам не нужно использовать сценарии для отправки. Кроме того, если скрипты отключены, резервная копия все еще работает без фантазийных эффектов сокращения. Если вы хотите получить простой текст из контентного элемента, вы всегда можете использовать скрипты типа node.textContent, чтобы вырезать html, который браузеры вставляют в пользовательский ввод.
Эта версия использует собственные элементы формы с небольшими уточнениями в некоторых предыдущих сообщениях.
Он также позволяет сокращать содержимое.
Используйте это в сочетании с CSS для лучшего контроля.
<html>
<textarea></textarea>
<br>
<input type="text">
<style>
textarea {
width: 300px;
min-height: 100px;
}
input {
min-width: 300px;
}
<script>
document.querySelectorAll('input[type="text"]').forEach(function(node) {
var minWidth = parseInt(getComputedStyle(node).minWidth) || node.clientWidth;
node.style.overflowX = 'auto'; // 'hidden'
node.onchange = node.oninput = function() {
node.style.width = minWidth + 'px';
node.style.width = node.scrollWidth + 'px';
};
});
Вы можете использовать нечто похожее с элементами textarea >
document.querySelectorAll('textarea').forEach(function(node) {
var minHeight = parseInt(getComputedStyle(node).minHeight) || node.clientHeight;
node.style.overflowY = 'auto'; // 'hidden'
node.onchange = node.oninput = function() {
node.style.height = minHeight + 'px';
node.style.height = node.scrollHeight + 'px';
};
});
Это не мерцает в Chrome, результаты могут отличаться в других браузерах, поэтому проверьте.
Я знаю, что это серьезно старый пост - но мой ответ может быть полезен другим в любом случае, так что здесь. Я обнаружил, что если мое определение стиля CSS для contenteditable div имеет минимальную высоту 200 вместо высоты 200, тогда div автоматически масштабируется.
Если вас просто интересует рост, вы можете обновить width
до scrollWidth
, когда изменяется содержимое элемента input
.
document.querySelectorAll('input[type="text"]').forEach(function(node) {
node.onchange = node.oninput = function() {
node.style.width = node.scrollWidth+'px';
};
});
Но это не сжимает элемент.