2013-04-09 120 views
5

看起来像调整HTML元素的大小时,窗口的resize事件也会被触发。调整元素的大小会触发窗口的大小调整事件

由于我想在调整元素的大小和窗口大小时执行不同的逻辑,有没有一种处理这个问题的非常方法?

http://jsfiddle.net/CPUwW/1/

$(function(){ 
    $(window).on('resize', function(){   
      // This event gets fired when the #my_element div gets resized, event if 
      // window doesn't get resized itself 
      $('#text').text(++resizes); 
    }); 

    $('#my_element').resizable();  
}); 

换句话说,问题是,当我调整的元素,调整大小事件,都会激发所有它的父母,即使他们的大小不会改变

+2

use event.stopPropagation(); http://api.jquery.com/event.stopPropagation – Daniel 2013-04-09 13:15:48

+1

除非您停止传播,否则“调整大小”事件会一直显示到窗口对象。 – 2013-04-09 19:16:12

+1

我认为这是jQueryUI可调整大小的错误,它会触发窗口大小调整事件,而不考虑返回值或停止传播状态。 – Doug 2013-09-29 15:31:26

回答

9

根据其他信息我认为这个反映了窗口的行为。

$(function() { 
    var resizes = 0; 

    $(window).on('resize', function() { 
     $('#text').text(++resizes); 
    }); 
    $('#my_element').resizable(); 

    $("#my_element").on('resize', function (e) { 
     e.stopPropagation(); 
    }); 

}); 

http://jsfiddle.net/djwave28/CPUwW/7/

编辑:另类和“更优雅”的解决方案

虽然上述方案的工作完美无瑕,我不满意具有可调整大小的()部件外管理。它不一定是。深入挖掘之后,可以在“创建”阶段内停止传播。为了展示这个解决方案,我将它添加到前一个。

$(function() { 
    var resizes = 0; 

    $(window).on('resize', function() { 
     $('#text').text(++resizes); 
    }); 
    $('#my_element').resizable({ 
     create: function (event, ui) { 
      $(this).parent().on('resize', function (e) { 
       e.stopPropagation(); 
      }); 
     } 
    }); 
}); 

更新小提琴:http://jsfiddle.net/djwave28/CPUwW/9/

+0

伟大的东西。谢谢 – ALFmachine 2016-01-16 13:51:16

5

使用电子邮件.TARGET:

SEE DEMO

$(window).on('resize', function(e){ 
     if(e.target===this)   
      $('#text').text(++resizes); 
    }); 
+0

这不是问题。显然,窗口大小是@Loupax所要求的。无论你想阅读还是不阅读,你都在制定一个条件。 – Daniel 2013-04-09 13:24:14

+0

“因为我想在调整元素大小和窗口大小时执行不同的逻辑”我的回答回答了这个问题。但是你是这样对待的:“问题是,当我调整一个元素的大小时,即使它们的大小没有改变,resize事件也会被所有的父母触发。”这里的解决方案应该是使用event.stopPropagation();在可调整大小元素的每个处理程序上 – 2013-04-09 13:28:53

+0

是的,但有趣的部分是在哪里实现。 (???)..我尝试了文档,但目前还没有运气。 你说得对,我很遗憾我错过了读逻辑部分的行为。 – Daniel 2013-04-09 13:35:31

2

对我的作品Demo

if (e.originalEvent.type == 'resize'){ 
     $('#textWindow').text(++resizesWindow); 
    } else { 
     $('#text').text(++resizes); 
    } 
1

接受e作为第一个参数的匿名函数。

这将是jQuery Event Object,您可以使用它阻止使用e.stopPropagation传播事件(如Daniel在上述注释中所建议的那样)。

$(function(){ 
    $(#my_element).on('resize', function(e){ 
    e.stopPropagation();  
    $('#text').text(++resizes); 
    }); 

    $('#my_element').resizable();  
}); 

PPK有关于事件顺序解释事件冒泡和捕获的一个很好的写法,这是什么导致你在这里遇到麻烦。 http://www.quirksmode.org/js/events_order.html

2

根据http://www.quirksmode.org/dom/events/resize.html resize事件可在窗口上,但不是在文件或其他元素(如果我们忽略在该网页提到的一些例外)。

所以这是真的不可预料的,使用改变某些元件的宽度和/或高度可调整大小()导致:
1)调整事件在所有
2烧成)调整事件冒泡至窗口对象

如果我只想使$('#elem')可调整大小,那就是我想要的。没有任何冒泡或窗口调整事件触发。

我做了一个行更改为例子小提琴(和更新库更多的最新版本):

http://jsfiddle.net/CPUwW/56/

// The following line is the needed change. widgetEventPrefix is 
// originally 'resize'. It have to be changed. 

$.ui.resizable.prototype.widgetEventPrefix = 'myresize'; 

$(function(){ 
    var resizes = 0; 
    $(window).on('resize', function(){   
     $('#text').text(++resizes); 
    }); 
    $('#my_element').resizable();  
}); 

编辑:在此页面上的其他解决方案的问题(和也是here)是冒泡到窗口和触发窗口的resize事件导致不必要的开销,如果你只是想调整一些div的大小。

编辑2:因为widgetEventPrefix是一个内部参数,它的名字可以改变,它可以被删除,它的行为可以在新版本的jQuery UI中改变。所以,在升级用户界面时,请检查它是否像以前一样工作。

0

这是jQuery core一个错误,但它可以与目标检查

$(window).resize(function(e) { 
if (e.target == window) 
/* do your stuff here */; 
}) 
0

如果你只需要浏览器大小调整和元调整大小来区分,则可以选中“泡沫”事件的性质来workarounded (E):

$(window).resize(function(e) 
    { 
    if (!e.bubbles) 
     { 
     clearTimeout(resizeId); 
     resizeId = setTimeout(doneResizing, 250); 
     } 
    }); 

当浏览器的大小时,e.bubbles是假的(因为它是顶级实体),但在任何文档元素的大小时,e.bubbles将是真正的。

我已经在Chrome中...与其他浏览器YMMV进行了测试。