làm cho trường nhập văn bản html phát triển khi tôi nhập?


81

Tôi có thể đặt kích thước đầu vào văn bản ban đầu trong css, như sau:

width: 50px;

Nhưng tôi muốn nó phát triển khi tôi nhập cho đến khi nó đạt 200px, chẳng hạn. Điều này có thể được thực hiện trong css, html thẳng, tốt hơn là không có javascript không?

Tất nhiên, hãy đăng các giải pháp js / jquery của bạn, nhưng nếu điều này có thể thực hiện được mà không có chúng - điều đó thật tuyệt.

thử của tôi ở đây:

http://jsfiddle.net/jszjz/2/


Tôi nghĩ câu hỏi SO này sẽ giúp bạn: stackoverflow.com/questions/1288297/…
Curt

Đối với kỷ lục, không phải là tôi. Có vẻ như một câu hỏi hợp lệ, mặc dù giống với câu hỏi tôi đã liên kết.
Curt

Andre: Hãy cố gắng giữ cho những nhận xét mang tính xây dựng.
Seth

1
Bạn có thể sử dụng một đoạn văn có nội dung phù hợp. Điều đó sẽ mở rộng khi bạn nhập vào chính nó.
Costa

Câu trả lời:


107

Đây là một ví dụ chỉ với CSS và Nội dung có thể chỉnh sửa :

Ví dụ về jsFiddle

CSS

span 
{
    border: solid 1px black;
}
div 
{
    max-width: 200px;   
}

HTML

<div>
    <span contenteditable="true">sdfsd</span>
</div>

4
ĐƯỢC. Tôi vừa thử nó trên IE6-9, Opera, Firefox và Chrome mới nhất - và OMG - nó hoạt động ở mọi nơi!
Stann

4
Đối với tôi trong Chrome, phần tử này kéo dài phần tử xuống một hàng khi nó đạt đến chiều rộng tối đa. Nó cũng sẽ không hoạt động nếu đầu vào dự định là một phần của biểu mẫu.
Paul

5
Đối với trường nhập nhiều dòng (ngắt dòng tùy chỉnh), hãy thay thế spanbằng div. Lưu ý rằng word-wrap: break-wordsẽ là cần thiết hoặc các từ dài hơn max-widthsẽ tràn div hộp: jsfiddle.net/YZPmC/157
CodeManX

6
Đảm bảo rằng bạn loại bỏ html không mong muốn có thể xâm nhập vào khoảng có thể nội dung thông qua sao chép và dán.
Brian Peacock,

3
Điều này có gửi với biểu mẫu không?
Tomáš Zato - Phục hồi Monica

38

Tôi chỉ viết cái này cho bạn, tôi hy vọng bạn thích nó :) Không đảm bảo rằng nó là trình duyệt chéo, nhưng tôi nghĩ nó là vậy :)

(function(){
    var min = 100, max = 300, pad_right = 5, input = document.getElementById('adjinput');

    input.style.width = min+'px';
    input.onkeypress = input.onkeydown = input.onkeyup = function(){
        var input = this;
        setTimeout(function(){
            var tmp = document.createElement('div');
            tmp.style.padding = '0';
            if(getComputedStyle)
                tmp.style.cssText = getComputedStyle(input, null).cssText;
            if(input.currentStyle)
                tmp.style.cssText = input.currentStyle.cssText;
            tmp.style.width = '';
            tmp.style.position = 'absolute';
            tmp.innerHTML = input.value.replace(/&/g, "&amp;")
                                       .replace(/</g, "&lt;")
                                       .replace(/>/g, "&gt;")
                                       .replace(/"/g, "&quot;")
                                       .replace(/'/g, "&#039;")
                                       .replace(/ /g, '&nbsp;');
            input.parentNode.appendChild(tmp);
            var width = tmp.clientWidth+pad_right+1;
            tmp.parentNode.removeChild(tmp);
            if(min <= width && width <= max)
                input.style.width = width+'px';
        }, 1);
    }
})();

JSFiddle


Cảm ơn vì điều này. Tôi đã quyết định làm điều đó với thuộc tính contenteditable mặc dù không yêu cầu js.
Stann

34
"Tôi chỉ viết cái này cho bạn". +1 cho nỗ lực :)
Kevin Martin Jose

Làm thế nào để cho phép điều này để nhắm mục tiêu hơn 1 (4) đầu vào vớiid='adjinput'
teachtyler

rất sáng tạo I love it
Deryck

2
Điều này giả định rằng các thay đổi nội dung chỉ xảy ra bằng cách sử dụng bàn phím.
thúc

6

Làm thế nào về việc sửa đổi theo chương trình thuộc tính kích thước trên đầu vào?

Về mặt ngữ nghĩa (imo), giải pháp này tốt hơn so với giải pháp được chấp nhận vì nó vẫn sử dụng các trường đầu vào để người dùng nhập vào nhưng nó có giới thiệu một chút jQuery. Soundcloud thực hiện điều gì đó tương tự như vậy để gắn thẻ của họ.

<input size="1" />

$('input').on('keydown', function(evt) {
    var $this = $(this),
        size = parseInt($this.attr('size'), 10),
        isValidKey = (evt.which >= 65 && evt.which <= 90) || // a-zA-Z
                     (evt.which >= 48 && evt.which <= 57) || // 0-9
                     evt.which === 32;

    if ( evt.which === 8 && size > 0 ) {
        // backspace
        $this.attr('size', size - 1);
    } else if ( isValidKey ) {
        // all other keystrokes
        $this.attr('size', size + 1);
    }
});

http://jsfiddle.net/Vu9ZT/


2
Đây không phải làm việc nếu bạn đánh dấu văn bản và nhấn phím lùi vì nó chỉ tính là size-1 không size- $ ( 'đầu vào') val () chiều dài..
Abadaba

3
Tôi đoán rằng việc đếm value.lengthsẽ dễ dàng hơn và đáng tin cậy hơn.
Tomáš Zato - Phục hồi Monica

1
Xóa chìa khóa làm cho điều này phát triển
Ricca

6

Nếu bạn đặt khoảng hiển thị: inline-block, tự động thay đổi kích thước ngang và dọc hoạt động rất tốt:

<span contenteditable="true" 
      style="display: inline-block;
             border: solid 1px black;
             min-width: 50px; 
             max-width: 200px">
</span>


3

Một số điều bạn nghĩ đến:

Sử dụng một onkeydowntrình xử lý trong trường văn bản của bạn, đo văn bản * và tăng kích thước hộp văn bản cho phù hợp.

Đính kèm một :focuslớp css vào hộp văn bản của bạn với chiều rộng lớn hơn. Sau đó, hộp của bạn sẽ lớn hơn khi tập trung. Đó không phải là chính xác những gì bạn đang yêu cầu, nhưng tương tự.

* Không đơn giản để đo lường văn bản trong javascript. Kiểm tra câu hỏi này để biết một số ý tưởng.


câu trả lời tốt nhất cho đến nay. :focus { width: 100% }
oldboy

3

Từ: Có plugin jQuery autogrow cho trường văn bản không?


Xem demo tại đây: http://jsbin.com/ahaxe

Các plugin:

(function($){

    $.fn.autoGrowInput = function(o) {

        o = $.extend({
            maxWidth: 1000,
            minWidth: 0,
            comfortZone: 70
        }, o);

        this.filter('input:text').each(function(){

            var minWidth = o.minWidth || $(this).width(),
                val = '',
                input = $(this),
                testSubject = $('<tester/>').css({
                    position: 'absolute',
                    top: -9999,
                    left: -9999,
                    width: 'auto',
                    fontSize: input.css('fontSize'),
                    fontFamily: input.css('fontFamily'),
                    fontWeight: input.css('fontWeight'),
                    letterSpacing: input.css('letterSpacing'),
                    whiteSpace: 'nowrap'
                }),
                check = function() {

                    if (val === (val = input.val())) {return;}

                    // Enter new content into testSubject
                    var escaped = val.replace(/&/g, '&amp;').replace(/\s/g,'&nbsp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
                    testSubject.html(escaped);

                    // Calculate new width + whether to change
                    var testerWidth = testSubject.width(),
                        newWidth = (testerWidth + o.comfortZone) >= minWidth ? testerWidth + o.comfortZone : minWidth,
                        currentWidth = input.width(),
                        isValidWidthChange = (newWidth < currentWidth && newWidth >= minWidth)
                                             || (newWidth > minWidth && newWidth < o.maxWidth);

                    // Animate width
                    if (isValidWidthChange) {
                        input.width(newWidth);
                    }

                };

            testSubject.insertAfter(input);

            $(this).bind('keyup keydown blur update', check);

        });

        return this;

    };

})(jQuery);

2

Ở đây bạn có thể thử một cái gì đó như thế này

CHỈNH SỬA: VÍ DỤ ĐÃ XEM LẠI (đã thêm một giải pháp mới) http://jsfiddle.net/jszjz/10/

Giải thích mã

var jqThis = $('#adjinput'), //object of the input field in jQuery
    fontSize = parseInt( jqThis.css('font-size') ) / 2, //its font-size
    //its min Width (the box won't become smaller than this
    minWidth= parseInt( jqThis.css('min-width') ), 
    //its maxWidth (the box won't become bigger than this)
    maxWidth= parseInt( jqThis.css('max-width') );

jqThis.bind('keydown', function(e){ //on key down
   var newVal = (this.value.length * fontSize); //compute the new width

   if( newVal  > minWidth && newVal <= maxWidth ) //check to see if it is within Min and Max
       this.style.width = newVal + 'px'; //update the value.
});

và css cũng khá đơn giản

#adjinput{
    max-width:200px !important;
    width:40px;
    min-width:40px;
    font-size:11px;
}

CHỈNH SỬA: Một giải pháp khác là yêu cầu người dùng nhập những gì anh ta muốn và làm mờ (lấy nét), lấy chuỗi (có cùng kích thước phông chữ) đặt nó vào một div - đếm chiều rộng của div - và sau đó với một hình ảnh động đẹp mắt hiệu ứng nới lỏng cập nhật chiều rộng trường đầu vào. Hạn chế duy nhất là trường nhập sẽ vẫn "nhỏ" trong khi người dùng nhập. Hoặc bạn có thể thêm thời gian chờ:) bạn cũng có thể kiểm tra một loại giải pháp như vậy trên fiddle ở trên!


font-sizekhông phải là một giải pháp hoàn hảo. Không tệ và chắc chắn không đáng để bỏ phiếu, nhưng hãy thử gõ ký tự ivài lần và bạn sẽ thấy kết quả rất lệch về kích thước. Xem câu trả lời của tôi để biết cách sửa lỗi này.
Paul

xem ví dụ thứ hai trong fiddle của tôi không sử dụng kích thước phông chữ và chọn độ mượt mà. Cái đầu tiên chỉ được thêm vào cho tốc độ và tốc độ - trong khi vẫn duy trì những gì người hỏi muốn. Việc phải tạo một div nối văn bản vào nó, tính toán chiều rộng của nó, v.v ... mỗi lần dường như "nặng" đối với tôi, đối với một điều đơn giản.
Pantelis

Tôi không chắc tại sao, nhưng ví dụ thứ hai của bạn hoàn toàn không thay đổi kích thước đối với tôi. Cũng nên nhớ rằng giải pháp của tôi (Giải pháp tạo div tạm thời và tương tự) có thể chạy khoảng 800 lần mỗi giây trong một trình duyệt hiện đại trên một máy tính cập nhật trung bình và có thể không chậm hơn nhiều so với 100 lần mỗi giây trên 99,5 % máy tính vẫn được sử dụng ngày nay)
Paul

2

Tôi biết đây là một bài đăng cũ nghiêm túc - nhưng dù sao câu trả lời của tôi có thể hữu ích cho những người khác, vì vậy hãy tiếp tục. Tôi thấy rằng nếu định nghĩa kiểu CSS của tôi cho div có thể nội dung có chiều cao tối thiểu là 200 thay vì chiều cao 200, thì div sẽ tự động thay đổi tỷ lệ.


1

Nếu bạn chỉ quan tâm đến việc phát triển, bạn có thể cập nhật widthđến scrollWidth, bất cứ khi nào nội dung của các inputthay đổi phần tử.

document.querySelectorAll('input[type="text"]').forEach(function(node) {
  node.onchange = node.oninput = function() {
    node.style.width = node.scrollWidth+'px';
  };
});

Nhưng điều này sẽ không thu nhỏ phần tử.


1

Tất nhiên, bạn sử dụng cách tiếp cận nào phụ thuộc vào mục tiêu cuối cùng của bạn. Nếu bạn muốn gửi kết quả với một biểu mẫu thì việc sử dụng các phần tử biểu mẫu gốc có nghĩa là bạn không phải sử dụng tập lệnh để gửi. Ngoài ra, nếu kịch bản bị tắt thì dự phòng vẫn hoạt động mà không có các hiệu ứng thu nhỏ ưa thích. Nếu bạn muốn nhận được các văn bản đơn giản ra khỏi một contenteditable yếu tố bạn luôn có thể cũng sử dụng kịch bản như node.textContent để loại bỏ html mà các trình duyệt chèn vào đầu vào người dùng.

Phiên bản này sử dụng các phần tử biểu mẫu gốc với một số cải tiến nhỏ trên một số bài đăng trước đó.

Nó cũng cho phép thu nhỏ nội dung.

Sử dụng điều này kết hợp với CSS để kiểm soát tốt hơn.

<html>

<textarea></textarea>
<br>
<input type="text">


<style>

textarea {
  width: 300px;
  min-height: 100px;
}

input {
  min-width: 300px;
}


<script>

document.querySelectorAll('input[type="text"]').forEach(function(node) {
  var minWidth = parseInt(getComputedStyle(node).minWidth) || node.clientWidth;
  node.style.overflowX = 'auto'; // 'hidden'
  node.onchange = node.oninput = function() {
    node.style.width = minWidth + 'px';
    node.style.width = node.scrollWidth + 'px';
  };
});

Bạn có thể sử dụng thứ gì đó tương tự với các phần tử <textareosystem

document.querySelectorAll('textarea').forEach(function(node) {
  var minHeight = parseInt(getComputedStyle(node).minHeight) || node.clientHeight;
  node.style.overflowY = 'auto'; // 'hidden'
  node.onchange = node.oninput = function() {
    node.style.height = minHeight + 'px';
    node.style.height = node.scrollHeight + 'px';
  };
});

Điều này không nhấp nháy trên Chrome, kết quả có thể khác nhau trên các trình duyệt khác, vì vậy hãy kiểm tra.


0

Đây là một phương pháp phù hợp với tôi. Khi bạn nhập vào trường, nó sẽ đặt văn bản đó vào khoảng ẩn, sau đó lấy chiều rộng mới và áp dụng cho trường nhập. Nó phát triển và thu nhỏ với đầu vào của bạn, với một biện pháp bảo vệ chống lại đầu vào hầu như biến mất khi bạn xóa tất cả đầu vào. Đã thử nghiệm trong Chrome. (CHỈNH SỬA: hoạt động trong Safari, Firefox và Edge tại thời điểm chỉnh sửa này)

function travel_keyup(e)
{
    if (e.target.value.length == 0) return;
    var oSpan=document.querySelector('#menu-enter-travel span');
    oSpan.textContent=e.target.value;
    match_span(e.target, oSpan);
}
function travel_keydown(e)
{
    if (e.key.length == 1)
    {
        if (e.target.maxLength == e.target.value.length) return;
        var oSpan=document.querySelector('#menu-enter-travel span');
        oSpan.textContent=e.target.value + '' + e.key;
        match_span(e.target, oSpan);
    }
}
function match_span(oInput, oSpan)
{
    oInput.style.width=oSpan.getBoundingClientRect().width + 'px';
}

window.addEventListener('load', function()
{
    var oInput=document.querySelector('#menu-enter-travel input');
    oInput.addEventListener('keyup', travel_keyup);
    oInput.addEventListener('keydown', travel_keydown);

    match_span(oInput, document.querySelector('#menu-enter-travel span'));
});
#menu-enter-travel input
{
	width: 8px;
}
#menu-enter-travel span
{
	visibility: hidden;
    position: absolute;
    top: 0px;
    left: 0px;
}
<div id="menu-enter-travel">
<input type="text" pattern="^[0-9]{1,4}$" maxlength="4">KM
<span>9</span>
</div>


0

Nếu bạn được phép sử dụng phép đo ch (monospaced), nó hoàn toàn giải quyết được những gì tôi đang cố gắng làm.

onChange(e => {
    e.target.style.width = `${e.target.length}ch`;
})

Đây chính xác là những gì tôi cần nhưng tôi không chắc liệu nó có hoạt động cho các họ phông chữ có chiều rộng động hay không.


0

Đối với những người đang tìm kiếm một giải pháp phù hợp với đầu vào hoặc vùng văn bản, đây là giải pháp đơn giản nhất mà tôi đã xem qua. Chỉ một vài dòng CSS và một dòng JS.

JavaScript đặt thuộc tính data- * trên phần tử bằng với giá trị của đầu vào. Đầu vào được đặt trong lưới CSS, trong đó lưới đó là một phần tử giả sử dụng thuộc tính data- * đó làm nội dung của nó. Nội dung đó là những gì kéo dài lưới đến kích thước thích hợp dựa trên giá trị đầu vào.


0

Tất cả những gì bạn cần làm là lấy phần tử của trường đầu vào mà bạn muốn phát triển khi nhập và trong CSS, đặt chiều rộng của đầu vào thành tự động và đặt chiều rộng tối thiểu là 50px.


Chào mừng bạn đến với Stack Overflow. Vui lòng đọc Cách trả lời. stackoverflow.com/questions/how-to-answer
Ran Marciano
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.