[英]jQuery Draggable - Create draggable and start dragging on html5 native Drag And Drop api event
好吧,基本上我想要尝试实现的是,当一个dragover
事件从HTML5 Drag And Drop API
触发时,我希望创建一个jQuery draggable
对象,并开始跟随鼠标,而dragend
事件从HTML5 Drag And Drop API
dragend
中触发HTML5 Drag And Drop API
。
我想这样做的原因如下:
jQuery.ui draggable
to function(它是FullCalendar Scheduler
插件,版本3) HTML5 Drag and Drop API
,并且jQuery.ui draggable
无法将元素从一个浏览器窗口拖动到另一个浏览器窗口,我认为我唯一的选择是混合使用这两个插件。 我提出的解决这个问题的方法是,使用原生的HTML5 Drag and Drop API
,当拖动的元素到达一个dropzone
,在浏览器窗口B中创建一个新的可拖动元素,并在其上模拟一个mousedown
事件,所以它开始跟随光标。 当dragend
事件发生时,我计划简单地简单地在draggable
元素上触发mouseup
事件,并且从调度程序插件开始就可以实现它的魔力。
为了尝试对此进行测试,首先使用单个浏览器窗口,我试图实现上述解决方案的第一部分,即:当dragover
触发时,创建jQuery.ui draggable
并在其上模拟mousedown
,然后它应该开始跟随鼠标。 我无法实现这种行为。
我做了一个小提琴,你可以看到我到目前为止所尝试的内容(我不是在这里发布整个代码,因为它很长): JSFiddle
基本上,我在小提琴中得到的错误,我尝试过的两个选项都是type.indexOf is not a function
错误。
我还询问并获得了一些关于以下问题的帮助,当使用click
事件开始拖动操作时,建议的解决方案可以正常工作,但它不适用于任何其他事件类型。 我按下,我只能从MouseEvent
模拟mousedown.draggable
事件,而dragend
事件不是MouseEvent
。
长话短说,我需要帮助才能获得我想要的结果,至少对于我提出的解决方案的第一部分!
这似乎没有一个好的答案。 首先,并非所有浏览器都支持相同的DnD术语或功能。 例如FireFox在drop上触发dragenter
事件,当对象来自另一个窗口时,Chrome似乎没有检测到drop
事件。
这是我到目前为止的测试。 要使用,请将内容复制到文本文件中并另存为HTM或HTML。 然后在浏览器中本地打开文件。 打开另一个窗口并打开第二个HTM。 现在你有两个可以拖拽的窗户。
WINA-1.htm
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Window A</title>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<style>
.items {
position: relative;
}
.items > div {
margin-right: 5px;
width: 150px;
height: 150px;
padding: 0.5em;
border-radius: 6px;
display: inline-block;
}
#log {
width: 100%;
height: 5em;
overflow-y: auto;
}
[draggable].idle {
background-color: rgba(255,0,0,0.75);
}
[draggable].selected {
background-color: rgba(255,0,0,0.95);
}
</style>
</head>
<body>
<pre id="log"></pre>
<div class="items ui-widget">
<div id="draggable" class="ui-widget-content idle" draggable="true">
<p>Drag me around</p>
</div>
<div id="static" class="ui-widget-content">
<p>I can't be moved</p>
</div>
</div>
<script>
var srcEl;
function log(s){
var now = new Date();
var t = now.getHours() + ":" + now.getMinutes() + ":" + now.getSeconds()
+ "." + now.getMilliseconds();
var l = document.getElementById("log");
l.append(t + ": " + s + "\r\n");
l.scrollTop = l.scrollHeight;
}
function dragStart(e){
log("Drag Start: " + e.target.nodeName + "#" + e.target.id);
srcEl = e.target;
if(e.dataTransfer == undefined){} else {
e.dataTransfer.effectAllowed = "copyMove";
log("Event dataTransfer.effectAllowed: " +
e.dataTransfer.effectAllowed);
log("Source Element: " + srcEl.nodeName + "#" + srcEl.id);
}
this.classList.add("selected");
}
function dragOver(e){
e.preventDefault();
log("Drag Over: " + e.target.nodeName + (e.target.id != "" ? "#" +
e.target.id : ""));
return false;
}
function dragLeave(e){
log("Drag Leave: " + e.target.nodeName + (e.target.id != "" ? "#" +
e.target.id : ""));
}
function dragStop(e){
log("Drag End: " + e.target.nodeName + "#" + e.target.id);
this.classList.remove("selected");
}
log("Init");
var item = document.getElementById("draggable");
item.addEventListener('dragstart', dragStart, false);
item.addEventListener('dragover', dragOver, false);
item.addEventListener('dragleave', dragLeave, false);
window.addEventListener('dragleave', dragLeave, false);
var items = document.querySelectorAll('.items > div');
[].forEach.call(items, function(el) {
el.addEventListener('dragover', dragOver, false);
});
</script>
</body>
</html>
如您所见,这是使用原始JavaScript。 我正在修改jQuery UI,我保留样式表只是为了方便他们。 我们有一个部分用于打印日志详细信息,可拖动项和静态项。
winb-1.htm
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Window B</title>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<style>
.drag-item {
width: 100px;
height: 100px;
background-color: red;
}
body {
position: relative;
}
div.drag-helper {
width: 100px;
height: 100px;
background-color: red;
z-index: 1002;
position: relative;
}
#log {
width: 100%;
height: 5em;
line-height: 1em;
font-size: 1em;
overflow-y: auto;
}
#dropzone {
background-color: green;
width: 95%;
height: 340px;
}
</style>
</head>
<body>
<pre id="log"></pre>
<div id="dropzone"></div>
<script>
jQuery(function($) {
function log(s){
var now = new Date();
var t = now.getHours() + ":" + now.getMinutes() + ":" + now.getSeconds
() + "." + now.getMilliseconds();
$("#log").append(t + ": " + s + "\r\n").scrollTop($("#log").prop
("scrollHeight"));
}
function dragEnter(e){
e.preventDefault();
log("Drag Enter triggered: " + $(e.target).prop("nodeName") +
($(e.target).attr("id").length ? "#" + $(e.target).attr("id") : ""));
}
function dragOver(e){
log("Drag Over triggered: " + $(e.target).prop("nodeName") +
($(e.target).attr("id").length ? "#" + $(e.target).attr("id") : ""));
e.dataTransfer.dropEffect = 'move';
e.preventDefault();
}
function handleDrop(e){
if (e.stopPropagation) {
e.stopPropagation();
}
log("Drop Triggered: " + $(e.target).attr("id"));
return false;
}
function dragEnd(e){
log("Drag End Triggered: " + $(e.target).prop("nodeName") +
($(e.target).attr("id").length ? "#" + $(e.target).attr("id") : ""));
}
log("Init");
$("#dropzone").on({
dragenter: dragEnter,
dragover: dragOver,
drop: handleDrop,
mouseup: handleDrop,
dragend: dragEnd
});
$(window).on({
dragenter: dragEnter,
dragover: dragOver,
drop: handleDrop,
dragend: dragEnd
});
});
</script>
</body>
</html>
Window B使用jQuery,目的是将元素转换为jQuery UI Draggable。
首先要知道的是,在运输过程中无法做到。 由于Source元素不是目标DOM的一部分,因此无法完成。 它可以在drop
事件中添加并初始化为Draggable。 基本上会发生什么是在那时分配所有数据的新元素。
其次,数据传输是不可靠的,我会避免使用DataTransfer作为您的数据容器。 我建议使用localStorage。 这类似于cookie,更可靠。
例如,我创建了以下Data对象:
{
id,
type,
attr: {
id,
class,
width,
height
},
content
}
以下是一些示例函数:
function collectData(obj){
return {
id: obj.attr("id"),
type: obj.prop("nodeName"),
attr: {
id: obj.attr("id"),
class: obj.attr("class"),
width: obj.width(),
height: obj.height()
},
content: obj.text().trim()
};
}
function saveData(k, d){
localStorage.setItem(k, JSON.stringify(d));
}
function getData(k){
return JSON.parse(localStorage.getItem(k));
}
function makeEl(d, pObj){
return $("<" + d.type +">", d.attr).html("<p>" + d.content + "</p>").appendTo(pObj);
}
$("#draggable").on('dragstart', function(e){
saveData("drag-data", collectData($(this)));
});
$("#dropzone").on('drop', function(e){
var item = makeEl(getData('drag-data'), $(this));
item.addClass("clone").position({
my: "center",
of: e
}).draggable();
});
从理论上讲,这应该都有效。 在实践中,我遇到了很多障碍。 我会建议像点击复制类型的操作。 用户单击窗口A中的项目(选择它),然后单击他们希望它在窗口B中的位置。再次使用localStorage,可以将项目克隆到新位置。
WINA-3.htm
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery UI Draggable - Default functionality</title>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<style>
.items {
position: relative;
}
.items > div {
margin-right: 5px;
width: 150px;
height: 150px;
padding: 0.5em;
border-radius: 6px;
display: inline-block;
}
#log {
width: 100%;
height: 5em;
overflow-y: auto;
}
[draggable].idle {
background-color: rgba(255,0,0,0.5);
}
[draggable].selected {
background-color: rgba(255,0,0,0.95);
}
</style>
</head>
<body>
<pre id="log"></pre>
<div class="items ui-widget">
<div id="draggable" class="ui-widget-content idle" draggable="true">
<p>Click on me</p>
</div>
<div id="static" class="ui-widget-content">
<p>I can't be moved</p>
</div>
</div>
<script>
var intv;
function log(s){
var now = new Date();
var t = now.getHours() + ":" + now.getMinutes() + ":" + now.getSeconds() + "." + now.getMilliseconds();
var l = document.getElementById("log");
l.append(t + ": " + s + "\r\n");
l.scrollTop = l.scrollHeight;
}
function collectData(el){
return {
id: el.id,
type: el.nodeName,
attr: {
id: el.id,
class: el.className,
width: el.width,
height: el.height
},
content: el.innerText
};
}
function saveData(k, v){
localStorage.setItem(k, JSON.stringify(v));
}
function getData(k){
return JSON.parse(localStorage.getItem(k));
}
function clearData(k){
localStorage.setItem(k, null);
}
function selElem(e){
var trg = e.target.nodeName + (e.target.id != "" ? "#" + e.target.id : "");
if(e.target.classList.contains("selected")){
log("Deselect element: " + trg);
e.target.classList.remove("selected");
} else {
log("Element Selected: " + trg);
e.target.classList.add("selected");
saveData("select-data", collectData(e.target));
}
intv = setInterval(function(){
if(getData("select-data") == null){
document.getElementsByClassName("selected")[0].classList.remove("selected");
log("Unselected");
clearInterval(intv);
}
}, 1000);
}
log("Init");
var item = document.getElementById("draggable");
item.addEventListener('click', selElem);
</script>
</body>
</html>
winb-3.htm
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Window B</title>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<style>
.drag-item {
width: 100px;
height: 100px;
background-color: red;
}
body {
position: relative;
}
#log {
width: 100%;
height: 5em;
line-height: 1em;
font-size: 1em;
overflow-y: auto;
}
#dropzone {
background-color: green;
width: 95%;
height: 340px;
position: relative;
}
.cloned {
position: absolute;
width: 150px;
height: 150px;
padding: 0.5em;
border-radius: 6px;
display: inline-block;
background-color: rgba(255,0,0,0.75);
}
</style>
</head>
<body>
<pre id="log"></pre>
<div id="dropzone"></div>
<script>
jQuery(function($) {
function log(s){
var now = new Date();
var t = now.getHours() + ":" + now.getMinutes() + ":" + now.getSeconds
() + "." + now.getMilliseconds();
$("#log").append(t + ": " + s + "\r\n").scrollTop($("#log").prop
("scrollHeight"));
}
function getData(k){
console.log("Getting Data: '" + k + "'", localStorage.getItem(k));
return JSON.parse(localStorage.getItem(k));
}
function clearData(k){
log("Clear Data");
localStorage.setItem(k, null);
}
function makeEl(dObj, pObj){
console.log(dObj, pObj);
return $("<" + dObj.type + ">", dObj.attr).html("<p>" + dObj.content +
"</p>").appendTo(pObj);
}
function handleDrop(e){
if (e.stopPropagation) {
e.stopPropagation();
}
var trg = $(e.target);
log("Drop Triggered: " + trg.prop("nodeName") + "#" + trg.attr("id"));
var d, item;
if(e.target.id == "dropzone" && (e.type == "click" || e.type ==
"mouseup")){
log("Click Detected - Collecting Data");
d = getData("select-data");
console.log("Data", d);
d.attr.id = "clone-" + ($("#dropzone .cloned").length + 1);
log("Making Element: " + d.type + "#" + d.attr.id);
item = makeEl(d, trg);
item.removeClass("selected").addClass("cloned").position({
my: "center",
of: e
}).draggable();
clearData("select-data");
return true;
}
return false;
}
log("Init");
$("#dropzone").on({
mouseup: handleDrop,
click: handleDrop
});
});
</script>
</body>
</html>
我知道这不是你正在寻找的答案,为此你需要尝试提出真正的问题。 你似乎一直在问这个问题。
希望这可以帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.