投放本站广告请联系:
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
- 要发表评论,请先登录

