示例

基本形式

<jr-draggable value="success"><div class="u-color u-color-success">拖我</div></jr-draggable>
<jr-draggable value="warning"><div class="u-color u-color-warning">拖我</div></jr-draggable>
<jr-draggable value="error"><div class="u-color u-color-error">拖我</div></jr-draggable>
<p></p>
<jr-droppable value={dropData}><div class="u-color u-color-{dropData || 'primary'}">放到这里</div></jr-droppable>
### 事件 请打开浏览器的控制台查看结果。
<jr-draggable value="success"
on-dragstart={console.log('on-dragstart:', '$event:', $event)}
on-dragend={console.log('on-dragend:', '$event:', $event)}>
<div class="u-color u-color-success">拖我</div>
</jr-draggable>
<jr-droppable value={dropData}
on-dragenter={console.log('on-dragenter:', '$event:', $event)}
on-dragleave={console.log('on-dragleave:', '$event:', $event)}
on-drop={console.log('on-drop:', '$event:', $event)}>
<div class="u-color u-color-{dropData || 'primary'}">放到这里</div>
</jr-droppable>

列表排序(占位型)

<div class="g-row">
<div class="g-col g-col-6">
<jr-droppable on-dragover={this._onListDragOver($event, {list: listA})}>
<ul class="m-listview m-listview-gutter">
{#list listA as item}
<jr-droppable
on-dragover={this._onDragOver($event, {list: listA})}>
<jr-draggable value={ @({item: item, list: listA}) }
on-dragend={this._onDragEnd($event)}>
<li><div>{item.text}</div></li>
</jr-draggable>
</jr-droppable>
{/list}
</ul>
</jr-droppable>
</div>
<div class="g-col g-col-6">
<jr-droppable on-dragover={this._onListDragOver($event, {list: listB})}>
<ul class="m-listview m-listview-gutter">
{#list listB as item}
<jr-droppable
on-dragover={this._onDragOver($event, {list: listB})}>
<jr-draggable value={ @({item: item, list: listB}) }
on-dragend={this._onDragEnd($event)}>
<li><div>{item.text}</div></li>
</jr-draggable>
</jr-droppable>
{/list}
</ul>
</jr-droppable>
</div>
</div>
let component = new JRUI.Component({
template,
data: {
listA: [
{text: '选项A1'},
{text: '选项A2'},
{text: '选项A3'},
{text: '选项A4'},
{text: '选项A5'},
],
listB: [
{text: '选项B1'},
{text: '选项B2'},
{text: '选项B3'},
{text: '选项B4'},
{text: '选项B5'},
],
},
_getElementIndex(element) {
return Array.prototype.indexOf.call(element.parentElement.children, element);
},
_onDragOver($event, tgt) {
let source = $event.source;
let target = $event.target;
// 排除source和target相同的情况
if(source === target)
return;
let sourceParent = source.parentElement;
let targetParent = target.parentElement;
let sourceIndex = this._getElementIndex(source);
let targetIndex = this._getElementIndex(target);
// 删除起始元素
sourceParent.removeChild(source);
// 再将起始元素插入到新的位置
if(sourceIndex >= targetIndex || sourceParent !== targetParent)
targetParent.insertBefore(source, target);
else
targetParent.insertBefore(source, target.nextElementSibling);
// 记录目标列表
this.data.tgt = tgt;
},
_onListDragOver($event, tgt) {
let source = $event.source;
let sourceParent = source.parentElement;
let targetParent = $event.target;
// 删除起始元素
sourceParent.removeChild(source);
// 再将起始元素插入到新的位置
targetParent.appendChild(source);
this.data.tgt = tgt;
},
_onDragEnd($event) {
let src = $event.value;
let tgt = this.data.tgt;
if(!tgt) return;
// 获取起始元素的初始位置
src.index = src.list.indexOf(src.item);
// 获取起始元素的结束位置
tgt.index = this._getElementIndex($event.source);
// 从起始列表中删除对象
src.list.splice(src.index, 1);
// 在目标列表中插入对象
tgt.list.splice(tgt.index, 0, src.item);
}
});

网格排序(占位型)

<jr-droppable on-dragover={this._onListDragOver($event)}>
<ul class="m-gridView">
{#list list as item}
<jr-droppable
on-dragover={this._onDragOver($event)}>
<jr-draggable
value={item}
on-dragend={this._onDragEnd($event)}>
<li><div class="u-brick">{item.text}</div></li>
</jr-draggable>
</jr-droppable>
{/list}
</ul>
</jr-droppable>
let _ = JRUI.util;
let list = [];
for(let i = 0; i < 15; i++)
list.push({text: '选项C' + i});
let component = new JRUI.Component({
template: template,
data: {list: list},
_getElementIndex(element) {
return Array.prototype.indexOf.call(element.parentElement.children, element);
},
_onDragOver($event, tgt) {
let source = $event.source;
let target = $event.target;
// 排除source和target相同的情况
if(source === target)
return;
let sourceParent = source.parentElement;
let targetParent = target.parentElement;
let sourceIndex = this._getElementIndex(source);
let targetIndex = this._getElementIndex(target);
// 删除起始元素
sourceParent.removeChild(source);
// 再将起始元素插入到新的位置
if(sourceIndex >= targetIndex || sourceParent !== targetParent)
targetParent.insertBefore(source, target);
else
targetParent.insertBefore(source, target.nextElementSibling);
// 记录目标列表
this.data.tgt = tgt;
},
_onListDragOver($event, tgt) {
let source = $event.source;
let sourceParent = source.parentElement;
let targetParent = $event.target;
// 删除起始元素
sourceParent.removeChild(source);
// 再将起始元素插入到新的位置
targetParent.appendChild(source);
this.data.tgt = tgt;
},
_onDragEnd($event) {
let src = $event.value;
let tgt = this.data.tgt;
if(!tgt) return;
// 获取起始元素的初始位置
src.index = src.list.indexOf(src.item);
// 获取起始元素的结束位置
tgt.index = this._getElementIndex($event.source);
// 从起始列表中删除对象
src.list.splice(src.index, 1);
// 在目标列表中插入对象
tgt.list.splice(tgt.index, 0, src.item);
}
});

列表排序(标记型)

<div class="g-row">
<div class="g-col g-col-6">
<ul class="m-listview">
{#list listA as item}
<jr-droppable
on-dragover={this._onDragOver($event)}
on-drop={this._onDrop($event, {item: item, list: listA})}>
<jr-draggable value={ @({item: item, list: listA}) }>
<li>{item.text}</li>
</jr-draggable>
</jr-droppable>
{/list}
</ul>
</div>
<div class="g-col g-col-6">
<ul class="m-listview">
{#list listB as item}
<jr-droppable
on-dragover={this._onDragOver($event)}
on-drop={this._onDrop($event, {item: item, list: listB})}>
<jr-draggable value={ @({item: item, list: listB}) }>
<li>{item.text}</li>
</jr-draggable>
</jr-droppable>
{/list}
</ul>
</div>
</div>
let component = new JRUI.Component({
template,
data: {
listA: [
{text: '选项A1'},
{text: '选项A2'},
{text: '选项A3'},
{text: '选项A4'},
{text: '选项A5'},
],
listB: [
{text: '选项B1'},
{text: '选项B2'},
{text: '选项B3'},
{text: '选项B4'},
{text: '选项B5'},
],
},
_onDragOver($event) {
let target = $event.target;
Regular.dom.delClass(target, 'z-dragTarget-before');
Regular.dom.delClass(target, 'z-dragTarget-after');
Regular.dom.addClass(target, 'z-dragTarget-' + ($event.ratioY < 0.5 ? 'before' : 'after'));
},
_onDrop($event, tgt) {
let target = $event.target;
Regular.dom.delClass(target, 'z-dragTarget-before');
Regular.dom.delClass(target, 'z-dragTarget-after');
let src = $event.value;
src.index = src.list.indexOf(src.item);
tgt.index = tgt.list.indexOf(tgt.item);
// 从起始列表中删除对象
src.list.splice(src.index, 1);
// 计算目标列表中插入位置的index
if(src.list === tgt.list) tgt.index--;
if($event.ratioY >= 0.5) tgt.index++;
if(tgt.index < 0) tgt.index = 0;
// 在目标列表中插入对象
tgt.list.splice(tgt.index, 0, src.item);
console.log(src.item.text, 'insert', $event.ratioY < 0.5 ? 'before' : 'after', tgt.item.text);
}
});

列表排序(标记型) - 加强版

<div class="g-row">
<div class="g-col g-col-6">
<jr-droppable
on-dragover={this._onDragOver($event)}
on-drop={this._onListDrop($event, {list: listA})}>
<ul class="m-listview m-listview-gutter">
{#list listA as item}
<jr-droppable
on-dragover={this._onDragOver($event)}
on-drop={this._onDrop($event, {item: item, list: listA})}>
<jr-draggable value={ @({item: item, list: listA}) }>
<li><div>{item.text}</div></li>
</jr-draggable>
</jr-droppable>
{/list}
</ul>
</jr-droppable>
</div>
<div class="g-col g-col-6">
<jr-droppable
on-dragover={this._onDragOver($event)}
on-drop={this._onListDrop($event, {list: listB})}>
<ul class="m-listview m-listview-gutter">
{#list listB as item}
<jr-droppable
on-dragover={this._onDragOver($event)}
on-drop={this._onDrop($event, {item: item, list: listB})}>
<jr-draggable value={ @({item: item, list: listB}) }>
<li><div>{item.text}</div></li>
</jr-draggable>
</jr-droppable>
{/list}
</ul>
</jr-droppable>
</div>
</div>
let component = new JRUI.Component({
template,
data: {
listA: [
{text: '选项A1'},
{text: '选项A2'},
{text: '选项A3'},
{text: '选项A4'},
{text: '选项A5'},
],
listB: [
{text: '选项B1'},
{text: '选项B2'},
{text: '选项B3'},
{text: '选项B4'},
{text: '选项B5'},
],
},
_onDragOver($event) {
let target = $event.target;
Regular.dom.delClass(target, 'z-dragTarget-before');
Regular.dom.delClass(target, 'z-dragTarget-after');
Regular.dom.addClass(target, 'z-dragTarget-' + ($event.ratioY < 0.5 ? 'before' : 'after'));
},
_onDrop($event, tgt) {
let target = $event.target;
Regular.dom.delClass(target, 'z-dragTarget-before');
Regular.dom.delClass(target, 'z-dragTarget-after');
let src = $event.value;
src.index = src.list.indexOf(src.item);
tgt.index = tgt.list.indexOf(tgt.item);
// 从起始列表中删除对象
src.list.splice(src.index, 1);
// 计算目标列表中插入位置的index
if(src.list === tgt.list) tgt.index--;
if($event.ratioY >= 0.5) tgt.index++;
if(tgt.index < 0) tgt.index = 0;
// 在目标列表中插入对象
tgt.list.splice(tgt.index, 0, src.item);
console.log(src.item.text, 'insert', $event.ratioY < 0.5 ? 'before' : 'after', tgt.item.text);
},
_onListDrop($event, tgt) {
this._onDrop($event, {
list: tgt.list,
item: tgt.list[$event.ratioY >= 0.5 ? tgt.list.length - 1 : 0]
});
}
});

API

Classes

JRDroppableComponent

Constants

Component

JRDroppable 放入

Functions

config()
init()
destroy()

Events

“dragenter 拖拽进入该元素时触发”
“dragleave 拖拽离开该元素时触发”
“dragover 拖拽在该元素上方时触发”
“drop 拖拽放置时触发”

JRDroppable ⇐ Component

Kind: global class
Extends: Component

new JRDroppable()

Param Type Default Description
[options.data] Object = 绑定属性
[options.data.value] var <= 拖放后传递过来的值
[options.data.disabled] boolean false => 是否禁用
[options.data.class] string "'z-droppable'" => 可放置时(即disabled=false)给元素附加此class
[options.data.dragTarget] string "'z-dragTarget'" => 拖拽在该元素上方时给该元素附加此class

Component


JRDroppable 放入

Kind: global constant

config()

Kind: global function
Access: protected

init()

Kind: global function
Access: protected

destroy()

Kind: global function
Access: protected

“dragenter 拖拽进入该元素时触发”

Kind: event emitted
Properties

Name Type Description
sender object 事件发送对象,为当前droppable
origin object 拖拽源,为拖拽的draggable
source object 拖拽起始元素
proxy object 拖拽代理元素
target object 拖拽目标元素
value object 拖拽时接收到的值
screenX number 鼠标指针相对于屏幕的水平位置
screenY number 鼠标指针相对于屏幕的垂直位置
clientX number 鼠标指针相对于浏览器的水平位置
clientY number 鼠标指针相对于浏览器的垂直位置
pageX number 鼠标指针相对于页面的水平位置
pageY number 鼠标指针相对于页面的垂直位置
startX number 拖拽开始时鼠标指针的水平坐标
startY number 拖拽开始时鼠标指针的垂直坐标
dragX number 拖拽时鼠标指针相对于起始坐标的水平位移
dragY number 拖拽时鼠标指针相对于起始坐标的垂直位移
startLeft number 拖拽开始时代理元素的left值
startTop number 拖拽开始时代理元素的top值
left number 拖拽时代理元素的left值
top number 拖拽时代理元素的top值
cancel function 取消拖拽操作

“dragleave 拖拽离开该元素时触发”

Kind: event emitted
Properties

Name Type Description
sender object 事件发送对象,为当前droppable
origin object 拖拽源,为拖拽的draggable
source object 拖拽起始元素
proxy object 拖拽代理元素
target object 拖拽目标元素
value object 拖拽时接收到的值
screenX number 鼠标指针相对于屏幕的水平位置
screenY number 鼠标指针相对于屏幕的垂直位置
clientX number 鼠标指针相对于浏览器的水平位置
clientY number 鼠标指针相对于浏览器的垂直位置
pageX number 鼠标指针相对于页面的水平位置
pageY number 鼠标指针相对于页面的垂直位置
startX number 拖拽开始时鼠标指针的水平坐标
startY number 拖拽开始时鼠标指针的垂直坐标
dragX number 拖拽时鼠标指针相对于起始坐标的水平位移
dragY number 拖拽时鼠标指针相对于起始坐标的垂直位移
startLeft number 拖拽开始时代理元素的left值
startTop number 拖拽开始时代理元素的top值
left number 拖拽时代理元素的left值
top number 拖拽时代理元素的top值
cancel function 取消拖拽操作

“dragover 拖拽在该元素上方时触发”

Kind: event emitted
Properties

Name Type Description
sender object 事件发送对象,为当前droppable
origin object 拖拽源,为拖拽的draggable
source object 拖拽起始元素
proxy object 拖拽代理元素
target object 拖拽目标元素
value object 拖拽时接收到的值
ratioX number 鼠标指针相对于接收元素所占的长度比
ratioY number 鼠标指针相对于接收元素所占的高度比
screenX number 鼠标指针相对于屏幕的水平位置
screenY number 鼠标指针相对于屏幕的垂直位置
clientX number 鼠标指针相对于浏览器的水平位置
clientY number 鼠标指针相对于浏览器的垂直位置
pageX number 鼠标指针相对于页面的水平位置
pageY number 鼠标指针相对于页面的垂直位置
startX number 拖拽开始时鼠标指针的水平坐标
startY number 拖拽开始时鼠标指针的垂直坐标
dragX number 拖拽时鼠标指针相对于起始坐标的水平位移
dragY number 拖拽时鼠标指针相对于起始坐标的垂直位移
startLeft number 拖拽开始时代理元素的left值
startTop number 拖拽开始时代理元素的top值
left number 拖拽时代理元素的left值
top number 拖拽时代理元素的top值
cancel function 取消拖拽操作

“drop 拖拽放置时触发”

Kind: event emitted
Properties

Name Type Description
sender object 事件发送对象,为当前droppable
origin object 拖拽源,为拖拽的draggable
source object 拖拽起始元素
proxy object 拖拽代理元素
target object 拖拽目标元素
value object 拖拽时接收到的值
ratioX number 鼠标指针相对于接收元素所占的长度比
ratioY number 鼠标指针相对于接收元素所占的高度比
screenX number 鼠标指针相对于屏幕的水平位置
screenY number 鼠标指针相对于屏幕的垂直位置
clientX number 鼠标指针相对于浏览器的水平位置
clientY number 鼠标指针相对于浏览器的垂直位置
pageX number 鼠标指针相对于页面的水平位置
pageY number 鼠标指针相对于页面的垂直位置
startX number 拖拽开始时鼠标指针的水平坐标
startY number 拖拽开始时鼠标指针的垂直坐标
dragX number 拖拽时鼠标指针相对于起始坐标的水平位移
dragY number 拖拽时鼠标指针相对于起始坐标的垂直位移
startLeft number 拖拽开始时代理元素的left值
startTop number 拖拽开始时代理元素的top值
left number 拖拽时代理元素的left值
top number 拖拽时代理元素的top值