调整textarea事件的大小?

时间:2011-04-06 17:19:54

标签: javascript jquery html events

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

我也尝试了正常的onResize事件,但结果是一样的。 You can try it on JSFiddle

有没有办法捕获它?

11 个答案:

答案 0 :(得分:41)

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

Chrome无法捕获调整大小事件且Chrome无法捕获mousedown,因此您需要设置初始状态,然后通过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. 您可以附加自己的可调整大小,如Hussein所做的那样,但如果您想要原始的,可以使用上面的代码
  2. 正如Bryan Downing所提到的,当你的鼠标位于文本区域顶部时,鼠标按钮可以正常工作;但是,有些情况可能不会发生,例如当浏览器未最大化并且您继续拖动超出浏览器范围,或使用resize:vertical来锁定移动时。

    对于更高级的东西,您需要添加其他侦听器,可能还有队列和间隔扫描程序;或者使用mousemove,因为我相信jQuery可以调整大小 - 那么问题就变成了你对性能与抛光的重视程度了多少?


  3. 更新: 此后,浏览器的用户界面发生了变化。现在双击该角可能会将文本框缩小为其默认大小。因此,您也可能需要在此事件之前/之后捕获更改。

答案 1 :(得分:12)

新标准是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>

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

调整观察者大小

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

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

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

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

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

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

答案 2 :(得分:7)

我把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;
        }
    });
});

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

在这种情况下,您可能希望在实际触发或处理调整大小事件时稍微延迟,例如: 取代上面的内容:

$(this).resize();

使用:

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

示例用法,使第二个textarea与第一个增长和缩小:

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

答案 3 :(得分:6)

另一种方法是通过绑定textarea上的mouseup事件。然后你可以检查尺寸是否改变了。

答案 4 :(得分:2)

textarea不存在调整大小事件。

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

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

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

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

答案 5 :(得分:2)

我将此答案写到了同一问题的另一个版本。好像这里是老新闻。无论出于何种原因,我都喜欢坚持使用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>

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

如果要将其添加到DOM中的每个textarea(未经测试):

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

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

注意:如果您要在mousemove上触发此操作,那么新的ResizeObserver(callback).observe(element)方式很有用!

答案 6 :(得分:1)

在发出resize事件之前,您需要首先使textarea可调整大小。您可以使用jQuery UI resizable()来实现,在其中可以调用resize事件。

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

检查http://jsfiddle.net/HhSYG/1/

处的工作示例

答案 7 :(得分:1)

FireFox现在支持textareas上的MutationObserver事件,这看起来效果很好。 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);
});

答案 8 :(得分:1)

我发现一个 mousemove 事件和一个 setTimeout 结合起来可以很好地解决这个问题。

let el = document.querySelector('textarea')
let resizeFn = ()=>{}
let timeout = null

el.addEventListener('mousemove',()=>{
    timeout && clearTimeout(timeout)
    timeout = setTimeout(resizeFn,250)
 })

答案 9 :(得分:0)

没有那么漂亮和动态,但它按预期工作。

$('.classname').mouseup(function(){
    $('.classname').css('height', $(this).height());
});

答案 10 :(得分:-1)

感谢MoonLite - 你的脚本运行正常,但有时,如果你快速增加调整大小,鼠标指针在mouseup上的textarea之外,并且不会触发所需的函数。所以我在包含元素上添加了一个mouseup事件,使其工作可靠。


    

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