Javascript 调整文本区域的大小事件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5570390/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 17:51:36  来源:igfitidea点击:

Resize event for textarea?

javascriptjqueryhtmlevents

提问by metrobalderas

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!

当前版本的 Firefox 和 Chrome 包含一个拖动处理程序来调整<textarea>框的大小。我需要捕获调整大小事件,我认为使用 jQueryresize()事件会很容易,但它不起作用!

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

我也尝试过正常onResize事件,但结果是一样的。你可以在 JSFiddle 上试试

Is there a way to capture it?

有没有办法捕获它?

采纳答案by Hussein

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.

在发出 resize 事件之前,您需要首先使 textarea 可调整大小。你可以通过使用 jQuery UI resizable()来做到这一点,你可以在其中调用 resize 事件。

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

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

http://jsfiddle.net/HhSYG/1/检查工作示例

回答by vol7ron

This is an old question, but someone else had the same one in IRC, so I decided to solve it here: http://jsfiddle.net/vol7ron/Z7HDn/

这是一个老问题,但其他人在 IRC 中有相同的问题,所以我决定在这里解决它:http: //jsfiddle.net/vol7ron/Z7HDn/

Chrome doesn't capture the resize event and that Chrome doesn't capture the mousedown, so you need to set the init state and then handle changes through mouseup:

Chrome 不会捕获 resize 事件并且 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

HTML

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

Note:

笔记:

  1. You could attach your own resizable as Hussein has done, but if you want the original one, you can use the above code
  2. As Bryan Downing mentions, this works when you mouseup while your mouse is on top of a textarea; however, there are instances where that might not happen like when a browser is not maximized and you continue to drag beyond the scope of the browser, or use resize:verticalto lock movement.

    For something more advanced you'd need to add other listeners, possibly a queue and interval scanners; or to use mousemove, as I believe jQuery resizable does -- the question then becomes how much do you value performance vs polish?

  1. 您可以像 Hussein 那样附加自己的可调整大小,但如果您想要原始的,则可以使用上面的代码
  2. 正如 Bryan Downing 所提到的,当您将鼠标放在 textarea 顶部时,这会起作用;但是,有些情况下可能不会发生这种情况,例如浏览器未最大化并且您继续拖动超出浏览器的范围或用于resize:vertical锁定移动。

    对于更高级的东西,您需要添加其他侦听器,可能是队列和间隔扫描器;或者使用 mousemove,正如我相信 jQuery resizable 所做的那样 - 那么问题就变成了你对性能与抛光的重视程度如何?



Update:There's since been a change to Browsers' UI. Now double-clicking the corner may contract the textbox to its default size. So you also may need to capture changes before/after this event as well.

更新:此后浏览器的 UI 发生了变化。现在双击角落可以将文本框收缩到其默认大小。因此,您可能还需要在此事件之前/之后捕获更改。

回答by Daniel Herr

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

一个新标准是 Resize Observer api,它在 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>

Alternatively, Mutation Observer can be used to detect the change of the style attribute in Firefox and Chrome 54.

或者,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

调整观察者大小

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

规格:https: //wig.github.io/ResizeObserver

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

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

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

Chrome 问题:https: //crbug.com/612962

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

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

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

Firefox 问题:https: //bugzil.la/1272409

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

Safari 问题:http: //wkb.ug/157743

回答by MoonLite

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

我对 vol7ron 的回答进行了一些混合,只是用普通的“resize”事件的简单触发器替换了“Resize Action Here”,这样你就可以“像往常一样”将你想要发生的任何事情附加到 resize 事件上:

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

我添加了 mousemove 事件,因此在调整大小时拖动鼠标时调整大小也会触发,但请记住,当您四处移动鼠标时,它会经常触发。

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 与第一个一起增长和缩小:

$('textarea').eq(0).resize(function(){
    var $ta2 = $('textarea').eq(1);
    $('textarea').eq(1).css('width',$ta2.css('width')).css('height',$ta2.css('height'));
});

回答by Guy

another way to do it is by binding to the mouseup event on the textarea. then you can check if size changed.

另一种方法是绑定到 textarea 上的 mouseup 事件。然后你可以检查大小是否改变。

回答by megar

Resize event doesn't exist for textarea.

textarea 不存在调整大小事件。

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

可调整大小的 jQueryPlugin 看起来不是原生的,所以我们必须使用替代。

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:

模拟它的一种方法是使用 mousedown/click 事件。如果你想要实时事件触发,你可以这样做:

Updated november 11, 2013:

2013 年 11 月 11 日更新:

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

演示:http: //jsfiddle.net/gbouthenot/D2bZd/

回答by David Bradshaw

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

FireFox 现在支持 textareas 上的 MutationObserver 事件,这似乎工作得很好。遗憾的是,Chrome 仍然需要一种解决方法。

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

根据此页面上的其他答案,这是一个重构和更新的版本,它在调整 a 大小时触发窗口调整大小事件textarea

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

我还为鼠标离开窗口添加了一个事件侦听器,在 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');
});

In IE9 and above we can do the same without jQuery.

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

回答by Krishan

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.

感谢 MoonLite - 您的脚本运行良好,但有时,如果您快速增加调整大小,则鼠标指针位于 mouseup 上的文本区域之外,并且不会触发所需的功能。所以我在包含元素上添加了一个 mouseup 事件以使其工作可靠。

.

.

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

回答by jaya

I wrote this answer to another version of the same question. looks like it's old news in here. I like to stick to vanilla js for whatever reason, so here's a tidy little solution in vanilla:

我在同一问题的另一个版本中写了这个答案。看来这里是旧闻了。无论出于何种原因,我都喜欢坚持使用 vanilla js,所以这里有一个简单的 vanilla 解决方案:

<textarea
  onmousedown="storeDimensions(this)"
  onmouseup="onresizeMaybe(this)"
></textarea>

<script>
  function storeDimensions(element){
    element.textWidth = element.offsetWidth;
    element.textHeight = element.offsetHeight;
    element.value = "is it gonna change? we don't know yet...";
  }
  
  function onresizeMaybe(element){
    if (element.textWidth===element.offsetWidth
     && element.textHeight===element.offsetHeight) 
      element.value = "no change.\n";
    else element.value ="RESIZED!\n";
    
    element.value +=
       `width: ${element.textWidth}\n`
      +`height: ${element.textHeight}`;
  }
</script>

and for homework, use onmousemoveto trigger the resize event instead of onmouseup(I didn't need that in my particular case).

对于家庭作业,使用onmousemove来触发调整大小事件而不是onmouseup(在我的特定情况下我不需要)。

if you want to add this to every textareain the DOM (not really tested):

如果你想把它添加到textareaDOM 中的每一个(没有真正测试过):

let elementArray = document.getElementsByTagName("textarea");
for(var i=0; i<elementArray.length; i++){
  elementArray[i].setAttribute("onmousedown", "storeDimensions(this)");
  elementArray[i].setAttribute("onmouseup", "onresizeMaybe(this)");
}

:) hope it helps someone someday... seeing as how this question is now 9 years old.

:) 希望有一天它可以帮助某人......看看这个问题现在已经 9 岁了。

NOTE: if you're going to want to trigger this on mousemove, the new fangled ResizeObserver(callback).observe(element)approach is great!

注意:如果您想在 mousemove 上触发它,那么新的奇特ResizeObserver(callback).observe(element)方法很棒!