现在的位置: 首页 > easyui > Window > dialog > 正文
panel,dialog,window组件越界问题汇总
2012年11月23日 dialog, panel, window ⁄ 共 5082字 评论数 18 ⁄ 被围观 16,854 views+
文章目录
[隐藏]

之前分别写过panel,dialog,window三个组件因为拖曳或者reSize造成组件越界而无法还原的问题,两篇文章分别针对拖曳和reSize给出了解决方案。不过根据朋友的反馈,reSize的解决方案拖曳的解决方案同时使用时存在效率低下的问题,个人也在进一步使用过程中发现了另外一些问题,共修正以下Bug:

  • 原生panel并无拖曳和缩放功能,且继承panel组件的上层组件太多,极容易出问题,故放弃对panel组件的支持。
  • onResize配合onMove使用时,性能低下,原因是由onResize触发的onMove内部死循环。已修正。
  • resize时,超越浏览器边界会造成缩放和拖动都不可用。通过增加了对offset的监控修正
  • IE8下,reSize超越浏览器边界后依旧会造成缩放和拖曳不可用,原因是IE8此时不影响onkeyup事件。已修正。
  • window,dioalg内部包含layout,datagrid组件时,resize高度小于一定值会造成性能低下。已修正。
  • 初始化时,如果页面不是最大化,onResize会把window和dialog高度自动变小。通过计数器修正。

实现代码:

最终综合两种方案,整理出代码:

  1. var ie = (function() {   
  2.     var undef, v = 3, div = document.createElement('div'), all = div   
  3.             .getElementsByTagName('i');   
  4.     while (div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->', all[0]);   
  5.     return v > 4 ? v : undef;   
  6. }());   
  7. /**
  8.  * add by cgh  
  9.  * 针对panel window dialog三个组件调整大小时会超出父级元素的修正  
  10.  * 如果父级元素的overflow属性为hidden,则修复上下左右个方向  
  11.  * 如果父级元素的overflow属性为非hidden,则只修复上左两个方向  
  12.  * @param width  
  13.  * @param height  
  14.  * @returns  
  15.  */  
  16. var easyuiPanelOnResize = function(width, height) {   
  17.     if (!$.data(this, 'window') && !$.data(this, 'dialog'))   
  18.         return;   
  19.   
  20.     if (ie === 8) {   
  21.         var data = $.data(this"window") || $.data(this"dialog");   
  22.         if (data.pmask) {   
  23.             var masks = data.window.nextAll('.window-proxy-mask');   
  24.             if (masks.length > 1) {   
  25.                 $(masks[1]).remove();   
  26.                 masks[1] = null;   
  27.             }   
  28.         }   
  29.     }   
  30.     if ($(this).panel('options').maximized == true) {   
  31.         $(this).panel('options').fit = false;   
  32.     }   
  33.     $(this).panel('options').reSizing = true;   
  34.     if (!$(this).panel('options').reSizeNum) {   
  35.         $(this).panel('options').reSizeNum = 1;   
  36.     } else {   
  37.         $(this).panel('options').reSizeNum++;   
  38.     }   
  39.     var parentObj = $(this).panel('panel').parent();   
  40.     var left = $(this).panel('panel').position().left;   
  41.     var top = $(this).panel('panel').position().top;   
  42.   
  43.     if ($(this).panel('panel').offset().left < 0) {   
  44.         $(this).panel('move', {   
  45.                     left : 0   
  46.                 });   
  47.     }   
  48.     if ($(this).panel('panel').offset().top < 0) {   
  49.         $(this).panel('move', {   
  50.                     top : 0   
  51.                 });   
  52.     }   
  53.   
  54.     if (left < 0) {   
  55.         $(this).panel('move', {   
  56.                     left : 0   
  57.                 }).panel('resize', {   
  58.                     width : width + left   
  59.                 });   
  60.     }   
  61.     if (top < 0) {   
  62.         $(this).panel('move', {   
  63.                     top : 0   
  64.                 }).panel('resize', {   
  65.                     height : height + top   
  66.                 });   
  67.     }   
  68.     if (parentObj.css("overflow") == "hidden") {   
  69.         var inline = $.data(this"window").options.inline;   
  70.         if (inline == false) {   
  71.             parentObj = $(window);   
  72.         }   
  73.   
  74.         if ((width + left > parentObj.width())   
  75.                 && $(this).panel('options').reSizeNum > 1) {   
  76.             $(this).panel('resize', {   
  77.                         width : parentObj.width() - left   
  78.                     });   
  79.         }   
  80.   
  81.         if ((height + top > parentObj.height())   
  82.                 && $(this).panel('options').reSizeNum > 1) {   
  83.             $(this).panel('resize', {   
  84.                         height : parentObj.height() - top   
  85.                     });   
  86.         }   
  87.     }   
  88.     $(this).panel('options').reSizing = false;   
  89. };   
  90. /**
  91.  * add by cgh  
  92.  * 针对panel window dialog三个组件拖动时会超出父级元素的修正  
  93.  * 如果父级元素的overflow属性为hidden,则修复上下左右个方向  
  94.  * 如果父级元素的overflow属性为非hidden,则只修复上左两个方向  
  95.  * @param left  
  96.  * @param top  
  97.  * @returns  
  98.  */  
  99. var easyuiPanelOnMove = function(left, top) {   
  100.     if ($(this).panel('options').reSizing)   
  101.         return;   
  102.     var parentObj = $(this).panel('panel').parent();   
  103.     var width = $(this).panel('options').width;   
  104.     var height = $(this).panel('options').height;   
  105.     var right = left + width;   
  106.     var buttom = top + height;   
  107.     var parentWidth = parentObj.width();   
  108.     var parentHeight = parentObj.height();   
  109.   
  110.     if (left < 0) {   
  111.         $(this).panel('move', {   
  112.                     left : 0   
  113.                 });   
  114.     }   
  115.     if (top < 0) {   
  116.         $(this).panel('move', {   
  117.                     top : 0   
  118.                 });   
  119.     }   
  120.   
  121.     if (parentObj.css("overflow") == "hidden") {   
  122.         var inline = $.data(this"window").options.inline;   
  123.         if (inline == false) {   
  124.             parentObj = $(window);   
  125.         }   
  126.         if (left > parentObj.width() - width) {   
  127.             $(this).panel('move', {   
  128.                         "left" : parentObj.width() - width   
  129.                     });   
  130.         }   
  131.         if (top > parentObj.height() - height) {   
  132.             $(this).panel('move', {   
  133.                         "top" : parentObj.height() - height   
  134.                     });   
  135.         }   
  136.     }   
  137. };   
  138.   
  139. $.fn.window.defaults.onResize = easyuiPanelOnResize;   
  140. $.fn.dialog.defaults.onResize = easyuiPanelOnResize;   
  141. $.fn.window.defaults.onMove = easyuiPanelOnMove;   
  142. $.fn.dialog.defaults.onMove = easyuiPanelOnMove;  

使用的时候,请在引入easyui的核心文件后,直接追加以上代码,注意不要写在document.ready里面。

到这里,panel,window,dialog等组件越界的问题就算是基本解决了。欢迎大家测试,即时反馈Bug。

效果演示:

http://www.easyui.info/easyui/demo/window/062.html

目前有 18 条留言 其中:访客:10 条, 博主:6 条 引用: 2

  1. 江南 : 2012年12月11日11:14:27  -49楼 @回复 回复

    不错非常好哦。
    IE8下会报错(自己改了下下。。),如果不报错,那么alert向下拖出窗口还是不行的哦。总之楼主很厉害。


    • 管理员
      世纪之光 : 2012年12月11日11:28:10  地下1层 @回复 回复

      能反馈一下IE8下究竟是什么问题吗,做什么样的操作会报错?我也好改进一下。
      注意我这里只是修正了window和dialog,不包括panel和messager组件。

      • 江南 : 2012年12月11日14:59:10  地下2层 @回复 回复

        就是单纯的使用,单击一个按钮,弹出一个window,就报错了。
        这个是调用js方法
        function deleteByTime() {
        $(‘#deleteUserMoniterDiv’).window(‘open’);
        if (window.XMLHttpRequest) {// 判断浏览器是否属于Mozilla,Sofari
        $(‘#deleteUserMoniterDiv’).window(‘resize’, {
        top : 15
        });
        };
        }

        报的错误是,对象不支持该属性或者方法,我是直接放到基本库最后的,火狐和chrome测试没有问题,IE报的错误行是这个
        var easyuiPanelOnMove = function(left, top) {
        if ($(this).panel(‘options’).reSizing)//这行报错,不知道是不是我使用错误哦


        • 管理员
          世纪之光 : 2012年12月12日09:16:39  地下3层 @回复 回复

          这个地方报错应该是大多是window还没渲染完成吧,肯定是$(this).panel(‘options’)为空了,没法访问reSizing属性。你可以单步一下试试。IE8下我也测试过,没有遇到这个问题呀。

      • tiger20111989 : 2013年10月22日16:29:22  地下2层 @回复 回复

        是不包含messager的

  2. zack : 2013年04月01日16:33:21  -48楼 @回复 回复

    你好,我在谷歌浏览器下使用后发生:
    Uncaught RangeError: Maximum call stack size exceeded


    • 管理员
      世纪之光 : 2013年04月01日16:54:05  地下1层 @回复 回复

      你好,谢谢你的反馈,把使用场景详细的说一下,或者使用静态的html文件把文件呈现给我,文件可以发到我邮箱里caoguanghuicgh^163.com,请把^换成@。

      • zack : 2013年04月03日16:55:22  地下2层 @回复 回复

        我试着将我可能出问题的html去掉,但,还是出现一样的问题。将你上面的js去掉就不会出现Uncaught RangeError: Maximum call stack size exceeded了。我目前,还不急解决 这个问题。如果找到场景,我会联系你的。
        谢谢管理员了。 😛

        • gaara : 2015年01月13日17:32:45  地下3层 @回复 回复

          场景出现:当dialog或window设置很大的时候,比父容器还要大,谷歌就会报这个错了。
          还有我发现这个改动后,如果父容器小的时候,不足以dailog移动时,这时候,一旦拖动了,dialog就无法固定了,感觉死循环了


          • 管理员
            世纪之光 : 2015年01月15日09:30:59  地下4层 @回复 回复

            什么时候会出现弹出窗口比父容器还要大的使用场景呢?我这段代码确实没有考虑这种情况。

  3. shengwenzheng : 2013年05月28日10:31:20  -47楼 @回复 回复

    ie8下,往上面拖,超出上面的边界时,窗体总是连着鼠标,无法放下,其他3个方向都是正常的,请楼主解决这个问题。

  4. sun : 2014年09月04日20:30:44  -46楼 @回复 回复

    不知道大家试过没,当设置dialog的width或者height超出了显示区域时,就会报下面的错:
    Uncaught RangeError: Maximum call stack size exceeded
    很明显死循环了。

    我在onMove里加了下面的代码:
    if(height>parentHeight){
    $(this).window(‘resize’,{
    height:parentHeight-20

    });
    }

    但这样会造成dialog底部的button被遮住了一部分,楼主有空了看下能解决不
    记得ext里有个属性直接设置一下就可以了,强制将弹出窗口全部显示,无论怎样改变大小或者拖动,窗口的边界都能显示全。
    我用的easyui1.3.2


    • 管理员
      世纪之光 : 2014年09月04日20:57:49  地下1层 @回复 回复

      if(height>parentHeight){
      $(this).window(‘resize’,{
      height:parentHeight
      });
      }
      把你代码改成这样应该就可以了吧。
      当尺寸超过父元素尺寸的时候,父元素的overflow为hidden的时候无法保证弹框全部显示吧,其它情况可以考虑用滚动条。

  5. web : 2014年12月02日15:37:03  -45楼 @回复 回复

    大神,刚接触WebUI框架,能发下整个代码吗?包括引入的js。谢谢
    邮箱:526578443@qq.com


    • 管理员
      世纪之光 : 2014年12月04日13:04:39  地下1层 @回复 回复

      就这么一段js,作为js文件在easyui文件之后引入就行了。

  6. dept : 2015年01月27日14:27:47  -44楼 @回复 回复

    hi,世纪之光!
    如果在panel中有一个win窗口,这个窗口如何能移除这个panel之外,就跟全局窗口一样的大小呢,

给我留言

留言无头像?


×