Mise à l’échelle automatique entrée à la largeur de la valeur?

Y a-t-il un moyen de redimensionner la largeur d’un à la largeur de la valeur réelle?

Vous pouvez le faire facilement en définissant l’atsortingbut size à la longueur du contenu en entrée:

 function resizeInput() { $(this).attr('size', $(this).val().length); } $('input[type="text"]') // event handler .keyup(resizeInput) // resize on page load .each(resizeInput); 

Voir: http://jsfiddle.net/nrabinowitz/NvynC/

Cela semble append un remplissage sur le droit qui, je pense, dépend du navigateur. Si vous voulez que ce soit très serré, vous pouvez utiliser une technique comme celle que je décris dans cette réponse , en utilisant jQuery pour calculer la taille de pixel de votre texte.

Si pour une raison quelconque les autres solutions ne fonctionnent pas pour vous, vous pouvez utiliser un élément contenteditable-span au lieu d’un élément d’entrée.

 dummy text 

Notez qu’il s’agit plus d’un piratage et qu’il présente l’inconvénient majeur de permettre une saisie HTML totalement non-sainte, comme permettre aux utilisateurs d’entrer (et coller) des sauts de ligne, des liens et d’autres éléments HTML.

Donc, vous ne devriez probablement pas utiliser cette solution, sauf si vous désinfectez très soigneusement les données …

Mise à jour : vous souhaitez probablement utiliser la solution Obsidian ci-dessous .

UNE SOLUTION PARFAITE SIMPLE MAIS PIXEL

J’ai vu plusieurs façons de le faire, mais le calcul de la largeur des fonts n’est pas toujours précis à 100%, c’est juste une estimation.

J’ai réussi à créer un pixel parfait pour ajuster la largeur d’entrée en ayant un espace réservé caché à mesurer.


jQuery (recommandé)

 $(function(){ $('#hide').text($('#txt').val()); $('#txt').width($('#hide').width()); }).on('input', function () { $('#hide').text($('#txt').val()); $('#txt').width($('#hide').width()); }); 
 body, #txt, #hide{ font:inherit; margin:0; padding:0; } #txt{ border:none; color:#888; min-width:10px; } #hide{ display:none; white-space:pre; } 
  

Lorem ipsum egestas arcu.

Edit : Le plugin fonctionne maintenant avec les caractères d’espacement finaux. Merci de l’avoir signalé @JavaSpyder

Comme la plupart des autres réponses ne correspondaient pas à ce dont j’avais besoin (ou simplement ne fonctionnaient pas du tout), j’ai modifié la réponse d’Adrian B en un plugin jQuery correct qui permet une mise à l’échelle parfaite des pixels sans devoir modifier votre css ou html.

Exemple: https://jsfiddle.net/587aapc2/

Utilisation: $("input").autoresize({padding: 20, minWidth: 20, maxWidth: 300});

Brancher:

 //JQuery plugin: $.fn.textWidth = function(_text, _font){//get width of text with font. usage: $("div").textWidth(); var fakeEl = $('').hide().appendTo(document.body).text(_text || this.val() || this.text()).css({font: _font || this.css('font'), whiteSpace: "pre"}), width = fakeEl.width(); fakeEl.remove(); return width; }; $.fn.autoresize = function(options){//resizes elements based on content size. usage: $('input').autoresize({padding:10,minWidth:0,maxWidth:100}); options = $.extend({padding:10,minWidth:0,maxWidth:10000}, options||{}); $(this).on('input', function() { $(this).css('width', Math.min(options.maxWidth,Math.max(options.minWidth,$(this).textWidth() + options.padding))); }).sortinggger('input'); return this; } //have  resize automatically $("input").autoresize({padding:20,minWidth:40,maxWidth:300}); 
   

called with: $("input").autoresize({padding: 20, minWidth: 40, maxWidth: 300});

J’ai un plugin jQuery sur GitHub: https://github.com/MartinF/jQuery.Autosize.Input

Il reflète la valeur de l’entrée, calcule la largeur et l’utilise pour définir la largeur de l’entrée.

Vous pouvez voir un exemple en direct ici: http://jsfiddle.net/mJMpw/2175/

Exemple d’utilisation (car du code est nécessaire lors de la publication d’un lien jsfiddle):

  input[type="data-autosize-input"] { width: 90px; min-width: 90px; max-width: 300px; transition: width 0.25s; } 

Vous utilisez simplement css pour définir min / max-width et utilisez une transition sur la largeur si vous voulez un bel effet.

Vous pouvez spécifier l’espace / la distance à la fin comme valeur dans la notation json pour l’atsortingbut data-autosize-input sur l’élément d’entrée.

Bien sûr, vous pouvez aussi simplement l’initialiser en utilisant jQuery

 $("selector").autosizeInput(); 

Il y a déjà beaucoup de bonnes réponses ici. Pour le plaisir, j’ai implémenté cette solution ci-dessous, basée sur les autres réponses et mes propres idées.

  

L’élément d’entrée est ajusté avec une précision de pixel et un décalage supplémentaire peut être défini.

 function adjust(elements, offset, min, max) { // Initialize parameters offset = offset || 0; min = min || 0; max = max || Infinity; elements.each(function() { var element = $(this); // Add element to measure pixel length of text var id = btoa(Math.floor(Math.random() * Math.pow(2, 64))); var tag = $('' + element.val() + '').css({ 'display': 'none', 'font-family': element.css('font-family'), 'font-size': element.css('font-size'), }).appendTo('body'); // Adjust element width on keydown function update() { // Give browser time to add current letter setTimeout(function() { // Prevent whitespace from being collapsed tag.html(element.val().replace(/ /g, '&nbsp')); // Clamp length and prevent text from scrolling var size = Math.max(min, Math.min(max, tag.width() + offset)); if (size < max) element.scrollLeft(0); // Apply width to element element.width(size); }, 0); }; update(); element.keydown(update); }); } // Apply to our element adjust($('.adjust'), 10, 100, 500); 

L'ajustement est adouci par une transition CSS.

 .adjust { transition: width .15s; } 

Voici le violon J'espère que cela peut aider d'autres personnes à la recherche d'une solution propre.

Vous pouvez résoudre ce problème comme ici 🙂 http://jsfiddle.net/MqM76/217/

HTML:

  

JS:

 $.fn.textWidth = function(text, font) { if (!$.fn.textWidth.fakeEl) $.fn.textWidth.fakeEl = $('').hide().appendTo(document.body); $.fn.textWidth.fakeEl.text(text || this.val() || this.text()).css('font', font || this.css('font')); return $.fn.textWidth.fakeEl.width(); }; $('#inpt').on('input', function() { var padding = 10; //Works as a minimum width var valWidth = ($(this).textWidth() + padding) + 'px'; $('#'+this.id+'-width').html(valWidth); $('#inpt').css('width', valWidth); }).sortinggger('input'); 

Malheureusement, l’atsortingbut size ne fonctionnera pas très bien. Il y aura parfois plus d’espace et d’espace, selon la configuration de la police. (consultez l’exemple)

Si vous souhaitez que cela fonctionne correctement, essayez de rechercher les modifications sur l’entrée et redimensionnez-la à ce moment-là. Vous voulez probablement le définir sur scrollWidth l’entrée. Nous devrions également prendre en compte le dimensionnement des boîtes.

Dans l’exemple suivant, je mets la size de l’entrée à 1 pour l’empêcher d’avoir une scrollWidth supérieure à notre largeur initiale (définie manuellement avec CSS).

 // (no-jquery document.ready) function onReady(f) { "complete" === document.readyState ? f() : setTimeout(onReady, 10, f); } onReady(function() { [].forEach.call( document.querySelectorAll("input[type='text'].autoresize"), registerInput ); }); function registerInput(el) { el.size = 1; var style = el.currentStyle || window.getComputedStyle(el), borderBox = style.boxSizing === "border-box", boxSizing = borderBox ? parseInt(style.borderRightWidth, 10) + parseInt(style.borderLeftWidth, 10) : 0; if ("onpropertychange" in el) { // IE el.onpropertychange = adjust; } else if ("oninput" in el) { el.oninput = adjust; } adjust(); function adjust() { // reset to smaller size (for if text deleted) el.style.width = ""; // getting the scrollWidth should sortinggger a reflow // and give you what the width would be in px if // original style, less any box-sizing var newWidth = el.scrollWidth + boxSizing; // so let's set this to the new width! el.style.width = newWidth + "px"; } } 
 * { font-family: sans-serif; } input.autoresize { width: 125px; min-width: 125px; max-width: 400px; } input[type='text'] { box-sizing: border-box; padding: 4px 8px; border-radius: 4px; border: 1px solid #ccc; margin-bottom: 10px; } 
  

Au lieu d’essayer de créer un div et de mesurer sa largeur, je pense qu’il est plus fiable de mesurer directement la largeur à l’aide d’un élément canvas plus précis.

 function measureTextWidth(txt, font) { var element = document.createElement('canvas'); var context = element.getContext("2d"); context.font = font; return context.measureText(txt).width; } 

Maintenant, vous pouvez l’utiliser pour mesurer la largeur de certains éléments en entrée à tout moment:

 // assuming inputElement is a reference to an input element (DOM, not jQuery) var style = window.getComputedStyle(inputElement, null); var text = inputElement.value || inputElement.placeholder; var width = measureTextWidth(text, style.font); 

Cela renvoie un nombre (éventuellement en virgule flottante). Si vous souhaitez comptabiliser le remplissage, vous pouvez essayer ceci:

  var desiredWidth = (parseInt(style.borderLeftWidth) + parseInt(style.paddingLeft) + Math.ceil(width) + 1 + // extra space for cursor parseInt(style.paddingRight) + parseInt(style.borderRightWidth)) inputElement.style.width = desiredWidth + "px"; 

Mon plugin jQuery fonctionne pour moi:

Usage:

  $('form input[type="text"]').autoFit({ }); 

Code source de jquery.auto-fit.js :

 ; (function ($) { var methods = { init: function (options) { var settings = $.extend(true, {}, $.fn.autoFit.defaults, options); var $this = $(this); $this.keydown(methods.fit); methods.fit.call(this, null); return $this; }, fit: function (event) { var $this = $(this); var val = $this.val().replace(' ', '-'); var fontSize = $this.css('font-size'); var padding = $this.outerWidth() - $this.width(); var contentWidth = $('' + val + '').insertAfter($this).outerWidth(); $this.width((contentWidth + padding) + 'px'); return $this; } }; $.fn.autoFit = function (options) { if (typeof options == 'ssortingng' && methods[options] && typeof methods[options] === 'function') { return methods[options].apply(this, Array.prototype.slice.call(arguments, 1)); } else if (typeof options === 'object' || !options) { // Default to 'init' return this.each(function (i, element) { methods.init.apply(this, [options]); }); } else { $.error('Method ' + options + ' does not exist on jquery.auto-fit.'); return null; } }; $.fn.autoFit.defaults = {}; })(this['jQuery']); 

Les éléments d’entrée se comportent différemment des autres éléments, ce qui ferait à peu près ce que vous voulez si vous leur donnez float: left (voir http://jsfiddle.net/hEvYj/5/ ). Je ne pense pas que ce soit possible sans le calculer d’une certaine manière avec JavaScript (c.-à-d. Ajouter 5px à la largeur par lettre dans la boîte).

La solution de l’ utilisateur nrabinowitz fonctionne très bien, mais j’utilise l’événement keyup au lieu du keyup . Cela réduit la latence si l’utilisateur tape lentement.

Voici ma modification de la solution nrabinowitz . Je n’ai pas utilisé la propriété size , car elle n’est pas parfaite avec les fonts proportionnelles comme @Mark l’a noté. Ma solution place un élément après votre saisie et obtient une largeur par navigateur (en utilisant jQuery).

Bien que je ne le teste pas, je suppose que cela ne fonctionnera que si toutes les propriétés CSS affectant la police sont héritées.

La largeur en entrée change lors de l’événement de focusout , ce qui fonctionne mieux pour moi. Mais vous pouvez utiliser keyup / keypress pour changer la largeur de saisie lors de la saisie.

 function resizeInput() { //Firstly take the content or placeholder if content is missing. var content = $(this).val().length > 0 ? $(this).val() : $(this).prop("placeholder"); //Create testing element with same content as input. var widthTester = $(""+content+"").hide(); //Place testing element into DOM after input (so it inherits same formatting as input does). widthTester.insertAfter($(this)); //Set inputs width; you may want to use outerWidth() or innerWidth() //depending whether you want to count padding and border or not. $(this).css("width",widthTester.width()+"px"); //Remove the element from the DOM widthTester.remove(); } $('.resizing-input').focusout(resizeInput).each(resizeInput); 

En utilisant canvas, nous pouvons calculer la largeur des éléments:

 function getTextWidth(text, fontSize, fontName) { let canvas = document.createElement('canvas'); let context = canvas.getContext('2d'); context.font = fontSize + fontName; return context.measureText(text).width; } 

et l’utiliser sur l’événement choisi:

 function onChange(e) { let width = getTextWidth(this.value, $(this).css('font-size'), $(this).css('font-family')); $(this.input).css('width', width); } 

essayez canvas measureText solution

css:

  input{ min-width:10px!important; max-width:99.99%!important; transition: width 0.1s; border-width:1px; } 

javascript:

 function getWidthOfInput(input){ var canvas = document.createElement('canvas'); var ctx = canvas.getContext('2d'); var text = input.value.length ? input.value : input.placeholder; var style = window.getComputedStyle(input); ctx.lineWidth = 1; ctx.font = style.font; var text_width = ctx.measureText(text).width; return text_width; } function resizable (el, factor) { function resize() { var width = getWidthOfInput(el); el.style.width = width + 'px'; } var e = 'keyup,keypress,focus,blur,change'.split(','); for (var i in e){ el.addEventListener(e[i],resize,false); } resize(); } $( "input" ).each( function(i){ resizable(this); });