resizable和draggable组件在IE8下浏览器越界无法释放对目标DOM控制的问题

标题有点长, 不考虑IE8兼容性的朋友可以直接忽视本文,本文所提到的问题是只在IE8这个垃圾版本下才会有的问题。大家在使用window组件的时候,应该注意到在IE8下,当resize或者拖动window超出浏览器边界的时候,被resize或者拖动的window组件实例依旧处于被reszie或者被拖动的状态,即便是松开鼠标也没有用。其实归根到底是mouseup事件没有被触发。这个并不是EasyUI才有的问题,很多类似框架,如DWZ,DHTMLX都存在这个问题。

如何解决这个问题,本人也一直没有想出太好的方案,不过IE浏览器有个setCapture方法可以被利用,这个方法并不是w3c标准里面的,不同浏览器可能有不同实现,它的用途就是设置事件可以被触发的范围,如果调用了某个DOM对象的setCapture方法,则这个DOM对象的绑定事件即便是在鼠标超出浏览器边界也会被触发。利用它,我们便可以解决这个尴尬的问题了。

网络上典型的设置事件可在浏览器外触发的代码是这样的:

  1. var dv = document.getElementById(“mydiv”);
  2. if(dv.setCapture){//IE浏览器
  3.     dv.setCapture();
  4. }else if(window.captureEvents){//FF等浏览器
  5.     window.captureEvents(Event.MOUSEMOVE | Event.MOUSEUP);
  6. }

不过我们,只针对IE8处理这个问题,所以在判断出IE版本的情况下,直接调用dv.setCapture();  便可以了。对于resiable和draggable组件来讲,通常都是在mousedown的时候setCapture(),mouseup的时候releaseCapture(),releaseCapture方法是setCapture方法的反过程。resizable组件修改的参考代码(draggable组件类似):

  1. function doDown(e){
  2.     isResizing = true;
  3.     if(isIE===8){
  4.         e.data.target.setCapture();
  5.     }
  6.     $.data(e.data.target, ‘resizable’).options.onStartResize.call(e.data.target, e);
  7.     return false;
  8. }
  1. function doUp(e){
  2.     isResizing = false;
  3.     resize(e, true);
  4.     applySize(e);
  5.     if(isIE===8){
  6.         e.data.target.releaseCapture();
  7.     }
  8.     $.data(e.data.target, ‘resizable’).options.onStopResize.call(e.data.target, e);
  9.     $(document).unbind(‘.resizable’);
  10.     $(‘body’).css(‘cursor’,”);
  11.     return false;
  12. }

最终,我们用IE8来看看纠正的效果:
http://www.easyui.info/easyui/demo/window/062.html

Tagged: , ,

Comments are closed.