змусити поле введення тексту HTML зростати, коли я набираю текст?


81

Я можу встановити початковий розмір введення тексту в css, наприклад:

width: 50px;

Але я хотів би, щоб воно росло, коли я друкую, поки воно не досягне, наприклад, 200 пікселів. Чи можна це зробити у прямому CSS, HTML, бажано без JavaScript?

Звичайно, публікуйте свої рішення js / jquery, але якщо це можливо без них - це буде чудово.

моя спроба тут:

http://jsfiddle.net/jszjz/2/


Я думаю, що це SO-питання допоможе вам: stackoverflow.com/questions/1288297/…
Курт

Для протоколу, не я. Виглядає як слушне запитання, хоч і подібне до того, яке я зв’язав.
Курт

Андре: Постарайтеся, щоб коментарі були конструктивними, будь ласка.
Сет

1
Ви можете використовувати абзац з contenteditable. Це буде розширюватися, коли ви набираєте текст самостійно.
Коста,

Відповіді:


107

Ось приклад, де можна редагувати лише CSS та вміст :

Приклад jsFiddle

CSS

span 
{
    border: solid 1px black;
}
div 
{
    max-width: 200px;   
}

HTML

<div>
    <span contenteditable="true">sdfsd</span>
</div>

4
ТАК. Я щойно спробував його в IE6-9, останній Opera, Firefox та Chrome - і OMG - він працював скрізь!
Stann

4
Для мене в Chrome це розширює елемент вниз на ряд, коли він досягає максимальної ширини. Він також не буде працювати, якщо введення призначено як частина форми.
Пол

5
Для багаторядкового поля введення (власні розриви рядків) замініть spanна div. Зверніть увагу, що word-wrap: break-wordбуде потрібно або слова довші, ніж max-widthпереповнюватимуть поле div: jsfiddle.net/YZPmC/157
CodeManX

6
Переконайтеся, що ви шукаєте небажаний html, який може потрапити в задоволений діапазон за допомогою копіювання та вставлення.
Brian Peacock

3
Це надсилає з формою?
Томаш Зато - відновити Моніку

38

Я щойно написав це для вас, сподіваюся, вам сподобалось :) Ніяких гарантій, що це крос-браузер, але я думаю, що так :)

(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, "&amp;")
                                       .replace(/</g, "&lt;")
                                       .replace(/>/g, "&gt;")
                                       .replace(/"/g, "&quot;")
                                       .replace(/'/g, "&#039;")
                                       .replace(/ /g, '&nbsp;');
            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);
    }
})();

JSFiddle


Дякую за це. Я вирішив зробити це з атрибутом contenteditable, хоча для цього не потрібен js.
Стенн

34
Msgstr "Я щойно написав це для вас". +1 за зусилля :)
Кевін Мартін Хосе

Як я можу дозволити це націлити більше ніж на 1 (4) введення за допомогоюid='adjinput'
learntyler

дуже креативно, мені це подобається
Deryck

2
Це передбачає, що зміни вмісту відбуваються лише за допомогою клавіатури.
заперечення

7

Якщо ви встановите інтервал для відображення: вбудований блок, автоматична горизонтальна та вертикальна зміна розміру працює дуже добре:

<span contenteditable="true" 
      style="display: inline-block;
             border: solid 1px black;
             min-width: 50px; 
             max-width: 200px">
</span>


6

Як щодо програмної модифікації атрибута size на вході?

Семантично (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);
    }
});

http://jsfiddle.net/Vu9ZT/


2
Це не спрацьовує, якщо ви виділяєте текст і натискаєте зворотний простір, оскільки він враховується лише як size-1, а не size- $ ('input'). Val ().
Length

3
Я думаю, що підрахунок value.lengthбув би і простішим, і надійнішим.
Томаш Зато - відновити Моніку

1
Клавіша Delete робить це зростання
Рікка

3

Пам'ятається кілька речей:

Використовуйте onkeydown обробник у текстовому полі, вимірюйте текст * і відповідно збільшуйте розмір текстового поля.

Прикріпити a :focus клас css до вашого текстового поля з більшою шириною. Тоді ваша коробка буде більше при фокусі. Це не зовсім те, про що ви просите, але подібне.

* Виміряти текст у javascript не просто. Перегляньте це питання, щоб отримати кілька ідей.


найкраща відповідь поки. :focus { width: 100% }
oldboy

3

Від: Чи існує плагін авторосту 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, '&amp;').replace(/\s/g,'&nbsp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
                    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);

2

Тут ви можете спробувати щось подібне

РЕДАКТУВАТИ: ПЕРЕГЛЯДОВИЙ ПРИКЛАД (додано одне нове рішення) 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;
}

РЕДАГУВАТИ: Ще одне рішення - набрати користувачеві те, що він хоче, і на розмитті (зосередитися), захопити рядок (з однаковим розміром шрифту), помістити його в div - підрахувати ширину div - а потім за допомогою приємного анімаційного файлу з крутим ефект пом'якшення оновити ширину полів введення Єдиним недоліком є ​​те, що поле введення залишатиметься "маленьким", поки користувач набирає текст. Або ви можете додати тайм-аут :) Ви можете перевірити подібне рішення на скрипці вище!


font-sizeне є ідеальним рішенням. Непогано і, звичайно, не варто голосувати проти, але спробуйте набрати лист iкілька разів, і ви побачите дуже нерівні результати в розмірі. Дивіться мою відповідь, щоб знайти виправлення цього.
Пол

див. другий приклад у моїй скрипті, який не використовує розмір шрифту і вибирає плавність. Перший додано лише для швидкості та швидкості - зберігаючи те, що хотів запитувач. Потрібно створювати до нього доданий до div текст, обчислювати його ширину і т.д.
Pantelis

Я не впевнений, чому, але ваш другий приклад для мене зовсім не змінюється. Також майте на увазі, що моє рішення (яке створює тимчасовий div і таке інше) може працювати в сучасному браузері приблизно 800 разів на секунду на середньому оновленому комп’ютері і, ймовірно, не набагато повільніше, ніж 100 разів на секунду, на 99,5 % комп'ютерів, які використовуються і сьогодні)
Павло,

2

Я знаю, що це серйозно старий пост, але моя відповідь у будь-якому випадку може бути корисна іншим, тому тут йдеться. Я виявив, що якщо моє визначення стилю CSS для вміщуваного div має мінімальну висоту 200 замість висоти 200, тоді div масштабується автоматично.


1

Якщо ви просто зацікавлені в зростанні, ви можете оновити widthдо scrollWidth, при inputзміні вмісту елемента.

document.querySelectorAll('input[type="text"]').forEach(function(node) {
  node.onchange = node.oninput = function() {
    node.style.width = node.scrollWidth+'px';
  };
});

Але це не зменшить стихію.


1

Який підхід ви використовуєте, звичайно, залежить від вашої кінцевої мети. Якщо ви хочете надіслати результати за допомогою форми, тоді використання рідних елементів форми означає, що вам не потрібно використовувати сценарії для надсилання. Крім того, якщо сценарії вимкнено, тоді резервний варіант все одно працює без вигадливих ефектів зростання-зменшення. Якщо ви хочете , щоб отримати простий текст з contenteditable елемента ви завжди можете також використовувати сценарії , як 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, результати можуть відрізнятися в інших браузерах, тому протестуйте.


0

Ось метод, який мені працював. Коли ви вводите в поле, воно поміщає цей текст у прихований проміжок, потім отримує нову ширину та застосовує його до поля введення. Він зростає та зменшується разом із вашим введенням, при цьому захист від введення практично зникає, коли ви стираєте всі введені дані. Перевірено в Chrome. (EDIT: працює в Safari, Firefox та Edge на момент редагування)

function travel_keyup(e)
{
    if (e.target.value.length == 0) return;
    var oSpan=document.querySelector('#menu-enter-travel span');
    oSpan.textContent=e.target.value;
    match_span(e.target, oSpan);
}
function travel_keydown(e)
{
    if (e.key.length == 1)
    {
        if (e.target.maxLength == e.target.value.length) return;
        var oSpan=document.querySelector('#menu-enter-travel span');
        oSpan.textContent=e.target.value + '' + e.key;
        match_span(e.target, oSpan);
    }
}
function match_span(oInput, oSpan)
{
    oInput.style.width=oSpan.getBoundingClientRect().width + 'px';
}

window.addEventListener('load', function()
{
    var oInput=document.querySelector('#menu-enter-travel input');
    oInput.addEventListener('keyup', travel_keyup);
    oInput.addEventListener('keydown', travel_keydown);

    match_span(oInput, document.querySelector('#menu-enter-travel span'));
});
#menu-enter-travel input
{
	width: 8px;
}
#menu-enter-travel span
{
	visibility: hidden;
    position: absolute;
    top: 0px;
    left: 0px;
}
<div id="menu-enter-travel">
<input type="text" pattern="^[0-9]{1,4}$" maxlength="4">KM
<span>9</span>
</div>


0

Якщо вам дозволено використовувати вимірювання ch (монопробіжне), це повністю вирішило те, що я намагався зробити.

onChange(e => {
    e.target.style.width = `${e.target.length}ch`;
})

Це було саме те, що мені потрібно, але я не впевнений, чи працює це для сімейств шрифтів з динамічною шириною.


0

Для тих, хто суворо шукає рішення, яке працює для введення чи тексту, це найпростіше рішення, з яким я стикався. Лише кілька рядків CSS і один рядок JS.

JavaScript встановлює атрибут data- * для елемента, що дорівнює значенню вводу. Вхідні дані встановлюються в сітці CSS, де ця сітка є псевдоелементом, який використовує цей атрибут data- * як свій вміст. Цей вміст розширює сітку до відповідного розміру на основі введеного значення.


0

Все, що вам потрібно зробити, це отримати елемент поля введення, який ви хочете розробити під час набору тексту та в CSS, встановити ширину введення в автоматичне значення та встановити мінімальну ширину, щоб сказати 50px.


Ласкаво просимо до Stack Overflow. Будь ласка, прочитайте Як відповісти. stackoverflow.com/questions/how-to-answer
Ран Марчано
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.