1 /** 2 * @fileOverview delegate all draggable nodes to one draggable object 3 * @author yiminghe@gmail.com 4 */ 5 KISSY.add("dd/draggable-delegate", function (S, DDM, Draggable, DOM, Node) { 6 7 var PREFIX_CLS = DDM.PREFIX_CLS; 8 9 /** 10 * @name DraggableDelegate 11 * @extends DD.Draggable 12 * @memberOf DD 13 * @class 14 * drag multiple nodes under a container element 15 * using only one draggable instance as a delegate. 16 */ 17 function DraggableDelegate() { 18 DraggableDelegate.superclass.constructor.apply(this, arguments); 19 } 20 21 22 /** 23 * 父容器监听 mousedown,找到合适的拖动 handlers 以及拖动节点 24 * @param ev 25 */ 26 function handleMouseDown(ev) { 27 var self = this, 28 handler, 29 node; 30 31 if (!self._checkMouseDown(ev)) { 32 return; 33 } 34 35 var handlers = self.get("handlers"), 36 target = new Node(ev.target); 37 38 // 不需要像 Draggble 一样,判断 target 是否在 handler 内 39 // 委托时,直接从 target 开始往上找 handler 40 if (handlers.length) { 41 handler = self._getHandler(target); 42 } else { 43 handler = target; 44 } 45 46 if (handler) { 47 node = self._getNode(handler); 48 } 49 50 // can not find handler or can not find matched node from handler 51 // just return ! 52 if (!node) { 53 return; 54 } 55 56 self.__set("activeHandler", handler); 57 58 // 找到 handler 确定 委托的 node ,就算成功了 59 self.__set("node", node); 60 self.__set("dragNode", node); 61 self._prepare(ev); 62 } 63 64 S.extend(DraggableDelegate, Draggable, { 65 66 _uiSetDisabledChange:function (d) { 67 this.get("container")[d ? 'addClass' : 68 'removeClass'](PREFIX_CLS + '-disabled'); 69 }, 70 71 _init:function () { 72 var self = this, 73 node = self.get('container'); 74 node.on('mousedown', handleMouseDown, self) 75 .on('dragstart', self._fixDragStart); 76 }, 77 78 /** 79 * 得到适合 handler,从这里开始启动拖放,对于 handlers 选择器字符串数组 80 * @param target 81 */ 82 _getHandler:function (target) { 83 var self = this, 84 ret = undefined, 85 node = self.get("container"), 86 handlers = self.get('handlers'); 87 while (target && target[0] !== node[0]) { 88 S.each(handlers, function (h) { 89 if (DOM.test(target[0], h)) { 90 ret = target; 91 return false; 92 } 93 }); 94 if (ret) { 95 break; 96 } 97 target = target.parent(); 98 } 99 return ret; 100 }, 101 102 /** 103 * 找到真正应该移动的节点,对应 selector 属性选择器字符串 104 * @param h 105 */ 106 _getNode:function (h) { 107 return h.closest(this.get("selector"), this.get("container")); 108 }, 109 110 destroy:function () { 111 var self = this; 112 self.get("container") 113 .detach('mousedown', 114 handleMouseDown, 115 self) 116 .detach('dragstart', self._fixDragStart); 117 self.detach(); 118 } 119 }, 120 { 121 ATTRS:/** 122 * @lends DD.DraggableDelegate# 123 */ 124 { 125 /** 126 * a selector query to get the container to listen for mousedown events on. 127 * All "draggable selector" should be a child of this container 128 * @type {HTMLElement|String} 129 */ 130 container:{ 131 setter:function (v) { 132 return Node.one(v); 133 } 134 }, 135 136 /** 137 * a selector query to get the children of container to make draggable elements from. 138 * usually as for tag.cls. 139 * @type {String} 140 */ 141 selector:{ 142 }, 143 144 /** 145 * handlers to initiate drag operation. 146 * can only be as form of tag.cls. 147 * default:[selector] 148 * @type {String[]} 149 **/ 150 handlers:{ 151 value:[], 152 // 覆盖父类的 getter ,这里 normalize 成节点 153 getter:0 154 } 155 } 156 }); 157 158 return DraggableDelegate; 159 }, { 160 requires:['./ddm', './draggable', 'dom', 'node'] 161 });