czy pole wprowadzania tekstu HTML rośnie w miarę pisania?

81

Mogę ustawić początkowy rozmiar wprowadzania tekstu w css, na przykład:

width: 50px;

Ale chciałbym, żeby rosło, kiedy piszę, aż osiągnie np. 200px. Czy można to zrobić w prostym css, html, najlepiej bez javascript?

Oczywiście publikuj też swoje rozwiązania js / jquery, ale jeśli jest to wykonalne bez nich - to świetnie.

moja próba tutaj:

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

Stann
źródło
Myślę, że to pytanie SO pomoże ci: stackoverflow.com/questions/1288297/ ...
Curt
Dla porządku, to nie ja. Wydaje się, że jest to ważne pytanie, choć podobne do tego, które załączyłem.
Curt
Andre: Postaraj się, aby komentarze były konstruktywne.
Seth
1
Możesz użyć akapitu z treścią do edycji. To rozwinie się, gdy będziesz pisać samodzielnie.
Costa

Odpowiedzi:

107

Oto przykład z tylko CSS i możliwością edycji treści :

jsFiddle Przykład

CSS

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

HTML

<div>
    <span contenteditable="true">sdfsd</span>
</div>
Joe
źródło
4
YAY. Właśnie wypróbowałem to w IE6-9, najnowszej Operze, Firefoksie i Chrome - i OMG - działało wszędzie!
Stann
4
Dla mnie w Chrome powoduje to wydłużenie elementu o wiersz w dół, gdy osiągnie maksymalną szerokość. Nie zadziała również, jeśli dane wejściowe mają być częścią formularza.
Paul
5
W przypadku wielowierszowego pola wejściowego (niestandardowe podziały wierszy) zamień spanna div. Zauważ, że word-wrap: break-wordbędzie to konieczne lub słowa będą dłuższe niż max-widthprzepełnienie pola div: jsfiddle.net/YZPmC/157
CodeManX
6
Upewnij się, że wyszukujesz niechciany kod HTML, który mógłby dostać się do edytowalnego zakresu treści poprzez kopiowanie i wklejanie.
Brian Peacock
3
Czy to jest wysyłane z formularzem?
Tomáš Zato - Przywróć Monikę
38

Właśnie napisałem to dla Ciebie, mam nadzieję, że Ci się spodoba :) Nie ma gwarancji, że jest to cross-browser, ale myślę, że tak jest :)

(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

Paweł
źródło
Dzięki za to. Zdecydowałem się to zrobić z atrybutem contenteditable, który nie wymaga js.
Stann
34
„Właśnie napisałem to dla Ciebie”. +1 za wysiłek :)
Kevin Martin Jose
Jak zezwolić na to, aby kierować więcej niż 1 (4) dane wejściowe za pomocąid='adjinput'
learntyler
bardzo kreatywny, uwielbiam to
Deryck
2
Zakłada się, że zmiany treści następują tylko przy użyciu klawiatury.
ceving
7

Jeśli ustawisz zakres do wyświetlania: inline-block, automatyczna zmiana rozmiaru w poziomie i w pionie działa bardzo dobrze:

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

lastmjs
źródło
6

A co z programową modyfikacją atrybutu rozmiaru na wejściu?

Semantycznie (imo), to rozwiązanie jest lepsze niż przyjęte rozwiązanie, ponieważ nadal używa pól wejściowych do wprowadzania danych przez użytkownika, ale wprowadza trochę jQuery. Soundcloud robi coś podobnego do ich tagowania.

<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/

mufki
źródło
2
To nie działa, jeśli podświetlisz tekst i
naciśniesz klawisz
3
Myślę, że liczenie value.lengthbyłoby łatwiejsze i bardziej wiarygodne.
Tomáš Zato - Przywróć Monikę
1
Usuń klucz sprawia, że ​​rośnie
Ricca
3

Przychodzi mi do głowy kilka rzeczy:

Użyj onkeydown modułu obsługi w polu tekstowym, zmierz tekst * i odpowiednio zwiększ rozmiar pola tekstowego.

Dołącz :focusklasę CSS do pola tekstowego o większej szerokości. Wtedy twoje pudełko będzie większe, gdy będzie skupione. Nie o to dokładnie prosisz, ale podobnie.

* Nie jest łatwo zmierzyć tekst w javascript. Sprawdź to pytanie, aby uzyskać kilka pomysłów.

Seth
źródło
jak dotąd najlepsza odpowiedź. :focus { width: 100% }
oldboy
3

Od: czy istnieje wtyczka autogrow jQuery dla pól tekstowych?


Zobacz demo tutaj: http://jsbin.com/ahaxe

Wtyczka:

(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);
cmpolis
źródło
2

Tutaj możesz spróbować czegoś takiego

EDYCJA: POPRAWIONY PRZYKŁAD (dodano jedno nowe rozwiązanie) http://jsfiddle.net/jszjz/10/

Objaśnienie kodu

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.
});

a css też jest całkiem proste

#adjinput{
    max-width:200px !important;
    width:40px;
    min-width:40px;
    font-size:11px;
}

EDYCJA: Innym rozwiązaniem jest wpisanie przez użytkownika tego, czego chce i rozmycie (wyostrzenie), złapanie ciągu (w tym samym rozmiarze czcionki) i umieszczenie go w div - policz szerokość div - a następnie z ładną animacją efekt łagodzenia zmiany szerokości pól wejściowych. Jedyną wadą jest to, że pole wejściowe pozostanie „małe”, gdy użytkownik pisze. Lub możesz dodać timeout :) możesz też sprawdzić takie rozwiązanie na skrzypcach powyżej!

Pantelis
źródło
font-sizenie jest idealnym rozwiązaniem. Nieźle i na pewno nie warte głosowania w dół, ale spróbuj wpisać literę ikilka razy, a zobaczysz bardzo wypaczone wyniki w rozmiarze. Zobacz moją odpowiedź, aby rozwiązać ten problem.
Paul
zobacz drugi przykład w moich skrzypcach, który nie używa rozmiaru czcionki i wybiera płynność. Pierwsza została dodana tylko ze względu na szybkość i szybkość - przy zachowaniu tego, czego chciał pytający. Konieczność tworzenia elementu div, dołączania do niego tekstu, obliczania jego szerokości itp. Za każdym razem wydaje mi się „ciężka”, jak na coś tak prostego.
Pantelis
Nie jestem pewien, dlaczego, ale twój drugi przykład w ogóle nie zmienia rozmiaru. Należy również pamiętać, że moje rozwiązanie (które tworzy tymczasowy div i tym podobne) może działać około 800 razy na sekundę w nowoczesnej przeglądarce na przeciętnie aktualnym komputerze i prawdopodobnie nie działa dużo wolniej niż 100 razy na sekundę przy 99,5 % komputerów, które są nadal w użyciu)
Paul,
2

Wiem, że to bardzo stary post - ale moja odpowiedź i tak może być przydatna dla innych, więc proszę. Odkryłem, że jeśli moja definicja stylu CSS dla edytowalnego elementu div ma minimalną wysokość 200 zamiast wysokości 200, to element div skaluje się automatycznie.

b0rgBart3
źródło
1

Jeśli jesteś zainteresowany uprawą, możesz zaktualizować widthto scrollWidth, gdy tylko zawartość inputelementu się zmieni.

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

Ale to nie zmniejszy elementu.

ceving
źródło
1

To, które podejście zastosujesz, zależy oczywiście od tego, jaki jest Twój końcowy cel. Jeśli chcesz przesłać wyniki za pomocą formularza, użycie natywnych elementów formularza oznacza, że ​​nie musisz używać skryptów do przesyłania. Ponadto, jeśli skrypty są wyłączone, funkcja rezerwowa nadal działa bez wymyślnych efektów kurczenia się. Jeśli chcesz uzyskać zwykłego tekstu z pomocą contentEditable elementu zawsze można też użyć włączony jak node.textContent rozebrać się html że przeglądarek wstawić do danych wprowadzonych przez użytkownika.

Ta wersja używa natywnych elementów formularza z drobnymi poprawkami w niektórych poprzednich postach.

Pozwala również zmniejszyć zawartość.

Użyj tego w połączeniu z CSS dla lepszej kontroli.

<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';
  };
});

Możesz użyć czegoś podobnego z elementami <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';
  };
});

To nie migocze w Chrome, wyniki mogą się różnić w innych przeglądarkach, więc przetestuj.

Kevin Douglas
źródło
0

Oto metoda, która działała dla mnie. Kiedy piszesz w polu, umieszcza ten tekst w ukrytym zakresie, a następnie pobiera nową szerokość i stosuje ją do pola wejściowego. Rośnie i kurczy się wraz z wprowadzeniem danych, a zabezpieczenie przed praktycznie zniknięciem danych wejściowych po usunięciu wszystkich danych wejściowych. Przetestowano w Chrome. (EDYCJA: działa w Safari, Firefox i Edge w czasie tej edycji)

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>

Aaron Mason
źródło
0

Jeśli możesz użyć pomiaru ch (o stałej szerokości), całkowicie rozwiązało to, co próbowałem zrobić.

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

To było dokładnie to, czego potrzebowałem, ale nie jestem pewien, czy działa to w przypadku rodzin czcionek o dynamicznej szerokości.

jscul
źródło
0

Dla tych, surowo patrząc na rozwiązanie, które umożliwia dostęp na wejściu lub textarea, to jest najprostsze rozwiązanie Ja natknąłem. Tylko kilka linii CSS i jedna linia JS.

JavaScript ustawia atrybut data- * na elemencie równym wartości wejścia. Dane wejściowe są ustawiane w siatce CSS, gdzie ta siatka jest pseudoelementem używającym atrybutu data- * jako swojej zawartości. Ta zawartość jest tym, co rozciąga siatkę do odpowiedniego rozmiaru na podstawie wartości wejściowej.

Chen W
źródło
0

Wszystko, co musisz zrobić, to pobrać element pola wejściowego, który chcesz powiększać podczas pisania i CSS, ustawić szerokość wejścia na auto i ustawić minimalną szerokość na 50 pikseli.

Anthony Rosario
źródło
Witamy w Stack Overflow. Przeczytaj artykuł Jak odpowiedzieć. stackoverflow.com/questions/how-to-answer
Ran Marciano