Sesuaikan lebar bidang input ke inputnya

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

Ini kode saya dan tidak berfungsi. Apakah ada cara lain dalam HTML, JavaScript, PHP atau CSS untuk menetapkan lebar minimum?

Saya ingin bidang input teks dengan lebar yang berubah secara dinamis, sehingga bidang input mengalir di sekitar isinya. Setiap input memiliki built-in padding 2em, itulah masalahnya dan masalah kedua adalah bahwa min-widthtidak bekerja pada input sama sekali.

Jika saya mengatur lebar lebih dari yang dibutuhkan daripada keseluruhan program berantakan, saya membutuhkan lebar 1px, lebih hanya jika diperlukan.

Kerc
sumber
Apakah ini menjawab pertanyaan Anda? Membuat textarea dengan mengubah ukuran otomatis
DreamTeK

Jawaban:

96

Kedengarannya seperti harapan Anda adalah bahwa gaya diterapkan secara dinamis ke lebar kotak teks berdasarkan pada isi kotak teks. Jika demikian, Anda akan memerlukan beberapa js untuk berjalan pada perubahan isi kotak teks, sesuatu seperti ini :

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

Catatan: solusi ini hanya berfungsi ketika setiap karakter persis 8pxlebar.

Tahbaza
sumber
41
@Kerc & Tahbaza: ya, tetapi ini hanya akan berfungsi jika lebar setiap karakter tepat 8 piksel.
Marcel Korpel
6
Saya setuju, Marcel (dan kode yang diposting bukan sesuatu yang bisa saya lihat benar-benar digunakan) tetapi menunjukkan perilaku yang diinginkan. Apakah Anda tahu cara menghitung lebar sebenarnya dari teks yang dirender dengan mempertimbangkan font, ukuran, berat, kerning, dll.? Jika demikian, silakan bagikan karena saya akan menemukan sedikit kode berguna pada kesempatan.
Tahbaza
1
- Saya sudah berpikir bahwa itu hanya sebuah contoh. Meskipun begitu, tidak sulit untuk menghitung lebar input. Lihatlah jawaban saya.
Marcel Korpel
unit em adalah lebar karakter "m". Ini akan berguna untuk menghitung lebar string. Saya telah melihat masalah lintas-browser dengan unit em yang diterapkan pada beberapa atribut, jadi lakukan pengujian.
Archonic
7
Anda lupa acara PASTE, teman saya;) Anda harus mengubahnya keonInput
vsync
114

Dalam versi browser modern, unit CSS chjuga tersedia. Menurut pemahaman saya, ini adalah unit font-independent, di mana 1chsama dengan lebar karakter0 (nol) di setiap font yang diberikan.

Dengan demikian, sesuatu yang sesederhana berikut ini dapat digunakan sebagai fungsi ukuran:

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>

Contoh itu akan mengubah ukuran "elem" menjadi panjang nilai + 2 karakter ekstra.

Jani Jalkala
sumber
13
Saya terkejut komentar ini tidak dipilih lebih tinggi, karena ini adalah solusi hebat dan sekitar 95% ( 1 ) browser mendukung ini.
Husky
8
Ini bukan jawaban yang baik sama sekali, karena pengukurannya tidak akurat dan tidak memperhitungkan gaya akun yang mungkin terjadi pada inputelemen, seperti font-style, letter-spacingdan sebagainya. Saya telah mengedit jawabannya dengan demo langsung.
vsync
5
Berfungsi bagus jika Anda menggunakan font monospace. Dengan font lain, jarak tempuh Anda mungkin beragam karena menggunakan lebar karakter 0 karakter.
Jilles van Gurp
2
Ini sangat bagus. Meskipun perhatikan bahwa kadang-kadang bug keluar / tidak berfungsi seperti yang saya harapkan ketika .ditemukan.
Rishav
1
Ini berfungsi dengan baik jika Anda mengatur ukuran kotak pada input ke 'kotak konten'. Dengan begitu ia mengabaikan bantalan saat Anda mengatur ukuran.
Hypersapien
65

Untuk menghitung lebar input saat ini, Anda harus menanamkannya dalam spanelemen sementara , lampirkan hal itu ke DOM, dapatkan lebar yang dihitung (dalam piksel) menggunakan scrollWidthproperti dan hapus spanlagi. Tentu saja Anda harus memastikan bahwa keluarga font yang sama, ukuran font, dll, digunakan di dalam inputdan dispan elemen. Karena itu saya menugaskan kelas yang sama kepada mereka.

Saya melampirkan fungsi ke keyupacara tersebut, karena pada keypresskarakter input belum ditambahkan ke input value, sehingga akan menghasilkan lebar yang salah. Sayangnya, saya tidak tahu cara menyingkirkan pengguliran bidang input (saat menambahkan karakter ke akhir bidang); itu bergulir, karena karakter ditambahkan dan ditampilkan sebelum adjustWidthOfInput()dipanggil. Dan, seperti yang saya katakan, saya tidak bisa melakukan ini dengan cara sebaliknya karena Anda akan memiliki nilai field input sebelum karakter yang ditekan dimasukkan. Saya akan mencoba menyelesaikan masalah ini nanti.

BTW, saya hanya menguji ini di Firefox (3.6.8), tetapi Anda akan mengerti intinya, saya harap.

<!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>
Marcel Korpel
sumber
Saya menyukai jawaban Anda dan bahkan menerapkannya menggunakan jQuery / Underscore: gist.github.com/3745941 . Namun, saya dapat membuat asumsi tertentu: (1) lebar karakter apa pun tidak lebih dari 14px, (2) dapat diterima untuk memiliki elemen input memperpanjang 14px melebihi nilai elemen. Saya memiliki ini terlampir pada acara keydown dan ini bekerja dengan baik!
Nathan
11
Anda harus menambahkan white-space: pre;ke css cara ini: .tmp-element{ visibility: hidden; white-space: pre;}. Jika tidak, spasi putih digabungkan dan penghitungan lebar gagal. <input>dan <span>berperilaku berbeda terkait penanganan ruang putih, <input>mempertahankan ruang putih dan <span>menggabungkan ruang putih berurutan menjadi satu jika white-space: pre;tidak ditambahkan.
Timo Kähkönen
2
tmp.getBoundingClientRect().widthlebih baik daripada tmp.scrollWidth, karena kadang-kadang mengembalikan 0
lisak
@lisak Terima kasih, saya menyesuaikan jawaban saya, tetapi sudah ada jawaban yang lebih baik di sini.
Marcel Korpel
Lebih baik? Saya tidak akan mengatakannya. Jawaban yang ditandai tidak memiliki presisi, yang lain (+ di sini 1 dan di sini 2 ) menggunakan jQuery - saya tidak melakukannya karena Bereaksi. Kanvas tidak dapat memberi Anda ketinggian teks AFAIK. Gagasan: masalah dengan ruang dapat juga diselesaikan dengan:.replace(/ /g, "&nbsp;")
Milan Jaros
30

Berikut ini modifikasi jawaban Lyth yang memperhitungkan:

  • Penghapusan
  • Inisialisasi
  • Placeholder

Ini juga memungkinkan sejumlah bidang input! Untuk melihatnya beraksi: http://jsfiddle.net/4Qsa8/

Naskah:

$(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())
    });
});

Gaya:

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

Michael
sumber
Hai @Michael. Kode Anda berfungsi dengan baik tetapi saya memiliki masalah. Salah satu bidang saya adalah bidang autocmplete Google place. Dan ketika saya memilih alamat yang benar dari menu yang jatuh, lebar bidang input tidak berubah sesuai dengan panjang alamat yang dipilih. Apakah ada perbaikan sederhana untuk itu?
Maxence
2
@Maxence mendengarkan changeatau inputacara tersebut sudah cukup
yarwest
Saya memiliki masalah dengan tampilan rentang: tidak ada gaya karena terdaftar rentang memiliki 0 lebar. Lebih baik menggunakan penentuan posisi absolut dengan visibilitas: tersembunyi untuk rentang tersebut.
jayt
Hai @yarwest, terima kasih atas tipnya. Bagaimana pun Anda tahu cara men-tweak skrip asli dengan pengaturan ini? (Pengetahuan saya tentang Js / jquery sangat terbatas)
Maxence
21

Ini adalah solusi tanpa font monospace yang diperlukan, dengan hanya kode potongan javascript yang sangat kecil , tidak perlu menghitung gaya yang dikomputasi , dan, bahkan mendukung ime , mendukung teks rtl .

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

Menggunakan span.text untuk menyesuaikan lebar teks, dan biarkan ukuran input sama dengan position: absolutekontainer. Salin nilai input ke spansetiap kali itu berubah (Anda dapat dengan mudah mengubah kode ini menjadi vanilla js). Jadi input hanya akan "sesuai" dengan ukuran kontennya.

tsh
sumber
18

UNTUK MENCARI NICER & MERASA

Anda harus menggunakan jQuery keypress () event dalam kombinasi dengan String.fromCharCode (e.which) untuk mendapatkan karakter yang ditekan. Oleh karena itu Anda dapat menghitung apa yang lebar Anda akan . Mengapa? Karena itu akan terlihat jauh lebih seksi :)

Berikut ini adalah jsfiddle yang menghasilkan perilaku yang baik dibandingkan dengan solusi yang menggunakan acara keyup: http://jsfiddle.net/G4FKW/3/

Di bawah ini adalah vanilla JS yang mendengarkan inputacara <input>elemen dan mengatur spansaudara kandung untuk memiliki nilai teks yang sama untuk mengukurnya.

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>

Tidur
sumber
1
Terlihat bagus, tetapi tidak memperhitungkan Backspace dan Hapus.
Marcel Korpel
Ya, untuk ini Anda perlu acara keydown. Anda dapat menambahkan penanganan spesifik untuk backspace dan menghapus dengan melakukannya (e.which === 46 untuk delete, e.which === 8 untuk backspace). Tetapi Anda masih perlu acara penekanan tombol untuk memiliki akses ke e.charCode untuk yang lainnya.
Lyth
Jika Anda tidak mendukung IE8, Anda dapat menggunakan acara oninput alih-alih memeriksa e.yang: developer.mozilla.org/en-US/docs/Web/Events/input
Frinsh
1
Saya telah mengedit jawaban Anda untuk menghilangkan jQuery dan hanya menggunakan vanilla JS. keberatan bahwa solusi ini jauh dari optimal karena Anda menginginkan solusi generik yang tidak melibatkan pengkodean secara manual spandan css untuknya.
vsync
17

Ini adalah jawaban khusus sudut, tetapi ini bekerja untuk saya dan telah sangat memuaskan dalam hal kesederhanaan dan kemudahan penggunaan:

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

Secara otomatis memperbarui melalui unit karakter dalam jawaban Jani .

Chris Vandevelde
sumber
3
Ini. Adalah. Epik.
Daniel Flippance
Serius. Gaib.
DongBin Kim
13

Berikut ini cara alternatif untuk menyelesaikan masalah ini menggunakan DIV dan properti 'dapat diedit':

HTML:

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

CSS: (untuk memberi DIV beberapa dimensi dan membuatnya lebih mudah dilihat)

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

}

Catatan: Jika Anda berencana untuk menggunakan ini di dalam elemen FORMULIR yang Anda rencanakan untuk dikirim, Anda harus menggunakan Javascript / jQuery untuk menangkap acara pengiriman sehingga Anda dapat menguraikan 'nilai' ( .innerHTMLatau .html()masing - masing) dari DIV.

logic8
sumber
1
Ini layak mendapatkan lebih banyak suara positif. Ini elegan dan sederhana (selama menggunakan JS untuk validasi formulir bukan masalah bagi Anda).
Daniel Bonnell
3
Tapi itu bukan input!
Toni Michel Caubet
8

Anda dapat mengatur lebar input menggunakan atribut ukuran juga. Ukuran input menentukan lebar karakter.

Sebuah input dapat secara dinamis menyesuaikan ukurannya dengan mendengarkan acara utama.

Sebagai contoh

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

JsFiddle di sini

brendan
sumber
7

Anda bisa melakukan sesuatu seperti ini

// 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();
  });
});

Dasi
sumber
Jika Anda menambah ukuran pada keyup itu akan menghasilkan perilaku yang buruk. Input perlu menambah ukurannya tepat sebelum karakter masuk ke dalamnya agar lebih nyaman.
Lyth
5

Cukup tambahkan di atas jawaban lain.

Saya perhatikan bahwa saat ini di beberapa browser bidang input memiliki scrollWidth. Yang berarti:

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

harus bekerja dengan baik. diuji dalam chrome, firefox dan safari.

Untuk dukungan penghapusan, Anda dapat menambahkan '= 0' terlebih dahulu dan kemudian menyesuaikan kembali.

this.style.width = 0; this.style.width = this.scrollWidth + 'px';
orang mograbi
sumber
3
Silakan tambahkan kode yang relevan di sini juga - tautannya mungkin mati di masa depan dan kemudian tulisan ini tidak berguna.
Uooo
3
Ini bekerja dengan baik, terima kasih! Saya tidak tahu mengapa jawaban ini tidak memiliki lebih banyak suara positif. Sejauh ini, ini adalah solusi (js) yang paling sederhana dan tidak dibikin.
Formulir
4

Berikut ini adalah JS sederhana dan plugin jQuery yang saya tulis yang akan menangani pengubahan ukuran elemen input menggunakan kanvas dan ukuran font / keluarga untuk menentukan panjang string aktual saat dirender. (hanya berfungsi di> IE9, chrome, safari, firefox, opera dan sebagian besar browser utama lainnya yang telah mengimplementasikan elemen kanvas).

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

Plugin jQuery:

$.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();

Catatan: ini tidak akan menangani transformasi teks, spasi baris dan spasi huruf, dan mungkin beberapa properti perubahan ukuran teks lainnya. Untuk menangani set properti transformasi-teks dan sesuaikan nilai teks agar sesuai dengan properti itu. Yang lain mungkin cukup lurus ke depan. Saya akan menerapkan jika ini mulai mendapatkan beberapa daya tarik ...

newms87
sumber
4

Perlu dicatat bahwa ukuran yang terlihat bagus dapat dilakukan ketika font monospace, jadi kita dapat dengan sempurna mengubah ukuran inputelemen menggunakan chunit.

Juga dalam pendekatan ini kita dapat memperbarui lebar bidang dengan hanya memperbarui variabel CSS ( properti khusus ) pada inputacara dan kita juga harus menjaga input yang sudah diisi sebelumnya pada DOMContentLoadedacara

Demo codepen


Markup

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

Sebagai variabel root yang kami tetapkan --size: 0: variabel ini akan berisi panjang input dan akan dikalikan dengan 1chdi dalam calc()ekspresi. Secara default kita juga bisa mengatur min-width, mis10ch

Bagian Javascript membaca panjang nilai yang dimasukkan dan memperbarui variabel --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);
});

tentu saja ini masih berfungsi bahkan jika Anda tidak menggunakan font monospace, tetapi dalam hal ini Anda perlu mengubah calc()rumus dengan mengalikan --sizevariabel dengan nilai lain (yang sangat bergantung pada font-familydan font-size) berbeda dari 1ch.

Fabrizio Calderan
sumber
3

Jawaban ini memberikan salah satu metode paling akurat untuk mengambil lebar teks yang tersedia di browser dan lebih akurat daripada jawaban yang diterima. Ia menggunakan elemen kanvas html5 dan tidak seperti jawaban lain tidak menambahkan elemen ke DOM dan dengan demikian menghindari masalah reflow yang disebabkan oleh terlalu banyak menambahkan elemen ke DOM.

Baca lebih lanjut tentang elemen Canvas di sini terkait dengan lebar teks.

CATATAN: Menurut MDN versi steno dari getPropertyValue()metode seperti font bisa tidak dapat diandalkan. Saya akan merekomendasikan untuk mendapatkan nilai secara tunggal untuk meningkatkan kompatibilitas. Saya hanya menggunakannya di sini untuk kecepatan.

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

Matthew Brent
sumber
2

Anda dapat melakukannya dengan lebih mudah di sudut menggunakan direktif gaya bawaan.

Di html Anda:

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

Di controller Anda:

 $scope.testdata = "whatever";

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

Di css Anda:

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

Sesuaikan karakter untuk mencocokkan lebar font Anda. Tampaknya menjadi 7 dengan ukuran font 12px;

michieljoris
sumber
3
Ini keren dan mudah untuk diketahui, tetapi menambahkan angularjs ke aplikasi untuk secara dinamis mengubah ukuran elemen input benar-benar serius terutama ketika OP meminta solusi "HTML, JavaScript, PHP atau CSS". Orang bisa berargumen bahwa jQuery terlalu berlebihan untuk ini, tetapi - tidak seperti Angular - menjadi DOM-manipulation toolkit adalah inti dari tujuan jQuery.
vlasits
Bagaimana saya bisa tahu lebar karakter yang diketik? Tidak mudah untuk menganggap itu adalah font berukuran mono.
Ethan
1
Anda tidak dapat memerlukan font monospace, dan tidak perlu untuk Angular. jawaban brendan pada dasarnya sama.
Dan Dascalescu
2

Jika Anda menggunakan Bootstrap, itu bisa dilakukan dengan sangat mudah:

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

Anda hanya perlu mengambil konten div dan memasukkannya ke dalam input tersembunyi sebelum mengirimkan formulir.

Alexey Kosov
sumber
1

Saya pikir Anda salah mengartikan properti CSS min-width . min-width umumnya digunakan untuk menentukan lebar DOM minimum dalam tata letak fluida, seperti:

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

Itu akan mengatur elemen input ke lebar minimum 200 piksel. Dalam konteks ini, "px" adalah singkatan dari "piksel".

Sekarang, jika Anda mencoba memeriksa untuk memastikan bahwa bidang input berisi setidaknya satu karakter ketika pengguna mengirimkannya, Anda harus melakukan beberapa validasi formulir dengan JavaScript dan PHP. Jika memang itu yang ingin Anda lakukan, saya akan mengedit jawaban ini dan melakukan yang terbaik untuk membantu Anda.

peterjmag
sumber
saya tahu apa arti px dan saya tahu javascript memiliki fungsi untuk min-width tetapi tidak berfungsi untuk input teks.
Kerc 2-10
1
@Kerc: "javascript memiliki fungsi untuk min-width" - yang mana? Maksud kamu apa? - “itu tidak berfungsi” tidak pernah merupakan deskripsi masalah yang baik. Cobalah untuk menguraikan perilaku yang dimaksud.
Marcel Korpel
Apakah Anda bahkan mencoba contoh saya, daripada Anda melihat bahwa itu tidak 1 px dan Anda juga tidak. Ini tidak akan bekerja tidak masalah jika saya menulisnya dalam html, css
Kerc
Mungkin ada fungsi php untuk ini, ada yang tahu?
Kerc 2-10
Saya memang mencoba contoh Anda, tetapi saya berasumsi bahwa bidang input selebar 1 piksel bukan yang Anda cari. Jika ya, coba<input type="text" value="1" style="width:1px;" />
peterjmag
1

Saya sangat menyukai jawaban Lyth , tetapi juga sangat menginginkannya:

  1. Tangani backspace dan hapus
  2. Tidak mengharuskan Anda menambahkan tag yang berdekatan secara manual.
  3. Terapkan lebar minimum.
  4. Secara otomatis diterapkan ke elemen dengan kelas tertentu

Saya mengadaptasi JSFiddle-nya dan muncul dengan ini . Salah satu peningkatan yang tidak ada dalam biola ini adalah menggunakan sesuatu seperti Parser CSS jQuery untuk benar-benar membaca lebar awal dari aturan input.textbox-autosize, dan menggunakannya sebagai minWidth. Benar saya hanya menggunakan atribut pada, yang membuat untuk demo yang ringkas tetapi tidak ideal. karena memerlukan atribut tambahan pada setiap input. Anda mungkin juga hanya ingin menempatkan minWidth sebagai 100 tepat di JavaScript.

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
});
Josh
sumber
1

Lebih baik adalah onvalue:

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

Ini juga melibatkan menempel, menyeret dan menjatuhkan, dll.

Łukasz Polowczyk
sumber
1

Ini 2 sen saya. Buat div tak terlihat kosong. Isi dengan konten input dan kembalikan lebar ke bidang input. Cocokkan gaya teks antara setiap kotak.

$(".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>

Thomas Byy
sumber
1

Cukup sederhana:

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

Di mana N adalah angka (2 dalam contoh, 17 pada sesuatu yang saya kembangkan) yang ditentukan secara eksperimental.

Mengurangkan N mencegah ruang ekstrenuous aneh ini mengakumulasi jauh sebelum teks mencapai akhir kotak teks.

Membandingkan. Perhatikan bagaimana perubahan ukuran bahkan setelah karakter pertama.

<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";'>

Dan T
sumber
Saya belum diuji secara luas dengan ini, tetapi Anda bisa saja mengganti oninput='this.style.width = (this.scrollWidth-2) + "px";'dengan oninput='this.style.width = 0; this.style.width = this.scrollWidth + "px";'menyingkirkan ruang yang terakumulasi
MaxCloutier
0

Saya hanya menghabiskan waktu mencari tahu bagaimana melakukannya.
Sebenarnya cara paling sederhana yang saya temukan adalah untuk memindahkan nilai input ke span sebelum input, menjaga lebar simbol input 1. Meskipun saya tidak yakin itu cocok untuk kebutuhan awal Anda.
Mungkin beberapa kode tambahan, tetapi dalam bereaksi + aplikasi berbasis fluks itu solusi yang cukup alami.

freele
sumber
0

Berdasarkan jawaban Michael, saya telah membuat versi saya sendiri menggunakan jQuery. Saya pikir ini adalah versi yang lebih bersih / lebih pendek dari sebagian besar jawaban di sini dan tampaknya menyelesaikan pekerjaan.

Saya melakukan hal yang sama seperti kebanyakan orang di sini dengan menggunakan rentang untuk menulis teks input kemudian mendapatkan lebar. Kemudian saya mengatur lebar ketika tindakan keyupdan blurdipanggil.

Ini adalah codepen yang berfungsi . Codepen ini menunjukkan bagaimana ini dapat digunakan dengan beberapa bidang input.

Struktur HTML:

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

Fungsi di atas mendapatkan nilai input, memangkas ruang ekstra dan mengatur teks ke dalam rentang untuk mendapatkan lebar. Jika tidak ada teks, alih-alih mendapatkan placeholder dan memasukkannya ke dalam rentang. Setelah memasukkan teks ke dalam rentang itu kemudian mengatur lebar input. The + 5pada lebar adalah karena tanpa bahwa input akan memotong sedikit di Edge Browser.

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

Jika ini bisa diperbaiki tolong beri tahu saya karena ini adalah solusi terbersih yang bisa saya buat.

Matius
sumber
0

Mengapa tidak menggunakan css saja?

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

kode ini diperkenalkan oleh @Iain Todd dan saya pikir saya harus membagikannya

Milad
sumber
Bukan hanya css. Ini hanyalah metode js. Satu yang menarik.
vatavale
0

Cara umum anti peluru harus:

  1. Mempertimbangkan semua gaya yang mungkin dari inputelemen yang diukur
  2. Mampu menerapkan pengukuran pada input apa pun tanpa memodifikasi HTML atau

Demo codepen

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

vsync
sumber
0

Anda bisa mengatur sizeatribut. Jika Anda menggunakan salah satu kerangka kerja reaktif, berikut ini akan cukup:

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

tetapi jika Anda menggunakan js murni, Anda harus mengatur penangan acara, seperti:

<input oninput="this.setAttribute('size', this.value.length)" />
akim lyubchenko
sumber