web-dev-qa-db-fra.com

faire en sorte que le champ de saisie de texte html se développe au fur et à mesure que je tape?

Je peux définir la taille initiale du texte en css, comme ceci:

width: 50px;

Mais je voudrais qu'il grossisse lorsque je tape jusqu'à atteindre, par exemple, 200px . Cela peut-il être fait en css droit, en HTML, de préférence sans JavaScript?

Publiez bien aussi vos solutions js/jquery, mais si cela est possible sans elles, ce sera génial.

mon essai ici:

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

61
Stann

Voici un exemple avec seulement CSS et Content Editable

jsFiddle Exemple

CSS

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

HTML

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

Je viens d'écrire ceci pour vous, j'espère que vous l'aimerez :) Aucune garantie que ce soit multi-navigateur, mais je pense que c'est :)

(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

29
Paulpro

Pourquoi ne pas modifier par programme l'attribut de taille sur l'entrée?

Sémantiquement (imo), cette solution est meilleure que la solution acceptée car elle utilise toujours des champs d’entrée pour l’entrée utilisateur, mais elle introduit un peu de jQuery. Soundcloud fait quelque chose de semblable à ceci pour leur marquage.

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

6
muffs

De: Y at-il un plugin jQuery autogrow pour les champs de texte?


Voir une démo ici: http://jsbin.com/ahaxe

Le plugin:

(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);
3
cmpolis

Si vous définissez l'étendue pour afficher: inline-block, le redimensionnement automatique horizontal et vertical fonctionne très bien:

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

3
lastmjs

Deux choses me viennent à l’esprit: 

Utilisez un gestionnaire onkeydown dans votre champ de texte, mesurez le texte * et augmentez la taille de la zone de texte en conséquence.

Attachez une classe :focus css à votre zone de texte avec une largeur plus grande. Ensuite, votre boîte sera plus grande quand elle sera focalisée. Ce n'est pas exactement ce que vous demandez, mais similaire.

* Mesurer le texte en javascript n'est pas simple. Découvrez cette question pour quelques idées. 

2
Seth

Ici, vous pouvez essayer quelque chose comme ça

EDIT: EXEMPLE RÉVISÉ (ajout d’une nouvelle solution) http://jsfiddle.net/jszjz/10/

Explication du code

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

et le css est assez simple aussi

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

EDIT: Une autre solution est d’avoir l’utilisateur qui tape ce qu’il veut et sur flou (focus out), de saisir la chaîne (dans la même taille de police), de la placer dans un div - compter la largeur du div - puis avec un Nice animé avec un cool L'effet d'accélération met à jour la largeur des champs d'entrée. Le seul inconvénient est que le champ de saisie restera "petit" pendant la saisie de l'utilisateur. Ou vous pouvez ajouter un timeout:) vous pouvez aussi vérifier ce type de solution sur le violon ci-dessus!

2
Pantelis

Je sais que c’est un vieux message sérieusement - Mais ma réponse pourrait de toute façon être utile à d’autres, alors allez-y . une hauteur de 200, la div est automatiquement mise à l’échelle.

1
b0rgBart3

L'approche que vous utilisez dépend, bien entendu, de votre objectif final. Si vous souhaitez soumettre les résultats avec un formulaire, l'utilisation d'éléments de formulaire natifs signifie que vous n'avez pas à utiliser de script pour le soumettre. De plus, si les scripts sont désactivés, la solution de secours fonctionne toujours sans les effets de croissance et de réduction fantaisistes. Si vous souhaitez obtenir le texte brut d'un élément contenteditable , vous pouvez toujours utiliser des scripts tels que node.textContent pour supprimer le code HTML que les navigateurs insèrent dans l'entrée utilisateur.

Cette version utilise des éléments de formulaire natifs avec de légères améliorations sur certains des messages précédents.

Cela permet également de réduire le contenu.

Utilisez ceci en combinaison avec CSS pour un meilleur contrôle.

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

Vous pouvez utiliser quelque chose de similaire avec les éléments <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';
  };
});

Cela ne clignote pas sur Chrome, les résultats peuvent varier sur les autres navigateurs, alors testez.

1
Kevin Douglas

Si vous êtes simplement intéressé par la croissance, vous pouvez mettre à jour width à scrollWidth à chaque fois que le contenu de l'élément input change.

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

Mais cela ne réduira pas l'élément.

0
ceving

Voici une méthode qui a fonctionné pour moi. Lorsque vous tapez dans le champ, il place ce texte dans la plage cachée, puis obtient sa nouvelle largeur et l'applique au champ de saisie. Il augmente et diminue avec votre entrée, avec une protection contre la disparition quasi complète de l'entrée lorsque vous effacez toutes les entrées. Testé en Chrome. (EDIT: fonctionne dans Safari, Firefox et Edge au moment de cette modification)

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
Aaron Mason