(十一)模仿Ext的 Resizer 和 Drag 的窗口。

Ext的 Resize 和 Drag 界面非常漂亮,很多朋友想把它用到自己的地方,却不想用整个Ext ,所以本文特别对这2个效果进行制作。让我们先看下效果:

(十一)模仿Ext的 Resizer 和 Drag 的窗口。

1. 修正一些认识。

     很多朋友肯能认为拖动时的虚线和透明窗口是为了美观,但其实它们更为了效率。如果窗口里有很多元素,如果经常改变大小,会导致内部元素经常重新布局,最后导致效果卡得不能用。

2. 复习上文的拖动。

    上文介绍了如何实现拖动,最终我们可以通过如下代码实现拖动:

     elem.on('dragstart', function(){});

3. resizer 节点。

   resize时见到的虚框其实是一个和窗口没关的div,我们把这个div称为代理层。 (div-proxy)

当鼠标按下角落时 - 显示代理,并附在窗口上 - 当鼠标移动, 改变代理大小。 - 当鼠标放开 - 隐藏代码, 设置窗口大小。

4. 拖动句柄。

   所谓的句柄就是八个可触发resize的小东西,这些东西可用<div>实现:

            <div class="x-resizable-lt">

            </div>

            <div class="x-resizable-t">

            </div>

            <div class="x-resizable-rt">

            </div>

            <div class="x-resizable-l">

            </div>

            <div class="x-resizable-r">

            </div>

            <div class="x-resizable-lb">

            </div>

            <div class="x-resizable-b">

            </div>

            <div class="x-resizable-rb">

            </div>

每个滑块:

.x-resizable-lt, .x-resizable-t, .x-resizable-rt, .x-resizable-l, .x-resizable-r, .x-resizable-lb, .x-resizable-b, .x-resizable-rb {

	overflow: hidden;

	width: 6px;

	height: 6px;

	position: absolute;

}



.x-resizable-lt {

	top: 0;

	left: 0;

	z-index: 2;

	cursor: nw-resize;

}



.x-resizable-t {

	width: 100%;

	top: 0;

	left: 0;

	z-index: 1;

	cursor: n-resize;

}



.x-resizable-rt {

	top: 0;

	right: 0;

	cursor: ne-resize;

}



.x-resizable-l {

	left: 0;

	cursor: w-resize;

}



.x-resizable-r {

	right: 0;

	cursor: e-resize;

}



.x-resizable-lb {

	bottom: 0;

	left: 0;

	z-index: 2;

	cursor: sw-resize;

}



.x-resizable-b {

	width: 100%;

	bottom: 0;

	left: 0;

	cursor: s-resize;

}



.x-resizable-rb {

	bottom: 0;

	right: 0;

	cursor: se-resize;

} 

这样,便可见到这些句柄。

原理不多说了,看代码就知道。

5. 绑定事件-开始拖动

以右滑块例,

document.queryOne('.x-resizable-r').on('dragstart', function(e){



  showProxy();  // 显示代理



}



document.queryOne('.x-resizable-r').on('dragmove', function(e){



 resize();  // 更改代理的大小



});



document.queryOne('.x-resizable-r').on('dragend', function(e){



 hideProxy();  // 显示代理



});

function showProxy(){

    $('proxy').show(); // 显示代理

    $('proxy').setBound(  $('elem').getBound() );  // 更改位置和大小 (具体实现见本系列(五))

}



function resize(e){   



   resizeEl(e, $('proxy');   // 根据e修改大小。

}





function hideProxy(e){

    $('proxy').hide(); // 显示代理



     resizeEl(e, $('elem'));  

   

}





function resizeEl(e, tg){     // 根据e修改大小。

   

    tg.resizeBy(  e.delta );   

  

    if({'x-resizable-l':1, 'x-resizable-t':1}[e.target.className]) {   // 如果是左上方向,需同时移动偏移位置。

       tg.moveBy( e.delta.plus(-1) );  // 移动的方向和大小改变的是相反。

    }

}

  6. 以上是对 left - top - bottom - right 实现,那角落如何处理(以右下角例)。

     其实在上面已经藏着玄机。 当鼠标按下右下角的滑块,其实也按了右滑块,下滑块。所以,把右下角的滑块事件转为右滑块,下滑块的结合(同时进行)

     这是 Ext未使用的方法, 有个优点,就是节约代码。

    所以上面的代码已经实现了每个角落的事件。

最后说个细节:

鼠标在拖到时,希望保持箭头方向,但除部分浏览器,其它浏览器会随文本更新鼠标样式。

最简单是方法为 设置 document.body.setStyle('cursor', 'resizer-x')

但这时 Chrome 仍然按因 select 更改鼠标 。

Ext 采用 layer 式处理, 即 在拖到前,全局加上 layer(透明,全局) 全部拖动都在 layer 上触发,这样兼容任何浏览器。

resize始终是麻烦的效果。做的时候需要仔细。否则会有各种问题。

你可能感兴趣的:(resize)