投放本站广告请联系:
extjscn#126.com
ExtJS 4 拖放[drag and drop]
定义拖放
一个拖动操作,就是在某个页面元素上按下鼠标并移动。一个放下操作,就是在拖动动作之后放开鼠标。可以从下图来看:
Ext JS 的Ext.dd 类中定义了基本的拖放操作。
拖放类的组织
所有的拖放类基本上都归类到Drag or Drop 组中
手头的任务
这里的例子是一个租车公司,把轿车和卡车有三种状态: 闲置,租用和修理。该应用就是可以在这三个状态
使用DD,让可选轿车和卡车可以拖动; 而后,使用 DDTarget,让租车和修理的容器可以接受拖放;最后使用不同的拖放组让轿车和卡车只能拖到指定的区块。
Step 1: 开始拖动
让以上可选的轿车和卡车可以拖动:
Ext.onReady(function() { // Create an object that we'll use to implement and override drag behaviors a little later var overrides = {}; // Configure the cars to be draggable var carElements = Ext.get('cars').select('div'); Ext.each(carElements.elements, function(el) { var dd = Ext.create('Ext.dd.DD', el, 'carsDDGroup', { isTarget : false }); //Apply the overrides object to the newly created instance of DD Ext.apply(dd, overrides); }); var truckElements = Ext.get('trucks').select('div'); Ext.each(truckElements.elements, function(el) { var dd = Ext.create('Ext.dd.DD', el, 'trucksDDGroup', { isTarget : false }); Ext.apply(dd, overrides); }); });
以上使用DomQuery的方式找到需要拖动的区块,并针对里面的子元素创建了DD的实例。
对于轿车和卡车用了不同的分组。(可以拖放的位置不同)
这里定义了一个空的对象 overrides, 并且把这个对象通过Ext.apply应用到创建的 DD 的对象上。
看一下拖动效果的实质
从以上可以看出, 一个元素有三个CSS的属性; position, top 和 left;
Step 2: 修复无效的拖放
最简单的修复方式就是,拖动失败之后让样式恢复到拖动前的状况,这样的处理看起来有点枯燥,所以,可以用Ext.Fx 添加动画的效果。还记得拖放类的设计有overridden 的方法,要实现这个效果,需要覆写b4StartDrag, onInvalidDrop 和endDrag这些方法。看下例:
var overrides = { // Called the instance the element is dragged. b4StartDrag : function() { // Cache the drag element if (!this.el) { this.el = Ext.get(this.getEl()); } //Cache the original XY Coordinates of the element, we'll use this later. this.originalXY = this.el.getXY(); }, // Called when element is dropped not anything other than a dropzone with the same ddgroup onInvalidDrop : function() { // Set a flag to invoke the animated repair this.invalidDrop = true; }, // Called when the drag operation completes endDrag : function() { // Invoke the animation if the invalidDrop flag is set to true if (this.invalidDrop === true) { // Remove the drop invitation this.el.removeCls('dropOK'); // Create the animation configuration object var animCfgObj = { easing : 'elasticOut', duration : 1, scope : this, callback : function() { // Remove the position attribute this.el.dom.style.position = ''; } }; // Apply the repair animation this.el.moveTo(this.originalXY[0], this.originalXY[1], animCfgObj); delete this.invalidDrop; } },
效果:
Step 3: 配置放下的目标(drop targets)
// Instantiate instances of Ext.dd.DDTarget for the cars and trucks container var carsDDTarget = Ext.create('Ext.dd.DDTarget', 'cars','carsDDGroup'); var trucksDDTarget = Ext.create('Ext.dd.DDTarget', 'trucks', 'trucksDDGroup'); // Instantiate instnaces of DDTarget for the rented and repair drop target elements var rentedDDTarget = Ext.create('Ext.dd.DDTarget', 'rented', 'carsDDGroup'); var repairDDTarget = Ext.create('Ext.dd.DDTarget', 'repair', 'carsDDGroup'); // Ensure that the rented and repair DDTargets will participate in the trucksDDGroup rentedDDTarget.addToGroup('trucksDDGroup'); repairDDTarget.addToGroup('trucksDDGroup');
这里代码为 轿车,卡车,租赁和修理的区块添加了drop targets. 轿车容器仅接收"carsDDGroup" 的drag, 卡车容器仅接收“trucksDDGroup”;
接着定义了rentedDDTarget 和repairDDTarget并且只接收 “carsDDGroup”, 为了让“trucksDDGroup”也可以,通过 addToGroup 方式进行添加。
效果:
以上的拖放可以拖放到指定位置,可能出现重叠等问题。
Step 4: 继续 完成Drop
var overrides = { ... // Called upon successful drop of an element on a DDTarget with the same onDragDrop : function(evtObj, targetElId) { // Wrap the drop target element with Ext.Element var dropEl = Ext.get(targetElId); // Perform the node move only if the drag element's // parent is not the same as the drop target if (this.el.dom.parentNode.id != targetElId) { // Move the element dropEl.appendChild(this.el); // Remove the drag invitation this.onDragOut(evtObj, targetElId); // Clear the styles this.el.dom.style.position =''; this.el.dom.style.top = ''; this.el.dom.style.left = ''; } else { // This was an invalid drop, initiate a repair this.onInvalidDrop(); } },
效果:
Step 5 : 添加放下邀请(Drop Invitation)
当拖放操作完成时,添加一些反馈信息给用户。
重写onDragEnter 和onDragOut 方法。
var overrides = { ... // Only called when the drag element is dragged over the a drop target with the same ddgroup onDragEnter : function(evtObj, targetElId) { // Colorize the drag target if the drag node's parent is not the same as the drop target if (targetElId != this.el.dom.parentNode.id) { this.el.addCls('dropOK'); } else { // Remove the invitation this.onDragOut(); } }, // Only called when element is dragged out of a dropzone with the same ddgroup onDragOut : function(evtObj, targetElId) { this.el.removeCls('dropOK'); } };
作者: oscar999
原文: http://blog.csdn.net/oscar999/article/details/9561883
- 要发表评论,请先登录