อินพุตมาตราส่วนอัตโนมัติ [type = text] เป็นความกว้างของค่า?


87

มีวิธีปรับขนาดความกว้างของ<input type="text">ความกว้างของค่าจริงหรือไม่?

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


คำตอบ:


86

คุณสามารถทำได้ง่ายๆโดยตั้งค่าsizeแอตทริบิวต์เป็นความยาวของเนื้อหาที่ป้อน:

function resizeInput() {
    $(this).attr('size', $(this).val().length);
}

$('input[type="text"]')
    // event handler
    .keyup(resizeInput)
    // resize on page load
    .each(resizeInput);

ดู: http://jsfiddle.net/nrabinowitz/NvynC/

ดูเหมือนว่าจะเพิ่มช่องว่างทางด้านขวาที่ฉันสงสัยว่าขึ้นอยู่กับเบราว์เซอร์ หากคุณต้องการให้อินพุตแน่นมากคุณสามารถใช้เทคนิคเช่นเดียวกับที่ฉันอธิบายในคำตอบที่เกี่ยวข้องนี้โดยใช้ jQuery เพื่อคำนวณขนาดพิกเซลของข้อความของคุณ


23
"ช่องว่างด้านขวา" ไม่ได้ขึ้นอยู่กับเบราว์เซอร์เนื่องจากขนาดขององค์ประกอบถูกระบุเป็นอักขระ แต่สำหรับแบบอักษรจำนวนมากอักขระบางตัวจะมีความกว้างไม่เท่ากัน กรอกข้อมูลในฟิลด์ของคุณด้วย 'iiiiiiiiiii' ในแบบอักษรความกว้างตัวแปรและคุณจะเห็นปัญหาชัดเจนขึ้น
ทำเครื่องหมาย

@Mark - จุดที่ใช้ แต่ส่วนที่ขึ้นอยู่กับเบราว์เซอร์คือการตีความแอตทริบิวต์ "size" - ฉันไม่คิดว่าความกว้างที่แน่นอนจะเป็นมาตรฐานสำหรับเบราว์เซอร์
nrabinowitz

... ลองใช้แบบอักษร monospace แล้วคุณจะเห็นว่ายังมีช่องว่างภายในที่ถูกต้องในบางเบราว์เซอร์: jsfiddle.net/nrabinowitz/NvynC/151
nrabinowitz

@nrabinowitz ดูjsfiddle.net/NvynC/662สำหรับการปรับเปลี่ยนเล็กน้อยที่เพิ่มค่า MAX ซึ่งจำเป็นมากในกรณีส่วนใหญ่
GJ

1
รหัสดีฉันคิดว่าควรใช้Courier Newแบบอักษรสำหรับกล่องข้อความเนื่องจากความกว้างของตัวอักษรทั้งหมดในแบบอักษรนี้เท่ากัน ( jsfiddle.net/NabiKAZ/NvynC/745 )
Nabi KAZ

46

โซลูชันที่เรียบง่าย แต่สมบูรณ์แบบของพิกเซล

ฉันได้เห็นหลายวิธีในการทำเช่นนี้ แต่การคำนวณความกว้างของฟอนต์ไม่ได้ถูกต้อง 100% เสมอไปมันเป็นเพียงค่าประมาณ

ฉันจัดการเพื่อสร้างวิธีที่สมบูรณ์แบบของพิกเซลในการปรับความกว้างอินพุตโดยมีตัวยึดที่ซ่อนอยู่เพื่อวัดจาก


jQuery (แนะนำ)

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


JavaScript บริสุทธิ์

ฉันไม่สามารถระบุได้ว่า jQuery คำนวณความกว้างขององค์ประกอบที่ซ่อนอยู่อย่างไรดังนั้นจึงต้องมีการปรับแต่ง css เล็กน้อยเพื่อรองรับโซลูชันนี้

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>


2
ที่ใช้งานได้ยอดเยี่ยม! ฉันยังอยากทำแบบนั้นโดยไม่มี jQuerry แต่เป็นวานิลลา JS เท่านั้น! นี่คือ jsfiddle พร้อมรหัสด้านบน: jsfiddle.net/kjxdr50a
Night Train

3
@NightTrain ตามคำขอของคุณ เพิ่มโซลูชัน JavaScript =)
DreamTeK

เมื่อเปรียบเทียบทั้งสองโซลูชั่น jQuerry: jsfiddle.net/kjxdr50a/42 JS: jsfiddle.net/kjxdr50a/44ดำเนินการแก้ปัญหา jQuerry ดีขึ้นเล็กน้อยเนื่องจากไม่มีบกพร่อง (ฉันแก้ไขโดยการเพิ่ม 2 พิกเซล) @Obsidian คุณโอเคไหมเมื่อฉันอ้างวิธีแก้ปัญหานี้ในคำถามของฉันมันคล้ายกันมาก?
รถไฟกลางคืน

ขอบคุณสำหรับความช่วยเหลือของคุณ! ในที่สุดฉันก็สามารถติดตั้งลงในแอป Angular ของฉันได้ สาธิตสามารถพบได้บน StackBlitz และคำถามที่ผมถามเกี่ยวกับการตอบสนองการป้อนข้อมูล: stackoverflow.com/a/49478320/9058671 ฉันจะพยายามปรับปรุงโค้ดของฉันและอัปเดตการสาธิต ..
รถไฟกลางคืน

1
คำตอบที่ดีฉันจะเพิ่มสิ่งหนึ่งที่อยู่เหนือ: หากข้อมูลที่คุณป้อนมีช่องว่างภายใน (แน่นอนว่าองค์ประกอบโกสต์hideต้องมีช่องว่างภายในเดียวกัน) height: 0;จะทำงานไม่ถูกต้อง วิธีแก้ปัญหาสำหรับปัญหานี้คือการใช้position: fixed; top: -100vh;คุณสามารถเพิ่มopacity: 0;เพียงเพื่อความปลอดภัย
Kamil Bęben

36

หากด้วยเหตุผลบางประการโซลูชันอื่น ๆ ไม่ได้ผลสำหรับคุณคุณสามารถใช้ contenteditable-span แทนองค์ประกอบอินพุตได้

<span contenteditable="true">dummy text</span>

โปรดทราบว่านี่เป็นการแฮ็กมากกว่าและมีข้อเสียเปรียบอย่างมากในการอนุญาตให้ป้อนข้อมูล HTML ที่ไม่ได้รับการดูแลโดยสิ้นเชิงเช่นการอนุญาตให้ผู้ใช้ป้อน (และวาง) การแบ่งบรรทัดลิงก์และ HTML อื่น ๆ

ดังนั้นคุณอาจไม่ควรใช้วิธีนี้เว้นแต่คุณจะทำความสะอาดอินพุตอย่างระมัดระวัง ...

ปรับปรุง : คุณอาจต้องการที่จะใช้ DreamTeK ของแก้ปัญหาด้านล่าง


1
โซลูชันนี้จะเลื่อนงานไปที่เบราว์เซอร์! ทางออกที่ดีที่สุด!
user2033412

8
ผู้ใช้สามารถวางมากกว่าการแบ่งบรรทัดในเนื้อหาที่แก้ไขได้ เขาสามารถวางรูปภาพ iframes html อะไรก็ได้
CodeToad

2
นอกจากนี้การวางข้อความที่จัดรูปแบบจากโปรแกรมแก้ไขเช่นไฟล์ MS Word หรือ PDF ยังให้ผลลัพธ์ที่ไม่คาดคิดโดยทั่วไปการใช้สิ่งนี้แทนองค์ประกอบอินพุตดั้งเดิมนั้นยากและไม่คุ้มค่า (ยัง)
Senthe

7
นี่เป็นสูตรสำหรับหายนะจริงๆ
Joseph Nields

2
contenteditableมีไว้สำหรับการตั้งค่าโปรแกรมแก้ไขข้อความ WYSIWYG แบบ Rich-text ไม่ใช่สำหรับการปรับขนาดอินพุต
Joseph Nields

10

แก้ไข : ตอนนี้ปลั๊กอินทำงานร่วมกับอักขระช่องว่างต่อท้าย ขอบคุณที่ชี้ให้เห็น @JavaSpyder

เนื่องจากคำตอบอื่น ๆ ส่วนใหญ่ไม่ตรงกับสิ่งที่ฉันต้องการ (หรือไม่ได้ผลเลย) ฉันจึงแก้ไขคำตอบของ Adrian B เป็นปลั๊กอิน jQuery ที่เหมาะสมซึ่งส่งผลให้การปรับขนาดอินพุตที่สมบูรณ์แบบของพิกเซลโดยไม่ต้องให้คุณเปลี่ยน css หรือ html

ตัวอย่าง: https://jsfiddle.net/587aapc2/

การใช้งาน:$("input").autoresize({padding: 20, minWidth: 20, maxWidth: 300});

เสียบเข้าไป:

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


1
วิธีแก้ปัญหาที่ดี แต่ดูเหมือนจะไม่คำนึงถึงช่องว่างต่อท้าย (เพิ่มช่องว่างต่อท้ายจำนวนมากในอินพุต)
SpyderScript

1
โปรดทราบว่ามันใช้ไม่ได้กับ Firefox เนื่องจากfontเป็นชวเลข CSS (FF แปลกไม่สามารถจัดการได้ ) คุณสามารถแก้ไขได้โดยกำหนดในฟังก์ชันแรก: 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(' ');. แล้วเปลี่ยนthis.css('font')เป็น_this_font.
Garrett

@Garrett ขอบคุณมากสำหรับการแก้ไข Firefox คุณช่วยฉันได้มากเวลา
maiko

8

ฉันมีปลั๊กอิน jQuery บน GitHub: https://github.com/MartinF/jQuery.Autosize.Input

มันสะท้อนค่าของอินพุตคำนวณความกว้างและใช้สำหรับกำหนดความกว้างของอินพุต

คุณสามารถดูตัวอย่างสดได้ที่นี่: http://jsfiddle.net/mJMpw/2175/

ตัวอย่างวิธีการใช้งาน (เนื่องจากจำเป็นต้องใช้รหัสบางอย่างเมื่อโพสต์ลิงก์ jsfiddle):

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

คุณเพียงแค่ใช้ css เพื่อตั้งค่า min / max-width และใช้การเปลี่ยนความกว้างหากคุณต้องการเอฟเฟกต์ที่ดี

คุณสามารถระบุช่องว่าง / ระยะทางไปยังจุดสิ้นสุดเป็นค่าในสัญกรณ์ json สำหรับแอตทริบิวต์ data-autosize-input บนองค์ประกอบอินพุต

แน่นอนคุณสามารถเริ่มต้นได้โดยใช้ jQuery

$("selector").autosizeInput();

7

มีคำตอบที่ดีมากมายอยู่แล้วที่นี่ เพื่อความสนุกสนานฉันใช้วิธีแก้ปัญหานี้ด้านล่างโดยอิงจากคำตอบอื่น ๆ และแนวคิดของฉันเอง

<input class="adjust">

องค์ประกอบอินพุตได้รับการปรับพิกเซลให้ถูกต้องและสามารถกำหนดออฟเซ็ตเพิ่มเติมได้

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

การปรับเปลี่ยนจะราบรื่นขึ้นด้วยการเปลี่ยน CSS

.adjust {
    transition: width .15s;
}

นี่คือไวโอลิน ฉันหวังว่านี่จะสามารถช่วยคนอื่น ๆ ที่กำลังมองหาโซลูชันที่สะอาด


4

แทนที่จะพยายามสร้าง div และวัดความกว้างฉันคิดว่าการวัดความกว้างโดยตรงโดยใช้องค์ประกอบ canvas จะน่าเชื่อถือกว่า

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

ตอนนี้คุณสามารถใช้สิ่งนี้เพื่อวัดความกว้างขององค์ประกอบอินพุตบางส่วนในช่วงเวลาใดก็ได้โดยทำสิ่งนี้:

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

สิ่งนี้จะส่งคืนตัวเลข (อาจเป็นทศนิยม) หากคุณต้องการบัญชีสำหรับช่องว่างภายในคุณสามารถลองสิ่งนี้:

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

4

ฉันพบวิธีอื่นสำหรับปัญหานี้ที่ไม่เกี่ยวข้องกับ JS ใน HTML ฉันใส่สิ่งที่ต้องการ:

<div>
  <input class="input" value={someValue} />
  <div class="ghost-input">someValue</div>
</div>

สิ่งที่จำเป็นทั้งหมดคือการตั้งค่าการมองเห็น: ซ่อนอยู่ในอินพุตโกสต์และความกว้าง: 100% ของอินพุตเอง ทำงานได้เนื่องจากอินพุตปรับขนาดเป็น 100% ของคอนเทนเนอร์ซึ่งความกว้างคำนวณโดยเบราว์เซอร์เอง (ขึ้นอยู่กับข้อความเดียวกัน)

หากคุณเพิ่มช่องว่างภายในและเส้นขอบลงในช่องป้อนข้อมูลคุณต้องปรับคลาสอินพุตโกสต์ให้สอดคล้องกัน (หรือใช้ calc () ในคลาสอินพุต)


3

คุณสามารถแก้ปัญหานี้ได้ที่นี่ :) 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');

3

น่าเสียดายที่ sizeแอตทริบิวต์ทำงานได้ไม่ดีนัก จะมีพื้นที่เพิ่มขึ้นและมีพื้นที่น้อยเกินไปในบางครั้งขึ้นอยู่กับวิธีการตั้งค่าแบบอักษร (ดูตัวอย่าง)

หากคุณต้องการให้สิ่งนี้ทำงานได้ดีให้ลองดูการเปลี่ยนแปลงของอินพุตแล้วปรับขนาด คุณอาจต้องการตั้งค่าเป็นอินพุตscrollWidthคุณอาจต้องการที่จะตั้งค่าให้ของการป้อนข้อมูลเราจะต้องพิจารณาขนาดกล่องด้วย

ในตัวอย่างต่อไปนี้ฉันตั้งค่าsizeอินพุตเป็น 1 เพื่อป้องกันไม่ให้มีค่าscrollWidthที่มากกว่าความกว้างเริ่มต้นของเรา (ตั้งค่าด้วยตนเองด้วย 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 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>

ฉันคิดว่าสิ่งนี้ควรใช้งานได้แม้กระทั่ง IE6 แต่อย่าใช้คำพูดของฉัน

คุณอาจต้องผูกฟังก์ชันปรับกับเหตุการณ์อื่นทั้งนี้ขึ้นอยู่กับกรณีการใช้งานของคุณ เช่นการเปลี่ยนค่าของอินพุตโดยทางโปรแกรมหรือเปลี่ยนdisplayคุณสมบัติสไตล์ขององค์ประกอบจากnone(ที่ไหนscrollWidth === 0) เป็นblockหรือinline-blockฯลฯ


1

ปลั๊กอิน jQuery ของฉันใช้ได้กับฉัน:

การใช้งาน:

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

    });

รหัสที่มาของ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']);

ทำไมคุณเริ่มต้นด้วยอัฒภาคในjquery.auto-fit.js ? เหตุใดจึงไม่มีอัฒภาคในบรรทัด "$ this.keydown (method.fit)"
Peter Mortensen

1
@PeterMortensen ขอบคุณสำหรับการตรวจสอบอย่างรอบคอบ ฉันเพิ่มเครื่องหมายอัฒภาคถัดจากบรรทัดที่คุณกล่าวถึงมันหายไปแล้ว สำหรับเซมิโคลอนเริ่มต้นมันเป็นเพียงนิสัยของฉันที่จะหลีกเลี่ยงปัญหาที่เกิดจากไฟล์อื่น ๆ ที่ไม่ได้ลงท้ายด้วยอัฒภาค
Jeff Tian

0

องค์ประกอบอินพุตจะทำงานแตกต่างจากองค์ประกอบอื่น ๆ ซึ่งจะทำในสิ่งที่คุณต้องการหากคุณให้float: left(ดูhttp://jsfiddle.net/hEvYj/5/ ) ฉันไม่คิดว่าจะเป็นไปได้โดยไม่ต้องคำนวณด้วย JavaScript (เช่นเพิ่ม 5px ให้กับความกว้างต่อตัวอักษรในกล่อง)


0

ผู้ใช้nrabinowitzแก้ปัญหา 'คือการทำงานที่ดี แต่ผมใช้เหตุการณ์แทนkeypress keyupซึ่งจะช่วยลดเวลาในการตอบสนองหากผู้ใช้พิมพ์ช้า


การใช้oninput(หรือonpropertychangeสำหรับ IE แบบเดิม) เป็นเหตุการณ์ที่ถูกต้องเนื่องจากตอบสนองต่อสิ่งต่างๆเช่นการวางด้วยการคลิกขวาหรือเลือก "ไฟล์ -> วาง" จากแถบเมนูของเบราว์เซอร์
Joseph Nields

0

นี่คือการปรับเปลี่ยนโซลูชันของnrabinowitzของฉัน ฉันไม่ได้ใช้คุณสมบัติขนาดเพราะมันไม่สมบูรณ์แบบกับฟอนต์ตามสัดส่วนตามที่ @Mark กล่าวไว้ วิธีแก้ปัญหาของฉันวางองค์ประกอบไว้หลังข้อมูลที่คุณป้อนและรับความกว้างที่นับโดยเบราว์เซอร์ (โดยใช้ jQuery)

แม้ว่าฉันจะไม่ได้ทดสอบ แต่ฉันคิดว่ามันจะใช้ได้ก็ต่อเมื่อคุณสมบัติ CSS ทั้งหมดที่มีผลต่อฟอนต์ถูกสืบทอดมา

ความกว้างของอินพุตเปลี่ยนไปตามเหตุการณ์โฟกัสซึ่งทำงานได้ดีกว่าสำหรับฉัน แต่คุณสามารถใช้keyup / keypressเพื่อเปลี่ยนความกว้างของอินพุตเมื่อพิมพ์ได้เช่นกัน

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

0

การใช้ผ้าใบเราสามารถคำนวณความกว้างขององค์ประกอบได้:

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

และใช้ในกิจกรรมที่เลือก:

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

0

ลองใช้โซลูชัน canvas measureText

css:

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

จาวาสคริปต์:

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

0

ฉันแก้ไขความกว้างในการสร้างผืนผ้าใบและคำนวณขนาดของมัน สิ่งสำคัญคือค่าอินพุตและผืนผ้าใบมีคุณสมบัติแบบอักษรเดียวกัน (ตระกูลขนาดน้ำหนัก ... )

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.