Resize event for textarea?

2019-01-03 03:31发布

The current versions of Firefox and Chrome include a drag handler to resize a <textarea> box. I need to capture the resizing event, I thought it would be easy with jQuery's resize() event, but it doesn't work!

I have also tried the normal onResize event, but the result is the same. You can try it on JSFiddle.

Is there a way to capture it?

8条回答
叼着烟拽天下
2楼-- · 2019-01-03 03:39

FireFox now supports MutationObserver events on textareas and this seems to work quite well. Chrome sadly still needs a workaround.

Based on the other answers on this page, here's a refactored and updated version, that triggers a window resize event when a textarea is resized.

I've also added an event listener for the mouse leaving the window which is needed in an iFrame to detect when the textarea becomes larger than the frame.

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

In IE9 and above we can do the same without 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);
});
查看更多
狗以群分
3楼-- · 2019-01-03 03:51

You need to first make the textarea resizable before issuing the resize event. You can do that by using jQuery UI resizable() and inside it you can call the resize event.

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

Check working example at http://jsfiddle.net/HhSYG/1/

查看更多
仙女界的扛把子
4楼-- · 2019-01-03 03:51

Resize event doesn't exist for textarea.

The resizeable jQueryPlugin doesn't look native, so we must use alternative.

One way to emulate it is to use the mousedown/click event. If you want real-time event triggering, you can do it like this:

Updated november 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"));

Demo : http://jsfiddle.net/gbouthenot/D2bZd/

查看更多
欢心
5楼-- · 2019-01-03 03:51

thanks to MoonLite - Your script is working fine, but sometimes, if You do a quick increasing-resize the mouse pointer is outside the textarea on mouseup and the wished function is not triggered. So I added a mouseup event on the containing element to make it work reliable.

.

 
        $('textarea_container').bind('mouseup', function()
        { YourCode ; } ) ;
'

查看更多
我想做一个坏孩纸
6楼-- · 2019-01-03 03:53

I mixed vol7ron's answer up a bit, and just replaced the "Resize Action Here" with a simple trigger of the normal "resize" event, so you can attach whatever you want to happen to the resize event "as usual":

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

I added the mousemove event so the resizing also fires while dragging the mouse around while resizing, but keep in mind that it fires very often when you move the mouse around.

in this case you might want to put a little delay in actually triggering or handling the resizing event, e.g. replace the above:

$(this).resize();

with:

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

example usage, make 2nd textarea grow and shrink with the first one:

$('textarea').eq(0).resize(function(){
    var $ta2 = $('textarea').eq(1);
    $('textarea').eq(1).css('width',$ta2.css('width')).css('height',$ta2.css('height'));
});
查看更多
不美不萌又怎样
7楼-- · 2019-01-03 03:55

A new standard for this is the Resize Observer api, available in Chrome Dev 54 behind the experimental web platform features flag.

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>

Alternatively, Mutation Observer can be used to detect the change of the style attribute in Firefox and 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

Spec: https://wicg.github.io/ResizeObserver

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

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

Chrome Flag: chrome://flags/#enable-experimental-web-platform-features

Firefox Issue: https://bugzil.la/1272409

Safari Issue: http://wkb.ug/157743

查看更多
登录 后发表回答