前阵子新版专辑管理项目开发中碰到比较郁闷的问题,经测试最终决定给Sortables打个小补丁。
由于对选择状态的文本内容、连接和图片等进行拖放操作会触发系统的默认动作,例如ie中拖动图片鼠标会变成禁止操作状态,这样会导致这个拖放程序执行失败,所以Mootools 的Drag基类配置里其实有preventDefault配置项来给使用者解决此类问题,默认值为false,需要处理时设置为true即可。
然而郁闷的是,开发时才发现,Sortables类里内部创建的Drag.Move实例却只能使用preventDefault的默认值,因为Sortables没有给出配置项用来设置内部(this.drag)这个DragMove实例的preventDefault参数项。无奈之下,只能打补丁了。
另打补丁期间又发现另一个问题,甚是郁闷。Sortables的start方法仅判断是否空闲进而决定是否真正执行。而实际项目需求有时需要屏蔽鼠标右键(带来的问题很多),而看了办法发现,找到的唯一办法仍旧是打补丁。
最终,打上2处补丁后,世界清静了。。。
源代码:
var Sortables = new Class({
Implements: [Events, Options],
options: {/*
onSort: $empty(element, clone),
onStart: $empty(element, clone),
onComplete: $empty(element),*/
snap: 4,
opacity: 1,
clone: false,
revert: false,
handle: false,
constrain: false
},
……
start: function(event, element){
if (!this.idle) return;
this.idle = false;
this.element = element;
this.opacity = element.get('opacity');
this.list = element.getParent();
this.clone = this.getClone(event, element);
this.drag = new Drag.Move(this.clone, {
snap: this.options.snap,
container: this.options.constrain && this.element.getParent(),
droppables: this.getDroppables(),
onSnap: function(){
event.stop();
this.clone.setStyle('visibility', 'visible');
this.element.set('opacity', this.options.opacity || 0);
this.fireEvent('start', [this.element, this.clone]);
}.bind(this),
onEnter: this.insert.bind(this),
onCancel: this.reset.bind(this),
onComplete: this.end.bind(this)
});
this.clone.inject(this.element, 'before');
this.drag.start(event);
},
……
补丁后:
var Sortables = new Class({
Implements: [Events, Options],
options: {/*
onSort: $empty(element, clone),
onStart: $empty(element, clone),
onComplete: $empty(element),*/
snap: 4,
opacity: 1,
clone: false,
revert: false,
handle: false,
constrain: false,
rightClickAble: false, // add by myself
preventDefault:false // add by myself
},
……
start: function(event, element){
if (!this.idle || (!this.options.rightClickAble && event.rightClick)) return; // modified by myself
this.idle = false;
this.element = element;
this.opacity = element.get('opacity');
this.list = element.getParent();
this.clone = this.getClone(event, element);
this.drag = new Drag.Move(this.clone, {
snap: this.options.snap,
container: this.options.constrain && this.element.getParent(),
droppables: this.getDroppables(),
preventDefault:!!this.options.preventDefault, // add by myself
onSnap: function(){
event.stop();
this.clone.setStyle('visibility', 'visible');
this.element.set('opacity', this.options.opacity || 0);
this.fireEvent('start', [this.element, this.clone]);
}.bind(this),
onEnter: this.insert.bind(this),
onCancel: this.reset.bind(this),
onComplete: this.end.bind(this)
});
this.clone.inject(this.element, 'before');
this.drag.start(event);
},
……