Giriş alanının genişliğini girişine göre ayarlayın


171
<html>
  <head>
  </head>
  <body>
    <input type="text" value="1" style="min-width:1px;" />
  </body>
</html>

Bu benim kodum ve çalışmıyor. HTML, JavaScript, PHP veya CSS'de minimum genişliği ayarlamanın başka bir yolu var mı?

Dinamik olarak değişen genişliğe sahip bir metin giriş alanı istiyorum, böylece giriş alanı içeriğinin etrafında akıyor. Her girişin yerleşik bir dolgusu vardır 2em, bu sorun ve ikinci sorun ise min-widthgirişte hiç çalışmıyor.

Genişliği tüm program dağınık olduğundan gerekenden daha fazla ayarlarsam, 1px genişliğine ihtiyacım var, sadece gerekirse.


Yanıtlar:


96

Beklentiniz, stilin, metin kutusunun içeriğine göre metin kutusunun genişliğine dinamik olarak uygulanmasıdır. Eğer, böyle bir şey değişen metin kutusu içeriğine çalıştırmak için bazı js gerekir Eğer öyleyse bu :

<input id="txt" type="text" onkeypress="this.style.width = ((this.value.length + 1) * 8) + 'px';">

Not: Bu çözüm yalnızca her karakter tam olarak 8pxgeniş olduğunda çalışır .


41
@Kerc & Tahbaza: evet, ancak bu sadece her karakterin genişliği tam olarak 8 piksel ise işe yarar.
Marcel Korpel

6
Kabul ediyorum, Marcel (ve yayınlanan kod gerçekten bir kullanım için görebileceğiniz bir şey değil) ama istenen davranışı sergiliyor. Yazı tipi, boyut, ağırlık, karakter aralığı vb. Dikkate alınarak oluşturulan metnin gerçek genişliğinin nasıl hesaplanacağını biliyor musunuz? Eğer öyleyse, zaman zaman bu kod yararlı bulacağınız gibi paylaşın lütfen.
Tahbaza

1
- Zaten bunun sadece bir örnek olduğunu düşündüm. Yine de, girdinin genişliğini hesaplamak o kadar zor değil. Cevabıma bir bak.
Marcel Korpel

em birimleri "m" karakterinin genişliğidir. Bu, bir dizenin genişliğini hesaplamak için yararlı olacaktır. Bazı birimlere uygulanan em birimleri ile çapraz tarayıcı sorunları gördüm, ancak test edin.
Archonic

7
PASTE etkinliğini unuttun arkadaşım;) bunu değiştirmelisinonInput
vsync

114

Modern tarayıcı versiyonlarında, CSS ünitesi chde mevcuttur. Anladığım kadarıyla, herhangi bir yazı tipindeki 1chkarakter genişliğine 0(sıfır) eşit olan yazı tipinden bağımsız birimdir .

Böylece, aşağıdaki kadar basit bir şey yeniden boyutlandırma fonksiyonu olarak kullanılabilir:

var input = document.querySelector('input'); // get the input element
input.addEventListener('input', resizeInput); // bind the "resizeInput" callback on "input" event
resizeInput.call(input); // immediately call the function

function resizeInput() {
  this.style.width = this.value.length + "ch";
}
input{ font-size:1.3em; padding:.5em; }
<input>

Bu örnek "elem" değerini ekstra + 2 karakter uzunluğunda yeniden boyutlandıracaktır.


13
Bu yoruma daha fazla oy verilmediği için şaşırdım, çünkü harika bir çözüm ve tarayıcıların yaklaşık% 95'i ( 1 ) bunu destekliyor.
Husky

8
Bu hiç de iyi bir yanıt değildir, çünkü ölçüm doğru değildir ve inputöğe üzerinde oluşabilecek stilleri dikkate almaz font-style, letter-spacingvb. Cevabı canlı bir demo ile düzenledim.
vsync

5
Tek aralıklı yazı tipi kullanırsanız harika çalışır. Diğer yazı tiplerinde, 0 karakterin karakter genişliğini görünüşe göre kullandığı için kilometreniz değişebilir.
Jilles van Gurp

2
Bu gerçekten harika. Rağmen bazen hatalar / bir .karşılaşıldığında beklediğim gibi çalışmıyor .
Rishav

1
Girişteki kutu boyutlandırmayı 'içerik kutusu' olarak ayarlarsanız bu mükemmel çalışır. Bu şekilde, boyutu ayarladığınızda dolgu göz ardı edilir.
Hypersapien

65

Geçerli girişin genişliğini hesaplamak için, onu geçici bir spanöğeye gömmeniz , bu şeyi DOM'ye eklemeniz, scrollWidthözelliği kullanarak hesaplanan genişliği (piksel cinsinden) almanız ve spantekrar kaldırmanız gerekir . Tabii ki aynı yazı tipi ailesinin, yazı tipi boyutunun, vb input.span öğede öğede . Bu yüzden onlara aynı sınıfı verdim.

Ben işlevi ekli keyupolduğu gibi, olayın keypressgirdi karakteri henüz giriş eklenmez valueyanlış genişliği neden olacaktır, bu yüzden. Ne yazık ki, giriş alanının kaydırılmasından nasıl kurtulacağımı bilmiyorum (alanın sonuna karakterler eklerken); kaydırılır, çünkü karakter eklenir ve daha önce gösterilir adjustWidthOfInput(). Ve dediğim gibi, bunu başka bir şekilde yapamam çünkü basılı karakter girilmeden önce giriş alanının değerine sahip olacaksınız . Bu sorunu daha sonra çözmeye çalışacağım.

BTW, bunu sadece Firefox'ta (3.6.8) test ettim, ama umarım anlarsın.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Get/set width of &lt;input&gt;</title>
    <style>
      body {
        background: #666;
      }

      .input-element {
        border: 0;
        padding: 2px;
        background: #fff;
        font: 12pt sans-serif;
      }

      .tmp-element {
        visibility: hidden;
        white-space: pre;
      }
    </style>
  </head>
  <body>
    <input id="theInput" type="text" class="input-element" value="1">
    <script>
      var inputEl = document.getElementById("theInput");

      function getWidthOfInput() {
        var tmp = document.createElement("span");
        tmp.className = "input-element tmp-element";
        tmp.innerHTML = inputEl.value.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
        document.body.appendChild(tmp);
        var theWidth = tmp.getBoundingClientRect().width;
        document.body.removeChild(tmp);
        return theWidth;
      }

      function adjustWidthOfInput() {
        inputEl.style.width = getWidthOfInput() + "px";
      }

      adjustWidthOfInput();
      inputEl.onkeyup = adjustWidthOfInput;
    </script>
  </body>
</html>

Cevabınızı beğendim ve hatta jQuery / Underscore kullanarak uyguladım: gist.github.com/3745941 . Ancak, bazı varsayımlar yapabilirim: (1) herhangi bir karakterin genişliği 14 pikselden fazla değildir, (2) giriş öğesinin öğenin değerinin 14 piksel ötesine uzatılması kabul edilebilir. Bu bir keydown olayına bağlı ve harika çalışıyor!
Nathan

11
Sen eklemek gerekir white-space: pre;css içine bu şekilde: .tmp-element{ visibility: hidden; white-space: pre;}. Aksi takdirde beyaz boşluklar birleştirilir ve genişlik hesaplaması başarısız olur. <input>ve <span>beyaz boşluk işleme ile ilgili farklı davranır, <input>beyaz boşlukları korur ve eklenmezse <span>sıralı beyaz boşlukları bir araya getirir white-space: pre;.
Timo Kähkönen

2
tmp.getBoundingClientRect().widthdaha iyidir tmp.scrollWidth, çünkü bu bazen 0 döndürür
lisak

@lisak Teşekkürler, cevabımı ayarladım, ancak burada daha iyi cevaplar var.
Marcel Korpel

Daha iyi? Ben söylemezdim. İşaretli yanıtın hassasiyeti yoktur, diğerleri (+ burada 1 ve burada 2 ) jQuery kullanır - React yüzünden değil. Canvas size AFAIK metin yüksekliği veremez. Fikir: boşluklarla ilgili sorun ayrıca şu şekilde de çözülebilir:.replace(/ /g, "&nbsp;")
Milan Jaros

30

İşte Lyth'ın cevabını dikkate alan bir değişiklik:

  • silme
  • Bafllatma
  • Yer tutucular

Ayrıca herhangi bir sayıda giriş alanına izin verir! Eylem halinde görmek için: http://jsfiddle.net/4Qsa8/

Senaryo:

$(document).ready(function () {
    var $inputs = $('.resizing-input');

    // Resize based on text if text.length > 0
    // Otherwise resize based on the placeholder
    function resizeForText(text) {
        var $this = $(this);
        if (!text.trim()) {
            text = $this.attr('placeholder').trim();
        }
        var $span = $this.parent().find('span');
        $span.text(text);
        var $inputSize = $span.width();
        $this.css("width", $inputSize);
    }

    $inputs.find('input').keypress(function (e) {
        if (e.which && e.charCode) {
            var c = String.fromCharCode(e.keyCode | e.charCode);
            var $this = $(this);
            resizeForText.call($this, $this.val() + c);
        }
    });

    // Backspace event only fires for keyup
    $inputs.find('input').keyup(function (e) { 
        if (e.keyCode === 8 || e.keyCode === 46) {
            resizeForText.call($(this), $(this).val());
        }
    });

    $inputs.find('input').each(function () {
        var $this = $(this);
        resizeForText.call($this, $this.val())
    });
});

Stil:

.resizing-input input, .resizing-input span {
    font-size: 12px;
    font-family: Sans-serif;
    white-space: pre;
    padding: 5px;
}

HTML:

<div class="resizing-input">
    <input type="text" placeholder="placeholder"/>
    <span  style="display:none"></span>
</div>


Merhaba Michael. Kodunuz harika çalışıyor ancak bir sorunum var. Alanımdan biri Google yer otomatik doldurma alanı. Ve aşağı açılan menüden doğru adresi seçtiğimde, giriş alanının genişliği seçilen adresin uzunluğuna göre değişmez. Bunun için basit bir düzeltme var mı?
Maxence

2
@ changeVeya inputetkinliği dinleyen maksimuma
yeter

Span'ın ekranı ile ilgili sorunlarım vardı: yayılma alanı 0 genişliğe sahip olduğu için hiçbir stil yok. Görüş alanı ile mutlak konumlandırma kullanmak daha iyidir: açıklık için gizlenmiştir.
jayt

Merhaba @yarwest, bahşiş için teşekkürler. Her halükarda, bu komut dosyasıyla orijinal komut dosyasını nasıl değiştireceğinizi biliyor musunuz? (Js / jquery'deki bilgim çok sınırlı)
Maxence

21

İşte çözüm orantısız yazı tipinde olmadan , gerekli javascript sadece çok küçük bir parça kod ile , bilgisayarlı stilleri hesaplamak gerek yok , ve hatta ime desteklemek , destek rtl metinleri .

// copy the text from input to the span
    $(function () {
      $('.input').on('input', function () { $('.text').text($('.input').val()); });
    });
    * {
      box-sizing: border-box;
    }
    
    .container {
      display: inline-block;
      position: relative;
    }
    
    .input,
    .text {
      margin: 0;
      padding: 2px 10px;
      font-size: 24px;
      line-height: 32px;
      border: 1px solid #ccc;
      box-radius: 3px;
      height: 36px;
      font: 20px/20px sans-serif;
      /* font: they should use same font; */
    }

    .text {
      padding-right: 20px;
      display: inline-block;
      visibility: hidden;
      white-space: pre;
    }
    
    .input {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      width: 100%;
    }
    
<script src="https://code.jquery.com/jquery-3.2.0.min.js"></script>

<div class="container">
  <span class="text">
    some text
  </span>
  <input class="input" value="some text" />
</div>

span.textMetnin genişliğine sığdırmak için kullanın ve girişin position: absolutekapsayıcıyla aynı boyutta olmasına izin verin . Giriş değerini spanher değiştiğinde kopyalayın (bu kod parçasını kolayca vanilya js olarak değiştirebilirsiniz). Böylece girdi sadece içeriğinin boyutuna "uyacaktır".


18

NICER GÖRÜNÜMÜ & HİSSETMEK İÇİN

Basılan karakteri elde etmek için jQuery keypress () olayını String.fromCharCode (e.which) ile birlikte kullanmalısınız. Böylece genişliğinizin ne olacağını hesaplayabilirsiniz . Neden? Çünkü çok daha seksi görünecek :)

Keyup olayını kullanan çözümlere kıyasla hoş bir davranışla sonuçlanan bir jsfiddle: http://jsfiddle.net/G4FKW/3/

Aşağıda, bir öğenin inputolayını dinleyen <input>ve spanölçmek için bir kardeşi aynı metin değerine sahip olacak şekilde ayarlayan bir vanilya JS'dir .

document.querySelector('input').addEventListener('input', onInput)

function onInput(){
    var spanElm = this.nextElementSibling;
    spanElm.textContent = this.value; // the hidden span takes the value of the input; 
    this.style.width = spanElm.offsetWidth + 'px'; // apply width of the span to the input
};
/* it's important the input and its span have same styling */
input, .measure {
    padding: 5px;
    font-size: 2.3rem;
    font-family: Sans-serif;
    white-space: pre; /* white-spaces will work effectively */
}

.measure{  
  position: absolute;
  left: -9999px;
  top: -9999px;
}
<input type="text" />
<span class='measure'></span>


1
Güzel görünüyor, ancak Backspace ve Delete'i hesaba katmıyor.
Marcel Korpel

Evet, bunun için keydown etkinliğine ihtiyacınız var. Backspace için özel işlem ekleyebilir ve silebilirsiniz (silmek için e.which === 46, backspace için e.which === 8). Ancak geri kalanı için e.charCode'a erişmek için hala keypress etkinliğine ihtiyacınız var.
Lyth

IE8'i desteklemiyorsanız, e.which'ı kontrol etmek yerine oninput olayını kullanabilirsiniz: developer.mozilla.org/en-US/docs/Web/Events/input
Frinsh

1
Cevabınızı jQuery'yi ortadan kaldırmak ve yalnızca vanilya JS kullanmak için düzenledim. bu çözümün optimal olmaktan uzak olduğunu unutmayın, çünkü spanbunun için a ve css'yi manuel olarak kodlamaya gerek duymayan genel bir çözüm istiyorsunuz .
vsync

17

Bu Açısal özel bir cevaptır, ancak bu benim için çalıştı ve basitliği ve kullanım kolaylığı açısından çok tatmin edici oldu:

<input [style.width.ch]="value.length" [(ngModel)]="value" />

Jani'nin cevabındaki karakter birimleri aracılığıyla otomatik olarak güncellenir .


3
Bu. Dır-dir. Epik.
Daniel Flippance

Ciddi anlamda. Büyülü.
DongBin Kim

13

Bir DIV ve 'contenteditable' özelliği kullanarak bunu çözmenin alternatif bir yolu:

HTML:

<div contenteditable = "true" class = "fluidInput" data-placeholder = ""></div>

CSS: (DIV'ye bazı boyutlar vermek ve görmeyi kolaylaştırmak için)

.fluidInput {

    display         : inline-block;
    vertical-align  : top;

    min-width       : 1em;
    height          : 1.5em;

    font-family     : Arial, Helvetica, sans-serif;
    font-size       : 0.8em;
    line-height     : 1.5em;

    padding         : 0px 2px 0px 2px;
    border          : 1px solid #aaa;
    cursor          : text;
}


.fluidInput * {

    display         : inline;

}


.fluidInput br  {

    display         : none;

}


.fluidInput:empty:before {

    content         : attr(data-placeholder);
    color           : #ccc;

}

Not: Bunu göndermeyi planladığınız bir FORM öğesinin içinde kullanmayı planlıyorsanız, DIV'nin 'değerini' ( .innerHTMLveya .html()sırasıyla) ayrıştırabilmeniz için, gönderme olayını yakalamak için Javascript / jQuery kullanmanız gerekir .


1
Bu daha fazla oyu hak ediyor. Zarif ve basittir (form doğrulamaları için JS kullanmak sizin için sorun değildir).
Daniel Bonnell

3
Ama bu bir girdi değil!
Toni Michel Caubet

8

Bir boyutun boyutunu boyut özelliğini kullanarak da ayarlayabilirsiniz . Bir girişin boyutu, karakterin genişliğini belirler.

Bir girdi, önemli olayları dinleyerek boyutunu dinamik olarak ayarlayabilir.

Örneğin

$("input[type='text']").bind('keyup', function () {
    $(this).attr("size", $(this).val().length );
});

JsFiddle burada


7

Sen böyle bir şey yapabileceğini bu

// HTML
<input id="input" type="text" style="width:3px" />
// jQuery
$(function(){
  $('#input').keyup(function(){
    $('<span id="width">').append( $(this).val() ).appendTo('body');
    $(this).width( $('#width').width() + 2 );
    $('#width').remove();
  });
});


Tuş takımındaki boyutu artırırsanız çirkin bir davranışla sonuçlanacaktır. Giriş, karakterin daha fazla rahatlık için içeri girmesinden hemen önce boyutunu artırmalıdır.
Lyth

5

Sadece diğer cevapların üzerine ekleyerek.

Bugünlerde bazı tarayıcılarda giriş alanının scrollWidth olduğunu fark ettim. Bunun anlamı:

this.style.width = this.scrollWidth + 'px';

güzel çalışmalı. chrome, firefox ve safari'de test edildi.

Silme desteği için önce '= 0' ekleyebilir ve sonra yeniden ayarlayabilirsiniz.

this.style.width = 0; this.style.width = this.scrollWidth + 'px';

3
Lütfen buraya ilgili kodu da ekleyin - bağlantı gelecekte ölmüş olabilir ve bu yazı işe yaramaz.
Uooo

3
Harika çalışıyor, teşekkürler! Bu cevabın neden daha fazla oyu olmadığını bilmiyorum. Bu en basit, daha az çelişkili (js) çözüm.
Form

4

İşte bir JS ve bir jQuery eklentisi işlendiğinde gerçek dize uzunluğunu belirlemek için bir tuval ve yazı tipi boyutu / ailesi kullanarak yeniden boyutlandırma işleyecek yazdı. (yalnızca IE9, krom, safari, firefox, opera ve canvas öğesini uygulayan diğer birçok büyük tarayıcıda çalışır).

PlainJS:

function autoSize(input, o) {
    o || (o = {});
    o.on || (o.on = 'keyup');

    var canvas = document.createElement('canvas');
    canvas.setAttribute('style', 'position: absolute; left: -9999px');
    document.body.appendChild(canvas);

    var ctx = canvas.getContext('2d');

    input.addEventListener(o.on, function () {
        ctx.font = getComputedStyle(this,null).getPropertyValue('font');
        this.style.width = ctx.measureText(this.value + '  ').width + 'px';
    });
}

//Usage
autoSize(document.getElementById('my-input'));

jQuery Eklentisi:

$.fn.autoSize = function(o) {
  o = $.extend({}, {
    on: 'keyup'
  }, o);

  var $canvas = $('<canvas/>').css({position: 'absolute', left: -9999});
  $('body').append($canvas);

  var ctx = $canvas[0].getContext('2d');

  return this.on(o.on, function(){
    var $this = $(this);
    ctx.font = $this.css('font');
    $this.width(ctx.measureText($this.val()).width + 'px');
  })
}

//Usage:
$('#my-input').autoSize();

Not: Bu, metin dönüşümlerini, satır aralığını ve harf aralığını ve muhtemelen diğer bazı metin boyutu değiştirme özelliklerini işlemez. Metin dönüşümü özellik kümesini işlemek ve metin değerini o özelliğe uyacak şekilde ayarlayın. Diğerleri muhtemelen oldukça basittir. Bu biraz çekişmeye başlarsa uygulayacağım ...


4

Yazı tipi tek boşluk bırakıldığında güzel görünen bir yeniden boyutlandırmanın yapılabileceğini belirtmek gerekir, böylece birimi inputkullanarak öğeyi mükemmel bir şekilde yeniden boyutlandırabiliriz ch.

Ayrıca, bu yaklaşımda sadece bir güncelleyerek alanın genişliğini güncelleyebilirsiniz CSS değişkeni ( özel özellik üzerine) inputolay ve biz de zaten önceden doldurulmuş girişinin özen DOMContentLoadedolay

Codepen demosu


Biçimlendirme

<input type="text" value="space mono font" class="selfadapt" />

CSS

:root { --size: 0; }

.selfadapt {
   padding: 5px;
   min-width: 10ch;
   font-family: "space mono";
   font-size: 1.5rem;
   width: calc(var(--size) * 1ch);
}

Bir kök değişken olarak ayarladık --size: 0: bu değişken, girdinin uzunluğunu içerecek 1chve calc()ifadenin içinde ile çarpılacaktır . Varsayılan olarak, bir minimum genişlik de ayarlayabiliriz, ör.10ch

Javascript bölümü, eklenen değerin uzunluğunu okur ve değişkeni günceller --size:

JS

let input = document.querySelector('.selfadapt');
let root  = document.documentElement.style;

/* on input event auto resize the field */
input.addEventListener('input', function() {
   root.setProperty('--size', this.value.length );
});

/* resize the field if it is pre-populated */
document.addEventListener("DOMContentLoaded", function() {
   root.setProperty('--size', input.value.length);
});

Tabii bu hala boşluklu font kullanmayın, ancak bu durumda değiştirmek gerekecektir bile çalışır calc()çarparak formülü --size(o kesinlikle bağımlı olan başka değere göre değişken font-familyve font-sizefarklı) 1ch.


3

Bu yanıt, tarayıcıda bulunan metin genişliğini almanın en doğru yöntemlerinden birini sağlar ve kabul edilen yanıttan daha doğrudur. Tuval html5 öğesini kullanır ve diğer cevapların aksine, öğeyi DOM'ye eklemez ve böylece DOM'ye aşırı eleman eklenmesi nedeniyle ortaya çıkan yeniden akış sorunlarından kaçınır.

Metin öğesiyle ilgili olarak Canvas öğesi hakkında daha fazla bilgiyi buradan edinebilirsiniz .

Not: MDN göre getPropertyValue()yazı tipi gibi yöntemin stenografi sürümleri güvenilmez olabilir. Uyumluluğu artırmak için değerleri tek tek almanızı tavsiye ederim. Burada sadece hız için kullandım.

/**
 * returns the width of child text of any DOM node as a float
 */
function getTextWidth(el) {
  // uses a cached canvas if available
  var canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement("canvas"));
  var context = canvas.getContext("2d");
  // get the full font style property
  var font = window.getComputedStyle(el, null).getPropertyValue('font');
  var text = el.value;
  // set the font attr for the canvas text
  context.font = font;
  var textMeasurement = context.measureText(text);
  return textMeasurement.width;
}

var input = document.getElementById('myInput');
// listen for any input on the input field
input.addEventListener('input', function(e) {
  var width = Math.floor(getTextWidth(e.target));
  // add 10 px to pad the input.
  var widthInPx = (width + 10) + "px";
  e.target.style.width = widthInPx;
}, false);
#myInput {
  font: normal normal 400 normal 18px / normal Roboto, sans-serif;
  min-width: 40px;
}
<input id="myInput" />


2

Yerleşik ng tarzı yönerge kullanarak açısaljlerde daha da basitleştirebilirsiniz .

HTML'nizde:

  <input ng-style="inputStyle(testdata)" ng-model="testdata" />

Kumandanızda:

 $scope.testdata = "whatever";

 $scope.inputStyle = function(str) {
    var charWidth = 7;
    return  {"width": (str.length +1) * charWidth + "px" };
    };

CSS'nizde:

input { font-family:monospace; font-size:12px; }

CharWidth değerini yazı tipinizin genişliğine uyacak şekilde ayarlayın. 12 punto büyüklüğünde 7 gibi görünüyor;


3
Bunu bilmek harika ve kullanışlıdır, ancak bir giriş öğesini dinamik olarak yeniden boyutlandırmak için bir uygulamaya açısaljs eklemek, özellikle OP, "HTML, JavaScript, PHP veya CSS" çözümleri istediğinde gerçekten ciddi bir aşırılıktır. JQuery'nin de bunun için aşırıya kaçmış olduğu iddia edilebilir, ancak - Angular'ın aksine - DOM manipülasyon araç takımı olmak jQuery'nin amacının temelini oluşturur.
vlasits

Yazılan karakterin genişliğini nasıl bilebilirim? Tek boyutlu bir yazı tipi olduğunu varsaymak kolay değil.
Ethan

1
Tek aralıklı yazı tipine ihtiyacınız olamaz ve Angular'a gerek yoktur. brendan'ın cevabı temelde aynı şeyi yapıyor.
Dan Dascalescu

2

Bootstrap kullanıyorsanız, çok kolay bir şekilde yapılabilir:

<div contenteditable="true" class="form-control" style="display: inline"></div>

Formu göndermeden önce div'ın içeriğini getirmeniz ve gizli bir girdiye koymanız yeterlidir.


1

Sanırım min genişlikli CSS özelliğini yanlış yorumluyorsunuz . min-genişlik genellikle bir akışkan düzeninde minimum DOM genişliğini tanımlamak için kullanılır, örneğin:

input {
  width: 30%;
  min-width: 200px;
}

Bu, giriş öğesini minimum 200 piksel genişliğe ayarlayacaktır. Bu bağlamda "px", "piksel" anlamına gelir.

Şimdi, kullanıcı gönderirken giriş alanının en az bir karakter içerdiğinden emin olmak için kontrol etmeye çalışıyorsanız , JavaScript ve PHP ile bazı form doğrulama yapmanız gerekir. Eğer gerçekten yapmaya çalıştığınız buysa, bu cevabı düzenleyeceğim ve size yardımcı olmak için elimden geleni yapacağım.


px ne anlama geldiğini biliyorum ve javascript min-genişlik için bir işlevi olduğunu biliyorum ama giriş metni için çalışmıyor.
Kerc

1
@Kerc: “javascript'in min genişlik için bir işlevi var” - hangisi? Ne demek istiyorsun? - “işe yaramıyor” asla sorunun iyi bir tanımı değildir. Amaçlanan davranış üzerinde durmaya çalışın.
Marcel Korpel

Örneğimi bile denedin mi, 1 piksel olmadığını ve sizinkinin de olmadığını gördünüz. Eğer html, css yazıyor
olsam da

Belki bunun için bir php işlevi var, kimse biliyor mu?
Kerc

Örneğinizi denedim, ancak 1 piksel genişliğinde bir giriş alanının aradığınız şey olmadığını varsaydım . Eğer öyleyse, deneyin<input type="text" value="1" style="width:1px;" />
peterjmag

1

Lyth'ın cevabını gerçekten çok beğendim , ama aynı zamanda şunu yapmasını istedim:

  1. Geri al ve sil
  2. Bitişik bir etiketi manuel olarak eklemenizi gerektirmez.
  3. Minimum genişliği zorlayın.
  4. Belirli bir sınıfa sahip öğelere otomatik olarak uygulanır

Onun JSFiddle uyarlanmış ve ortaya attı bu . Bu kemanda bulunmayan bir gelişme, input.textbox-autosize kuralından başlangıç ​​genişliğini okumak için jQuery CSS Parser gibi bir şey kullanmak ve bunu minWidth olarak kullanmak olacaktır. Doğru sadece bir öznitelik kullanıyorum, bu kompakt bir demo yapar, ancak ideal değildir. çünkü her girdi için ekstra bir özellik gerektirir. Ayrıca JavaScript'te minWidth değerini 100 olarak koymak isteyebilirsiniz.

HTML:

<div id='applicationHost'>
<div>Name:   <input class='textbox-autosize' data-min-width='100' type="text" /></div>
<div>Email:  <input class='textbox-autosize' data-min-width='100' type="email" /></div>
<div>Points: <input class='textbox-autosize' data-min-width='100' type="number" /></div>
</div>

CSS:

#applicationHost {
    font-family: courier;
    white-space: pre;
}

input.textbox-autosize, span.invisible-autosize-helper {
    padding:0;
    font-size:12px;
    font-family:Sans-serif; 
    white-space:pre;
}
input.textbox-autosize {
    width: 100px; /* Initial width of textboxes */
}

/*
In order for the measurements to work out, your input and the invisible
span need to have the same styling.
*/

JavaScript:

$('#applicationHost').on('keyup', '.textbox-autosize', function(e) {
    // Add an arbitary buffer of 15 pixels.
    var whitespaceBuffer = 15;
    var je = $(this);
    var minWidth = parseInt(je.attr('data-min-width'));
    var newVal = je.val();
    var sizingSpanClass = 'invisible-autosize-helper';
    var $span = je.siblings('span.' + sizingSpanClass).first();
    // If this element hasn't been created yet, we'll create it now.
    if ($span.length === 0) {
        $span = $('<span/>', {
            'class': sizingSpanClass,
            'style': 'display: none;'
        });
        je.parent().append($span);
    }
    $span = je.siblings('span').first();
    $span.text(newVal) ; // the hidden span takes 
    // the value of the input
    $inputSize = $span.width();
    $inputSize += whitespaceBuffer;
    if($inputSize > minWidth)
        je.css("width", $inputSize) ; // apply width of the span to the input
    else
        je.css("width", minWidth) ; // Ensure we're at the min width
});

1

Daha iyisi onvalue:

<input id="txt" type="text" onvalue="this.style.width = ((this.value.length + 1) * 8) + 'px';">

Ayrıca yapıştırma, sürükleme ve bırakma vb.


1

İşte benim 2 sentim. Boş bir görünmez div oluşturun. Girdi içeriği ile doldurun ve genişliği girdi alanına döndürün. Her stilde metin stillerini eşleştirin.

$(".answers_number").keyup(function(){
    $( "#number_box" ).html( $( this ).val() );
    $( this ).animate({
        width: $( "#number_box" ).width()+20
        }, 300, function() {
    });
});
#number_box {
   position: absolute;
   visibility: hidden;
   height: auto;
   width: auto;
   white-space: nowrap;
   padding:0 4px;
   /*Your font styles to match input*/
   font-family:Arial;
   font-size: 30px; 
}
    
.answers_number {
   font-size: 30px; 
   font-family:Arial;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number" class="answers_number" />
<div id="number_box">
</div>


1

Oldukça basit:

oninput='this.style.width = (this.scrollWidth - N) + "px";'

N, deneysel olarak belirlenen bir sayıdır (örnekte 2, geliştirdiğim bir şey üzerinde 17).

N'nin çıkarılması, bu garip geniş alanın metin metin kutusunun sonuna gelmeden çok önce birikmesini önler.

Karşılaştırmak. İlk karakterden sonra bile boyutun nasıl değiştiğine dikkat edin .

<p>Subtracting N:</p>    
<input type="text" placeholder="enter lots of text here" oninput='this.style.width = (this.scrollWidth-2) + "px";'>

<p>Not Subtracting N:</p>    
<input type="text" placeholder="enter lots of text here" oninput='this.style.width = (this.scrollWidth) + "px";'>


Ben bu konuda kapsamlı test etmedim, ama sadece değişebilir oninput='this.style.width = (this.scrollWidth-2) + "px";'tarafından oninput='this.style.width = 0; this.style.width = this.scrollWidth + "px";'biriken uzay kurtulmak için
MaxCloutier

0

Sadece nasıl yapılacağını anlamak için biraz zaman harcıyorum.
Aslında bulduğum en basit yol, giriş değerini sembol genişliğini koruyarak giriş değerini girişten hemen önce yaymaktır. Yine de ilk ihtiyacınıza uygun olduğundan emin olamıyorum.
Belki bazı ekstra kod, ancak reaksiyon + akı bazlı uygulamada oldukça doğal bir çözümdür.


0

Michael'ın cevabına dayanarak, jQuery kullanarak kendi versiyonumu oluşturdum. Bence burada çoğu cevabın daha temiz / kısa bir versiyonu ve işi bitirmiş gibi görünüyor.

Ben girdi metni yazmak için bir açıklık kullanarak genişliği sonra almak burada çoğu insanla aynı şeyi yapıyorum. Eylemler sırasında Sonra genişliğini kuruyorum keyupve blurdenir.

İşte çalışan bir kodlama . Bu kod alanı, bunun birden çok giriş alanı ile nasıl kullanılabileceğini gösterir.

HTML Yapısı:

<input type="text" class="plain-field" placeholder="Full Name">
<span style="display: none;"></span>

jQuery:

function resizeInputs($text) {
    var text = $text.val().replace(/\s+/g, ' '),
        placeholder = $text.attr('placeholder'),
        span = $text.next('span');
        span.text(placeholder);
    var width = span.width();

    if(text !== '') {
        span.text(text);
    var width = span.width();
    }

    $text.css('width', width + 5);
};

Yukarıdaki fonksiyon girdi değerini alır, fazladan boşlukları keser ve genişliği elde etmek için metni açıklığa ayarlar. Metin yoksa, bunun yerine yer tutucuyu alır ve bunu yayılma alanına girer. Metni yayılma alanına girdikten sonra girişin genişliğini ayarlar. + 5Genişliğine girdi Kenar Tarayıcıda bir nebze kesti olur çünkü olmadan olmasıdır.

$('.plain-field').each(function() {
    var $text = $(this);
    resizeInputs($text);
});

$('.plain-field').on('keyup blur', function() {
    var $text = $(this);
    resizeInputs($text);
});

$('.plain-field').on('blur', function() {
    var $text = $(this).val().replace(/\s+/g, ' ');
    $(this).val($text);
});

Eğer bu iyileştirilebilseydi, bana bulabileceğim en temiz çözüm olduğu için lütfen bildirin.


0

Neden sadece css kullanmıyorsunuz?

<div id="wrapper">
  <input onkeyup="keyup(event)">
  <div id="ghost"></div>
</div>

function keyup(e) {
	document.getElementById('ghost').innerText = e.target.value;
}
#wrapper {
  position: relative;
  min-width: 30px;
  display: inline-block;
}

input {
  position: absolute;
  left:0;
  right:0;
  border:1px solid blue;
  width: 100%;
}

#ghost {
  color: transparent;
}
<div id="wrapper">
  <input onkeyup="keyup(event)">
  <div id="ghost"></div>
</div>

wrapper {
  position: relative;
  min-width: 30px;
  border: 1px solid red;
  display: inline-block;
}

input {
  position: absolute;
  left:0;
  right:0;
  width: 100%;
}

#ghost {
  color: transparent;
}

Bu kod @Iain Todd tarafından tanıtıldı ve paylaşmam gerektiğini düşündüm


Sadece css değil. Bu sadece başka bir js yöntemidir. İlginç olan.
vatavale

0

Kurşun geçirmez, genel bir yol:

  1. Ölçülen öğenin tüm olası stillerini dikkate alıninput
  2. Ölçümü HTML'yi değiştirmeden herhangi bir girişe uygulayabilme veya

Codepen demosu

var getInputValueWidth = (function(){
  // https://stackoverflow.com/a/49982135/104380
  function copyNodeStyle(sourceNode, targetNode) {
    var computedStyle = window.getComputedStyle(sourceNode);
    Array.from(computedStyle).forEach(key => targetNode.style.setProperty(key, computedStyle.getPropertyValue(key), computedStyle.getPropertyPriority(key)))
  }
  
  function createInputMeassureElm( inputelm ){
    // create a dummy input element for measurements
    var meassureElm = document.createElement('span');
    // copy the read input's styles to the dummy input
    copyNodeStyle(inputelm, meassureElm);
    
    // set hard-coded styles needed for propper meassuring 
    meassureElm.style.width = 'auto';
    meassureElm.style.position = 'absolute';
    meassureElm.style.left = '-9999px';
    meassureElm.style.top = '-9999px';
    meassureElm.style.whiteSpace = 'pre';
    
    meassureElm.textContent = inputelm.value || '';
    
    // add the meassure element to the body
    document.body.appendChild(meassureElm);
    
    return meassureElm;
  }
  
  return function(){
    return createInputMeassureElm(this).offsetWidth;
  }
})();


// delegated event binding
document.body.addEventListener('input', onInputDelegate)

function onInputDelegate(e){
  if( e.target.classList.contains('autoSize') )
    e.target.style.width = getInputValueWidth.call(e.target) + 'px';
}
input{ 
  font-size:1.3em; 
  padding:5px; 
  margin-bottom: 1em;
}

input.type2{
  font-size: 2.5em;
  letter-spacing: 4px;
  font-style: italic;
}
<input class='autoSize' value="type something">
<br>
<input class='autoSize type2' value="here too">


0

Sadece sizeözniteliği ayarlayabilirsiniz . Reaktif çerçevelerden birini kullanıyorsanız, aşağıdakiler yeterli olacaktır:

<input size="{{ yourValue.length }}" [value]="yourValue" />

ancak salt js kullanıyorsanız, olay işleyicileri ayarlamanız gerekir, örneğin:

<input oninput="this.setAttribute('size', this.value.length)" />
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.