Изменить размер события для textarea? - PullRequest
44 голосов
/ 06 апреля 2011

Текущие версии Firefox и Chrome включают обработчик перетаскивания для изменения размера поля <textarea>. Мне нужно захватить событие изменения размера, я думал, что это будет легко с событием jQuery resize(), но оно не работает!

Я также пробовал обычное событие onResize, но результат тот же. Вы можете попробовать это на JSFiddle .

Есть ли способ его запечатлеть?

Ответы [ 8 ]

41 голосов
/ 14 августа 2011

Это старый вопрос, но у кого-то еще был такой же в IRC, поэтому я решил решить его здесь: http://jsfiddle.net/vol7ron/Z7HDn/

Chrome не фиксирует событие изменения размера, и Chrome не фиксирует mousedown, поэтому вам нужно установить состояние init и затем обрабатывать изменения с помощью mouseup:

jQuery(document).ready(function(){
   var $textareas = jQuery('textarea');

   // store init (default) state   
   $textareas.data('x', $textareas.outerWidth());
   $textareas.data('y', $textareas.outerHeight()); 

   $textareas.mouseup(function(){

      var $this = jQuery(this);

      if (  $this.outerWidth()  != $this.data('x') 
         || $this.outerHeight() != $this.data('y') )
      {
          // Resize Action Here
          alert( $this.outerWidth()  + ' - ' + $this.data('x') + '\n' 
               + $this.outerHeight() + ' - ' + $this.data('y')
               );
      }

      // store new height/width
      $this.data('x', $this.outerWidth());
      $this.data('y', $this.outerHeight()); 
   });

});

HTML

<textarea></textarea>
<textarea></textarea>

Примечание:

  1. Вы можете прикрепить свой собственный изменяемый размер, как это сделал Хуссейн, но если вы хотите оригинальный, вы можете использовать приведенный выше код
  2. Как упоминает Брайан Даунинг, это работает, когда вы наведите курсор мыши, когда мышь находится над текстовой областью; однако в некоторых случаях это может не происходить, например, когда браузер не развернут и вы продолжаете перетаскивать его за пределы браузера или используете resize:vertical для блокировки движения.

    Для чего-то более сложного вам нужно добавить других слушателей, возможно, сканеры очередей и интервалов; или использовать mousemove, как я полагаю, jQuery resizable. Возникает вопрос: насколько вы цените производительность по сравнению с польским?


Обновление: С тех пор произошли изменения в пользовательском интерфейсе браузеров. Теперь двойной щелчок по углу может сократить текстовое поле до размера по умолчанию. Поэтому вам также может потребоваться зафиксировать изменения до и после этого события.

14 голосов
/ 04 сентября 2016

Новый стандарт для этого - API Resize Observer, доступный в Chrome Dev 54 за флагом экспериментальных функций веб-платформы.

function outputsize() {
 width.value = textbox.offsetWidth
 height.value = textbox.offsetHeight
}
outputsize()

new ResizeObserver(outputsize).observe(textbox)
Width: <output id="width">0</output><br>
Height: <output id="height">0</output><br>
<textarea id="textbox">Resize me.</textarea>

В качестве альтернативы, Mutation Observer может использоваться для обнаружения изменения атрибута стиля в Firefox и Chrome 54.

function outputsize() {
 width.value = textbox.offsetWidth
 height.value = textbox.offsetHeight
}
outputsize()

new MutationObserver(outputsize).observe(textbox, {
 attributes: true, attributeFilter: [ "style" ]
})
Width: <output id="width">0</output><br>
Height: <output id="height">0</output><br>
<textarea id="textbox">Resize me.</textarea>

Resize Observer

Спецификация: https://wicg.github.io/ResizeObserver

Polyfill: https://github.com/pelotoncycle/resize-observer

Chrome Issue: https://crbug.com/612962

Chrome Флаг: chrome: // flags / # enable-эксперимент-web-platform-features

Firefox Проблема: https://bugzil.la/1272409

Проблема Safari:http://wkb.ug/157743

7 голосов
/ 31 мая 2013

Я немного перепутал ответ vol7ron и просто заменил «Действие по изменению размера здесь» простым триггером обычного события «изменение размера», чтобы вы могли присоединить все, что хотите, к событию изменения размера «как обычно»:

$(document).ready(function(){
    $('textarea').bind('mouseup mousemove',function(){
        if(this.oldwidth  === null){this.oldwidth  = this.style.width;}
        if(this.oldheight === null){this.oldheight = this.style.height;}
        if(this.style.width != this.oldwidth || this.style.height != this.oldheight){
            $(this).resize();
            this.oldwidth  = this.style.width;
            this.oldheight = this.style.height;
        }
    });
});

Я добавил событие mousemove, чтобы изменение размера также происходило при перетаскивании мыши при изменении размера, но имейте в виду, что оно срабатывает очень часто, когда вы перемещаете мышь.

inв этом случае вам может потребоваться небольшая задержка для фактического запуска или обработки события изменения размера, например, замените выше:

$(this).resize();

на:

if(this.resize_timeout){clearTimeout(this.resize_timeout);}
this.resize_timeout = setTimeout(function(){$(this).resize();},100);

пример использования, сделайте 2-е текстовое полерасти и уменьшаться с первым:

$('textarea').eq(0).resize(function(){
    var $ta2 = $('textarea').eq(1);
    $('textarea').eq(1).css('width',$ta2.css('width')).css('height',$ta2.css('height'));
});
6 голосов
/ 19 апреля 2012

еще один способ сделать это - привязка к событию mouseup в текстовой области. тогда вы можете проверить, если размер изменился.

2 голосов
/ 30 декабря 2012

Событие изменения размера не существует для textarea.

Изменяемый размер jQueryPlugin не выглядит нативным, поэтому мы должны использовать альтернативу.

Один из способов эмулировать это использовать mousedown /событие клика.Если вы хотите запускать события в реальном времени, вы можете сделать это следующим образом:

Обновлено 11 ноября 2013 г .:

// This fiddle shows how to simulate a resize event on a
// textarea
// Tested with Firefox 16-25 Linux / Windows
// Chrome 24-30 Linux / Windows

var textareaResize = function(source, dest) {
    var resizeInt = null;

    // the handler function
    var resizeEvent = function() {
        dest.outerWidth( source.outerWidth() );
        dest.outerHeight(source.outerHeight());
    };

    // This provides a "real-time" (actually 15 fps)
    // event, while resizing.
    // Unfortunately, mousedown is not fired on Chrome when
    // clicking on the resize area, so the real-time effect
    // does not work under Chrome.
    source.on("mousedown", function(e) {
        resizeInt = setInterval(resizeEvent, 1000/15);
    });

    // The mouseup event stops the interval,
    // then call the resize event one last time.
    // We listen for the whole window because in some cases,
    // the mouse pointer may be on the outside of the textarea.
    $(window).on("mouseup", function(e) {
        if (resizeInt !== null) {
            clearInterval(resizeInt);
        }
        resizeEvent();
    });
};

textareaResize($("#input"), $("#output"));

Демонстрация: http://jsfiddle.net/gbouthenot/D2bZd/

1 голос
/ 22 июня 2015

FireFox теперь поддерживает события MutationObserver на textareas, и это, кажется, работает довольно хорошо. К сожалению, Chrome все еще нуждается в обходном пути.

Основываясь на других ответах на этой странице, приведена обновленная и обновленная версия, которая запускает событие изменения размера окна при изменении размера textarea.

Я также добавил прослушиватель событий для мыши, выходящей из окна, которое необходимо в iFrame для определения, когда textarea становится больше, чем кадр.

(function(textAreaChanged){
    function store(){
        this.x = this.offsetWidth;
        this.y = this.offsetHeight;
    }

    function textAreaEvent(){
        if (this.offsetWidth !== this.x || this.offsetHeight !== this.y) {
            textAreaChanged();
            store.call(this);
        }
    }

    $('textarea').each(store).on('mouseup mouseout',textAreaEvent);

    $(window).on('mouseup',textAreaEvent);

})(function(){
    $(window).trigger('resize');
});

В IE9 и выше мы можем сделать то же самое без jQuery.

(function(textAreaChanged){
    function store(){
        this.x = this.offsetWidth;
        this.y = this.offsetHeight;
    }

    function textAreaEvent(){
        if (this.offsetWidth !== this.x || this.offsetHeight !== this.y) {
            textAreaChanged();
            store.call(this);
        }
    }

    Array.prototype.forEach.call(
        document.querySelectorAll('textarea'),
        function (el){
            el.addEventListener('mouseup',   textAreaEvent);
            el.addEventListener('mouseout',  textAreaEvent);
        }
    );

    window.addEventListener('mouseup',textAreaEvent)

})(function(){
    //trigger window resize
    var event = document.createEvent('Events');
    event.initEvent('resize', true, false);
    window.dispatchEvent(event);
});
1 голос
/ 06 апреля 2011

Вам нужно сначала сделать текстовую область изменяемой размера перед выдачей события изменения размера. Вы можете сделать это, используя jQuery UI resizable () , и внутри него вы можете вызвать событие resize.

<code>$("textarea").resizable({
    resize: function() {
        $("body").append("<pre>resized!
"); } });

Проверьте рабочий пример на http://jsfiddle.net/HhSYG/1/

0 голосов
/ 15 июня 2013

благодаря MoonLite - ваш скрипт работает нормально, но иногда, если вы делаете быстрое увеличение-изменение размера, указатель мыши находится вне текстовой области при mouseup, и требуемая функция не срабатывает.Поэтому я добавил событие mouseup для содержащего элемента, чтобы он работал надежно.

.

 
        $('textarea_container').bind('mouseup', function()
        { YourCode ; } ) ;<br>
    
'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...