Gibt es eine Möglichkeit, die Breite von a <input type="text">
auf die Breite des tatsächlichen Werts zu skalieren ?
input {
display: block;
margin: 20px;
width: auto;
}
<input type="text" value="I've had enough of these damn snakes, on this damn plane!" />
<input type="text" value="me too" />
Antworten:
Sie können dies auf einfache Weise tun, indem Sie das
size
Attribut auf die Länge des Eingabeinhalts festlegen:function resizeInput() { $(this).attr('size', $(this).val().length); } $('input[type="text"]') // event handler .keyup(resizeInput) // resize on page load .each(resizeInput);
Siehe: http://jsfiddle.net/nrabinowitz/NvynC/
Dies scheint etwas Polsterung auf der rechten Seite hinzuzufügen, von der ich vermute, dass sie vom Browser abhängig ist. Wenn Sie möchten, dass die Eingabe sehr eng ist, können Sie eine Technik wie die in dieser Antwort beschriebene verwenden und mit jQuery die Pixelgröße Ihres Textes berechnen.
quelle
Courier New
Schriftart für das Textfeld, da die Breite aller Zeichen in dieser Schriftart gleich ist. ( jsfiddle.net/NabiKAZ/NvynC/745 )EINFACHE, ABER PIXEL PERFEKTE LÖSUNG
Ich habe verschiedene Möglichkeiten gesehen, dies zu tun, aber die Berechnung der Schriftbreite ist nicht immer 100% genau, sondern nur eine Schätzung.
Ich habe es geschafft, eine pixelgenaue Methode zum Anpassen der Eingabebreite zu erstellen, indem ich einen versteckten Platzhalter zum Messen hatte.
jQuery (empfohlen)
$(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; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <p>Lorem ipsum <span id="hide"></span><input id="txt" type="text" value="type here ..."> egestas arcu. </p>
Reines JavaScript
Ich konnte nicht feststellen, wie jQuery die Breite versteckter Elemente berechnet, sodass eine geringfügige Änderung an CSS erforderlich war, um diese Lösung aufzunehmen.
var hide = document.getElementById('hide'); var txt = document.getElementById('txt'); resize(); txt.addEventListener("input", resize); function resize() { hide.textContent = txt.value; txt.style.width = hide.offsetWidth + "px"; }
body, #txt, #hide { font: inherit; margin: 0; padding: 0; } #txt { border: none; color: #888; min-width: 10px; } #hide { position: absolute; height: 0; overflow: hidden; white-space: pre; }
<p>Lorem ipsum <span id="hide"></span><input id="txt" type="text" value="type here ..."> egestas arcu. </p>
quelle
hide
muss das Ghost-Element dieselbe Auffüllung haben)height: 0;
, funktioniert der Teil nicht richtig. Eine Problemumgehung für dieses Problem wäre die Verwendungposition: fixed; top: -100vh;
. Sie können auch hinzufügenopacity: 0;
, um die Sicherheit zu gewährleisten.Wenn die anderen Lösungen aus irgendeinem Grund für Sie nicht funktionieren, können Sie anstelle eines Eingabeelements eine inhaltsbearbeitbare Spanne verwenden.
<span contenteditable="true">dummy text</span>
Beachten Sie, dass dies eher ein Hack ist und den schwerwiegenden Nachteil hat, dass völlig unbereinigte HTML-Eingaben zulässig sind, z. B. das Eingeben (und Einfügen) von Zeilenumbrüchen, Links und anderem HTML durch Benutzer.
Daher sollten Sie diese Lösung wahrscheinlich nicht verwenden, es sei denn, Sie bereinigen die Eingabe sehr sorgfältig ...
Update : Sie möchten wahrscheinlich die unten stehende DreamTeK- Lösung verwenden .
quelle
contenteditable
dient zum Einrichten eines Rich-Text-WYSIWYG-Texteditors. Nicht zum Ändern der Größe von Eingaben.Bearbeiten : Das Plugin funktioniert jetzt mit nachgestellten Leerzeichen. Vielen Dank für den Hinweis auf @JavaSpyder
Da die meisten anderen Antworten nicht meinen Anforderungen entsprachen (oder einfach überhaupt nicht funktionierten), habe ich die Antwort von Adrian B in ein geeignetes jQuery-Plugin geändert, das zu einer pixelgenauen Skalierung der Eingabe führt, ohne dass Sie CSS oder HTML ändern müssen.
Beispiel: https://jsfiddle.net/587aapc2/
Verwendung:
$("input").autoresize({padding: 20, minWidth: 20, maxWidth: 300});
Plugin:
//JQuery plugin: $.fn.textWidth = function(_text, _font){//get width of text with font. usage: $("div").textWidth(); var fakeEl = $('<span>').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))); }).trigger('input'); return this; } //have <input> resize automatically $("input").autoresize({padding:20,minWidth:40,maxWidth:300});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <input value="i magically resize"> <br/><br/> called with: $("input").autoresize({padding: 20, minWidth: 40, maxWidth: 300});
quelle
font
es sich um eine CSS-Abkürzung handelt (seltsamerweise kann FF damit nicht umgehen ). Sie können dies beheben, indem Sie in der ersten Funktion Folgendes definieren :var _this_font = [this.css('font-style'), this.css('font-variant'), this.css('font-weight'), 'normal', this.css('font-size') + ' / ' + this.css('line-height'), this.css('font-family')].join(' ');
. Dann ändern Sie sichthis.css('font')
zu sein_this_font
.Ich habe ein jQuery-Plugin auf GitHub: https://github.com/MartinF/jQuery.Autosize.Input
Es spiegelt den Wert der Eingabe wider, berechnet die Breite und verwendet sie zum Festlegen der Breite der Eingabe.
Ein Live-Beispiel finden Sie hier: http://jsfiddle.net/mJMpw/2175/
Beispiel für die Verwendung (da beim Posten eines jsfiddle-Links Code benötigt wird):
<input type="text" value="" placeholder="Autosize" data-autosize-input='{ "space": 40 }' /> input[type="data-autosize-input"] { width: 90px; min-width: 90px; max-width: 300px; transition: width 0.25s; }
Sie verwenden einfach CSS, um die minimale / maximale Breite festzulegen, und verwenden einen Übergang für die Breite, wenn Sie einen schönen Effekt erzielen möchten.
Sie können den Abstand / Abstand zum Ende als Wert in json-Notation für das Attribut data-autosize-input für das Eingabeelement angeben.
Natürlich können Sie es auch einfach mit jQuery initialisieren
$("selector").autosizeInput();
quelle
Hier gibt es bereits viele gute Antworten. Zum Spaß habe ich diese Lösung unten implementiert, basierend auf den anderen Antworten und meinen eigenen Ideen.
<input class="adjust">
Das Eingabeelement wird pixelgenau eingestellt und ein zusätzlicher Versatz kann definiert werden.
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 = $('<span id="' + id + '">' + element.val() + '</span>').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, ' ')); // 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);
Die Anpassung wird mit einem CSS-Übergang geglättet.
.adjust { transition: width .15s; }
Hier ist die Geige . Ich hoffe, dies kann anderen helfen, nach einer sauberen Lösung zu suchen.
quelle
Anstatt zu versuchen, ein Div zu erstellen und seine Breite zu messen, ist es meiner Meinung nach zuverlässiger, die Breite direkt mit einem genaueren Canvas-Element zu messen.
function measureTextWidth(txt, font) { var element = document.createElement('canvas'); var context = element.getContext("2d"); context.font = font; return context.measureText(txt).width; }
Jetzt können Sie damit messen, wie breit ein Eingabeelement zu einem beliebigen Zeitpunkt sein soll:
// 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);
Dies gibt eine Zahl zurück (möglicherweise Gleitkomma). Wenn Sie das Auffüllen berücksichtigen möchten, können Sie Folgendes versuchen:
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";
quelle
Sie können dieses Problem wie hier lösen :) http://jsfiddle.net/MqM76/217/
HTML:
<input id="inpt" type="text" /> <div id="inpt-width"></div>
JS:
$.fn.textWidth = function(text, font) { if (!$.fn.textWidth.fakeEl) $.fn.textWidth.fakeEl = $('<span>').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); }).trigger('input');
quelle
Leider
size
funktioniert das Attribut nicht sehr gut. Je nachdem, wie die Schriftart eingerichtet ist, ist manchmal zusätzlicher Speicherplatz und zu wenig Speicherplatz vorhanden. (siehe Beispiel)Wenn dies gut funktionieren soll, suchen Sie nach Änderungen an der Eingabe und ändern Sie die Größe. Sie möchten es wahrscheinlich auf die Eingänge einstellen
scrollWidth
. Wir müssten auch die Größe der Box berücksichtigen.Im folgenden Beispiel setze ich
size
die Eingabe auf 1, um zu verhindern,scrollWidth
dass sie größer als unsere anfängliche Breite ist (manuell mit CSS festgelegt).// (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 trigger 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; }
<label> Resizes: <input class="autoresize" placeholder="this will resize" type='text'> </label> <br/> <label> Doesn't resize: <input placeholder="this will not" type='text'> </label> <br/> <label> Has extra space to right: <input value="123456789" size="9" type="text"/> </label>
Ich denke, das sollte sogar in IE6 funktionieren, aber nimm mein Wort nicht dafür.
Abhängig von Ihrem Anwendungsfall müssen Sie möglicherweise die Anpassungsfunktion an andere Ereignisse binden. ZB das programmgesteuerte Ändern des Werts einer Eingabe oder das Ändern der Stileigenschaft des Elements
display
vonnone
(woscrollWidth === 0
) nachblock
oderinline-block
usw.quelle
Ich habe eine andere Lösung für dieses Problem gefunden, an der JS nicht beteiligt ist. In HTML habe ich einfach so etwas wie:
<div> <input class="input" value={someValue} /> <div class="ghost-input">someValue</div> </div>
Alles, was benötigt wird, ist die Sichtbarkeit festzulegen: bei Ghost-Eingabe ausgeblendet und Breite: 100% bei der Eingabe selbst. Dies funktioniert, weil die Eingabe auf 100% des Containers skaliert wird und die Breite vom Browser selbst berechnet wird (basierend auf demselben Text).
Wenn Sie dem Eingabefeld eine Auffüllung und einen Rand hinzufügen, müssen Sie Ihre Ghost-Eingabeklasse entsprechend anpassen (oder calc () in der Eingabeklasse verwenden).
quelle
Mein jQuery-Plugin funktioniert für mich:
Verwendung:
$('form input[type="text"]').autoFit({ });
Quellcode von
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 = $('<span style="font-size: ' + fontSize + '; padding: 0 ' + padding / 2 + 'px; display: inline-block; position: absolute; visibility: hidden;">' + val + '</span>').insertAfter($this).outerWidth(); $this.width((contentWidth + padding) + 'px'); return $this; } }; $.fn.autoFit = function (options) { if (typeof options == 'string' && 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']);
quelle
Eingabeelemente verhalten sich anders als andere Elemente, die genau das tun, was Sie möchten, wenn Sie sie angeben
float: left
(siehe http://jsfiddle.net/hEvYj/5/ ). Ich denke nicht, dass dies möglich ist, ohne es in irgendeiner Weise mit JavaScript zu berechnen (dh 5px zur Breite pro Buchstabe in der Box hinzufügen).quelle
Die Lösung von User nrabinowitz funktioniert hervorragend, aber ich verwende das
keypress
Ereignis stattdessenkeyup
. Dies verringert die Latenz, wenn der Benutzer langsam tippt.quelle
oninput
(oderonpropertychange
für Legacy-IE) ist das richtige Ereignis, da sie auf Dinge wie das Einfügen mit einem Rechtsklick oder die Auswahl von "Datei -> Einfügen" in der Menüleiste des BrowsersHier ist meine Modifikation der Lösung von nrabinowitz . Ich habe die size- Eigenschaft nicht verwendet , da sie mit proportionalen Schriftarten nicht perfekt ist, wie @Mark feststellte. Meine Lösung platziert ein Element nach Ihrer Eingabe und erhält die Breite, die vom Browser gezählt wird (mithilfe von jQuery).
Obwohl ich es nicht teste, funktioniert es vermutlich nur, wenn alle CSS-Eigenschaften, die sich auf die Schriftart auswirken, vererbt werden.
Die Eingabebreite ändert sich beim Focusout- Ereignis, was für mich besser funktioniert. Sie können aber auch die Tastenkombination verwenden , um die Breite der Eingabe beim Tippen zu ändern.
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 = $("<span>"+content+"</span>").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);
quelle
Mit Canvas konnten wir die Breite der Elemente berechnen:
function getTextWidth(text, fontSize, fontName) { let canvas = document.createElement('canvas'); let context = canvas.getContext('2d'); context.font = fontSize + fontName; return context.measureText(text).width; }
und verwenden Sie es für das ausgewählte Ereignis:
function onChange(e) { let width = getTextWidth(this.value, $(this).css('font-size'), $(this).css('font-family')); $(this.input).css('width', width); }
quelle
Versuchen Sie es mit der Canvas MeasureText-Lösung
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); });
quelle
Ich habe die Breite gelöst, indem ich Leinwand erstellt und deren Größe berechnet habe. Es ist wichtig, dass Eingabewert und Zeichenfläche dieselben Schriftmerkmale aufweisen (Familie, Größe, Gewicht ...).
import calculateTextWidth from "calculate-text-width"; /* requires two props "value" and "font" - defaultFont: normal 500 14px sans-serif */ const defaultText = 'calculate my width' const textFont = 'normal 500 14px sans-serif' const calculatedWidth = calculateTextWidth(defaultText, textFont) console.log(calculatedWidth) // 114.37890625
GitHub: https://github.com/ozluy/calculate-text-width CodeSandbox: https://codesandbox.io/s/calculate-text-width-okr46
quelle