Как автоизмерить текстовую область с помощью Прототипа?

Как отметил @FelixKling, наиболее вероятным сценарием является то, что узлы, которые вы ищете, еще не существуют.

Однако современные методы разработки часто могут манипулировать элементами документа за пределами дерева документов либо с DocumentFragments, либо просто отсоединением / повторным подключением текущих элементов напрямую. Такие методы могут использоваться как часть шаблонов JavaScript или для предотвращения чрезмерных операций перерисовки / переплавки, в то время как элементы, о которых идет речь, сильно изменяются.

Аналогично, новая функциональность «Теневой DOM» развертывается в современных браузерах позволяет элементам быть частью документа, но не обрабатываться запросом document.getElementById и всеми его методами sibling (querySelector и т. д.). Это делается для инкапсуляции функциональных возможностей и, в частности, скрыть его.

Опять же, скорее всего, элемент, который вы ищете, просто (пока) в документе, и вы должны сделать, как предлагает Феликс , Тем не менее, вы также должны знать, что это все чаще является не единственной причиной того, что элемент может быть необоснованным (временно или постоянно).

115
задан Nandini Venkateshan 3 January 2019 в 06:54
поделиться

11 ответов

Facebook делает это, когда Вы пишете на стенах людей, но только изменяет размеры вертикально.

Горизонтальный изменяют размеры, кажется мне, путаницей, из-за перехода на новую строку, длинные линии, и так далее, но вертикальный изменяют размеры, кажется, довольно безопасен и хорош.

Ни один из новичков использования Facebook, которых я знаю, ничего никогда не упоминал об этом или смущался. Я использовал бы это в качестве неподтвержденной информации, чтобы сказать 'разрешение, реализовать его'.

Некоторый код JavaScript, чтобы сделать это, с помощью Прототип (потому что это - то, что я знаком с):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <script src="http://www.google.com/jsapi"></script>
        <script language="javascript">
            google.load('prototype', '1.6.0.2');
        </script>
    </head>

    <body>
        <textarea id="text-area" rows="1" cols="50"></textarea>

        <script type="text/javascript" language="javascript">
            resizeIt = function() {
              var str = $('text-area').value;
              var cols = $('text-area').cols;

              var linecount = 0;
              $A(str.split("\n")).each( function(l) {
                  linecount += Math.ceil( l.length / cols ); // Take into account long lines
              })
              $('text-area').rows = linecount + 1;
            };

            // You could attach to keyUp, etc. if keydown doesn't work
            Event.observe('text-area', 'keydown', resizeIt );

            resizeIt(); //Initial on load
        </script>
    </body>
</html>

пз: Очевидно, этот код JavaScript очень наивен и не хорошо протестированный, и Вы, вероятно, не хотите использовать его на текстовых полях с романами в них, но Вы в общих чертах понимаете.

73
ответ дан Peter Mortensen 24 November 2019 в 02:25
поделиться

Просто пересмотрев это, я сделал его немного более опрятным (хотя кто-то, кто полная бутылка на Прототип / JavaScript, мог предложить улучшения?).

var TextAreaResize = Class.create();
TextAreaResize.prototype = {
  initialize: function(element, options) {
    element = $(element);
    this.element = element;

    this.options = Object.extend(
      {},
      options || {});

    Event.observe(this.element, 'keyup',
      this.onKeyUp.bindAsEventListener(this));
    this.onKeyUp();
  },

  onKeyUp: function() {
    // We need this variable because "this" changes in the scope of the
    // function below.
    var cols = this.element.cols;

    var linecount = 0;
    $A(this.element.value.split("\n")).each(function(l) {
      // We take long lines into account via the cols divide.
      linecount += 1 + Math.floor(l.length / cols);
    })

    this.element.rows = linecount;
  }
}

Просто это звонит с:

new TextAreaResize('textarea_id_name_here');
3
ответ дан Peter Mortensen 24 November 2019 в 02:25
поделиться

Вот другая техника для автокалибровки текстовой области.

  • пиксельная высота Использования вместо высоты строки: более точная обработка строки переносится, если пропорциональный шрифт используется.
  • Принимает или идентификатор или элемент, как введено
  • , Принимает дополнительный максимальный параметр высоты - полезный, если Вы скорее не позволили текстовой области вырасти вне определенного размера (сохраните все это на экране, постарайтесь не повреждать расположение, и т.д.)
  • Протестированный на Firefox 3 и Internet  Explorer  6

Код: (простая ваниль JavaScript)

function FitToContent(id, maxHeight)
{
   var text = id && id.style ? id : document.getElementById(id);
   if (!text)
      return;

   /* Accounts for rows being deleted, pixel value may need adjusting */
   if (text.clientHeight == text.scrollHeight) {
      text.style.height = "30px";
   }

   var adjustedHeight = text.clientHeight;
   if (!maxHeight || maxHeight > adjustedHeight)
   {
      adjustedHeight = Math.max(text.scrollHeight, adjustedHeight);
      if (maxHeight)
         adjustedHeight = Math.min(maxHeight, adjustedHeight);
      if (adjustedHeight > text.clientHeight)
         text.style.height = adjustedHeight + "px";
   }
}

Демонстрация: (использует jQuery, цели на текстовой области, в которую я ввожу прямо сейчас - если Вы имеете установленный Firebug, вставьте оба образца в консоль и тест на этой странице)

$("#post-text").keyup(function()
{
   FitToContent(this, document.documentElement.clientHeight)
});
38
ответ дан Peter Mortensen 24 November 2019 в 02:25
поделиться

I needed this function for myself, but none of the ones from here worked as I needed them.

So I used Orion's code and changed it.

I added in a minimum height, so that on the destruct it does not get too small.

function resizeIt( id, maxHeight, minHeight ) {
    var text = id && id.style ? id : document.getElementById(id);
    var str = text.value;
    var cols = text.cols;
    var linecount = 0;
    var arStr = str.split( "\n" );
    $(arStr).each(function(s) {
        linecount = linecount + 1 + Math.floor(arStr[s].length / cols); // take into account long lines
    });
    linecount++;
    linecount = Math.max(minHeight, linecount);
    linecount = Math.min(maxHeight, linecount);
    text.rows = linecount;
};
2
ответ дан 24 November 2019 в 02:25
поделиться

Вот Прототип версия изменения размера текстовой области, которая не зависит от количества столбцов в текстовой области. Это превосходный метод, поскольку он позволяет вам управлять текстовой областью с помощью CSS, а также иметь текстовую область переменной ширины. Кроме того, в этой версии отображается количество оставшихся символов. Хотя это и не запрашивается, это довольно полезная функция, которую легко удалить, если она не нужна.

//inspired by: http://github.com/jaz303/jquery-grab-bag/blob/63d7e445b09698272b2923cb081878fd145b5e3d/javascripts/jquery.autogrow-textarea.js
if (window.Widget == undefined) window.Widget = {}; 

Widget.Textarea = Class.create({
  initialize: function(textarea, options)
  {
    this.textarea = $(textarea);
    this.options = $H({
      'min_height' : 30,
      'max_length' : 400
    }).update(options);

    this.textarea.observe('keyup', this.refresh.bind(this));

    this._shadow = new Element('div').setStyle({
      lineHeight : this.textarea.getStyle('lineHeight'),
      fontSize : this.textarea.getStyle('fontSize'),
      fontFamily : this.textarea.getStyle('fontFamily'),
      position : 'absolute',
      top: '-10000px',
      left: '-10000px',
      width: this.textarea.getWidth() + 'px'
    });
    this.textarea.insert({ after: this._shadow });

    this._remainingCharacters = new Element('p').addClassName('remainingCharacters');
    this.textarea.insert({after: this._remainingCharacters});  
    this.refresh();  
  },

  refresh: function()
  { 
    this._shadow.update($F(this.textarea).replace(/\n/g, '<br/>'));
    this.textarea.setStyle({
      height: Math.max(parseInt(this._shadow.getHeight()) + parseInt(this.textarea.getStyle('lineHeight').replace('px', '')), this.options.get('min_height')) + 'px'
    });

    var remaining = this.options.get('max_length') - $F(this.textarea).length;
    this._remainingCharacters.update(Math.abs(remaining)  + ' characters ' + (remaining > 0 ? 'remaining' : 'over the limit'));
  }
});

Создайте виджет, вызвав new Widget.Textarea ('element_id') . Параметры по умолчанию можно переопределить, передав их в виде объекта, например new Widget.Textarea ('element_id', {max_length: 600, min_height: 50}) . Если вы хотите создать его для всех текстовых полей на странице, сделайте что-нибудь вроде:

Event.observe(window, 'load', function() {
  $$('textarea').each(function(textarea) {
    new Widget.Textarea(textarea);
  });   
});
8
ответ дан 24 November 2019 в 02:25
поделиться

Вот расширение виджета Prototype, которое Джереми опубликовал 4 июня:

Оно не позволяет пользователю вводить больше символов, если вы используете ограничения в текстовых областях. Он проверяет, остались ли символы. Если пользователь копирует текст в текстовое поле, текст обрезается по максимуму. length:

/**
 * Prototype Widget: Textarea
 * Automatically resizes a textarea and displays the number of remaining chars
 * 
 * From: http://stackoverflow.com/questions/7477/autosizing-textarea
 * Inspired by: http://github.com/jaz303/jquery-grab-bag/blob/63d7e445b09698272b2923cb081878fd145b5e3d/javascripts/jquery.autogrow-textarea.js
 */
if (window.Widget == undefined) window.Widget = {}; 

Widget.Textarea = Class.create({
  initialize: function(textarea, options){
    this.textarea = $(textarea);
    this.options = $H({
      'min_height' : 30,
      'max_length' : 400
    }).update(options);

    this.textarea.observe('keyup', this.refresh.bind(this));

    this._shadow = new Element('div').setStyle({
      lineHeight : this.textarea.getStyle('lineHeight'),
      fontSize : this.textarea.getStyle('fontSize'),
      fontFamily : this.textarea.getStyle('fontFamily'),
      position : 'absolute',
      top: '-10000px',
      left: '-10000px',
      width: this.textarea.getWidth() + 'px'
    });
    this.textarea.insert({ after: this._shadow });

    this._remainingCharacters = new Element('p').addClassName('remainingCharacters');
    this.textarea.insert({after: this._remainingCharacters});  
    this.refresh();  
  },

  refresh: function(){ 
    this._shadow.update($F(this.textarea).replace(/\n/g, '<br/>'));
    this.textarea.setStyle({
      height: Math.max(parseInt(this._shadow.getHeight()) + parseInt(this.textarea.getStyle('lineHeight').replace('px', '')), this.options.get('min_height')) + 'px'
    });

    // Keep the text/character count inside the limits:
    if($F(this.textarea).length > this.options.get('max_length')){
      text = $F(this.textarea).substring(0, this.options.get('max_length'));
        this.textarea.value = text;
        return false;
    }

    var remaining = this.options.get('max_length') - $F(this.textarea).length;
    this._remainingCharacters.update(Math.abs(remaining)  + ' characters remaining'));
  }
});
1
ответ дан 24 November 2019 в 02:25
поделиться
[

] Одно из уточнений некоторых из этих ответов состоит в том, чтобы позволить CSS сделать больше работы. [

] [

] Похоже, что основной маршрут: [

] [
    ] [
  1. ] Создайте элемент контейнера для хранения [] тексттарии [] и скрытого [] div[][
  2. ] [
  3. ] с помощью Javascript, сохранить содержимое []textarea[] синхронизированным с []div[][
  4. ] [
  5. ] Пусть браузер делает работу по вычислению высоты этого div[
  6. ] [
  7. ] Поскольку браузер обрабатывает рендеринг/размер скрытых []div[], мы избегаем явно устанавливает высоту []texttarea[].[
  8. ] [
] [

][

][
] [
] [
][]document.addEventListener('DOMContentLoaded', () => { textArea.addEventListener('change', autosize, false) textArea.addEventListener('keydown', autosize, false) textArea. addEventListener('keyup', autosize, false) autosize() }, false) функция autosize() { // Копирование содержимого тексттареа в div браузер вычислит правильную высоту // копирования, что сделает общий контейнер более высоким, что сделает // тексттареа более высоким. textCopy.innerHTML = textArea.value.replace(/\n/g, '
') }[
][
] [
][]html, body, textarea { семейство шрифтов: sans-serif; font-size: 14px; } .textarea-container { позиция: относительная; } . textarea-container > div, .textarea-container > textarea { word-wrap: break-word; /* следите за тем, чтобы слова div и textarea-container обертывались одинаково */ box-sizing: border-box; padding: 2px; ширина: 100%; } .textarea-container > textarea { переполнение: скрытое; положение: абсолютное; высота: 100%; } .textarea-container > div { отступ: 1.5em; /* Чуть больше одной дополнительной строки текста. */ видимость: скрытый; }[][
] [
][]
[
][
] [
] [
]
63
ответ дан 24 November 2019 в 02:25
поделиться

Internet Explorer, Safari, Chrome и opera Пользователи должны помнить, чтобы явно установить значение высоты строки в CSS. Я делаю таблицу стилей, которая устанавливает начальные палаты для всех текстовых ящиков следующим образом.

<style>
    TEXTAREA { line-height: 14px; font-size: 12px; font-family: arial }
</style>
1
ответ дан 24 November 2019 в 02:25
поделиться

Вот функция, которую я только что написал для этого в jQuery - вы можете перенести ее на Prototype , но они не поддерживают «живучесть» jQuery, поэтому элементы, добавленные запросами Ajax, не будут отвечать .

Эта версия не только расширяется, но и сжимается при нажатии клавиши удаления или возврата.

Эта версия основана на jQuery 1.4.2.

Наслаждайтесь;)

http://pastebin.com/SUKeBtnx

Использование:

$("#sometextarea").textareacontrol();

или (любой селектор jQuery, например)

$("textarea").textareacontrol();

Тестировалось в Internet Explorer 7 / Internet Explorer 8 , Firefox 3.5 и Chrome. Все работает нормально.

1
ответ дан 24 November 2019 в 02:25
поделиться

Проверьте ссылку ниже: http://james.padolsey.com/javascript/jquery-plugin-autoresize/

$(document).ready(function () {
    $('.ExpandableTextCSS').autoResize({
        // On resize:
        onResize: function () {
            $(this).css({ opacity: 0.8 });
        },
        // After resize:
        animateCallback: function () {
            $(this).css({ opacity: 1 });
        },
        // Quite slow animation:
        animateDuration: 300,
        // More extra space:
        extraSpace:20,
        //Textarea height limit
        limit:10
    });
});
5
ответ дан 24 November 2019 в 02:25
поделиться

Вот решение с помощью JQuery:

$(document).ready(function() {
    var $abc = $("#abc");
    $abc.css("height", $abc.attr("scrollHeight"));
})

abc - teaxtarea.

7
ответ дан 24 November 2019 в 02:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: