<html>
<head>
<title>Experimental Drag and Drop - RJM Programming - July, 2023 ... thanks to https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/setData</title>
<script type=text/javascript>
var clonedata='', pos3=0, pos4=0;

function cloneize() {
if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1){
document.getElementById('source').setAttribute('contenteditable',false);
document.getElementById('strongs').innerHTML='';
}
if (clonedata != document.getElementById('source').innerHTML) {
clonedata=document.getElementById('source').outerHTML.replace(' id=', ' data-id=');
document.getElementById('clone').style.display='inline-block';
}
setTimeout(cloneize, 1000);
}

function bodyev() {
if (document.getElementById('clone').innerHTML.indexOf(' ...') == -1) {
document.getElementById('clone').innerHTML+=' ... Double click (or right click) where you want clone to be';
}
document.body.ondblclick=function(e) {
e = e || window.event;
e.preventDefault();

if (e.touches) {
if (e.touches[0].pageX) {
pos3 = e.touches[0].pageX;
pos4 = e.touches[0].pageY;
} else {
pos3 = e.touches[0].clientX;
pos4 = e.touches[0].clientY;
}
console.log('pos3=' + pos3 + ',pos4=' + pos4);
} else if (e.clientX || e.clientY) {
pos3 = e.clientX;
pos4 = e.clientY;
} else {
pos3 = e.pageX;
pos4 = e.pageY;
}

if (clonedata.indexOf(' style="') != -1) {
document.getElementById('scratchpad').innerHTML+=clonedata.replace(' style="', ' style="position:absolute;left:' + pos3 + 'px;top:' + pos4 + 'px;');
} else if (clonedata.indexOf(" style='") != -1) {
document.getElementById('scratchpad').innerHTML+=clonedata.replace(" style='", " style='position:absolute;left:" + pos3 + "px;top:" + pos4 + "px;");
} else {
document.getElementById('scratchpad').innerHTML+=clonedata.replace(' ', ' style="position:absolute;left:' + pos3 + 'px;top:' + pos4 + 'px;" ');
}
};

document.body.oncontextmenu=function(e) {
e = e || window.event;
e.preventDefault();

if (e.touches) {
if (e.touches[0].pageX) {
pos3 = e.touches[0].pageX;
pos4 = e.touches[0].pageY;
} else {
pos3 = e.touches[0].clientX;
pos4 = e.touches[0].clientY;
}
console.log('pos3=' + pos3 + ',pos4=' + pos4);
} else if (e.clientX || e.clientY) {
pos3 = e.clientX;
pos4 = e.clientY;
} else {
pos3 = e.pageX;
pos4 = e.pageY;
}

if (clonedata.indexOf(' style="') != -1) {
document.getElementById('scratchpad').innerHTML+=clonedata.replace(' style="', ' style="position:absolute;left:' + pos3 + 'px;top:' + pos4 + 'px;');
} else if (clonedata.indexOf(" style='") != -1) {
document.getElementById('scratchpad').innerHTML+=clonedata.replace(" style='", " style='position:absolute;left:" + pos3 + "px;top:" + pos4 + "px;");
} else {
document.getElementById('scratchpad').innerHTML+=clonedata.replace(' ', ' style="position:absolute;left:' + pos3 + 'px;top:' + pos4 + 'px;" ');
}
};

}

</script>
<style>
div {
margin: 0.5em 0;
padding: 2em;
}

#target,
#source {
border: 1px solid black;
padding: 0.5rem;
}

.dragging {
background-color: pink;
}

</style>
</head>
<body onload='cloneize();'>
<h1>Experimental Drag and Drop</h1>
<h3>RJM Programming - July, 2023</h3>
<h4>Thanks to <a target=_blank title='https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/setData' href='//developer.mozilla.org/en-US/docs/Web/API/DataTransfer/setData'>https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/setData</a></h4>
<div>
<p id="source" draggable="true" contenteditable="true" style="background-color:#f0f0f0;">
Select this <strong id=strongs>editable</strong> element, drag it to the drop zone and then release the selection
to move the element.
</p>
</div>
<div id="target">Drop Zone</div>

<button id="reset">Reset example</button> <button id="clone" style="display:none;" onclick="bodyev();">Clone content</button>
<div id=scratchpad></div>
<script type=text/javascript>

const source = document.querySelector("#source");
source.addEventListener("dragstart", (ev) => {
console.log("dragStart");
// Change the source element's background color
// to show that drag has started
ev.currentTarget.classList.add("dragging");
// Clear the drag data cache (for all formats/types)
ev.dataTransfer.clearData();
// Set the drag's format and data.
// Use the event target's id for the data
ev.dataTransfer.setData("text/plain", ev.target.id);
});
source.addEventListener("dragend", (ev) =>
ev.target.classList.remove("dragging")
);

const target = document.querySelector("#target");
target.addEventListener("dragover", (ev) => {
console.log("dragOver");
ev.preventDefault();
});
target.addEventListener("drop", (ev) => {
console.log("Drop");
ev.preventDefault();
// Get the data, which is the id of the source element
const data = ev.dataTransfer.getData("text");
const source = document.getElementById(data);
ev.target.appendChild(source);
});

const reset = document.querySelector("#reset");
reset.addEventListener("click", () => document.location.reload());

</script>

</body>
</html>