说拖拽功能实现的步骤:
1.将想要拖拽的东西设置为可拖拽
2.拖拽的东西要放入目的地
3. 将东西进行上传(如github传输文件到自己的远程仓库)
今天我就对1和2两个进行探讨一下,
一、拖拽单个元素:
<div class="src">
<div class="dragable">
<div class="txt" id="txt">
所有的文字都可以拖拽
<p draggable="true">此段文字设置了属性draggable="true"</p>
</div>
</div>
<div id="target">Drop here</div>
</div>
首先将"此段文字设置了属性draggable="true""设置为鼠标可以进行移动,只要添加属性draggable="true",我们就可以将这段文字进行拖动。
此段文字设置了属性draggable="true"
接着就是对拖拽的元素进行监听,探寻元素到底如何变化?
监听中的事件:
ondrag 当某个对象被拖动时触发此事件 [活动事件]
ondragdrop 一个外部对象被鼠标拖进当前窗口或者帧
ondragend 当鼠标拖动结束时触发此事件,即鼠标的按钮被释放了
ondragenter 当对象被鼠标拖动的对象进入其容器范围内时触发此事件
ondragleave 当对象被鼠标拖动的对象离开其容器范围内时触发此事件
ondragover 当某被拖动的对象在另一对象容器范围内拖动时触发此事
ondragstart 当某对象将被拖动时触发此事件
ondrop 在一个拖动过程中,释放鼠标键时触发此事件
事件监听方式:
进行监听要获得监听的对象,并使用监听事件**,使用document.getElementById(" ") 得到的是一个对象。**
let dragSrc = document.getElementById('txt'); // drag
let target = document.getElementById('target'); // drop
dragSrc.ondragstart = handle_start;
事件监听 左事件 右处理函数 其中drag和drop都可以添加监听事件
在Drop here的盒子中释放鼠标键,在ondrap事件进行写入函数(target.innerHTML = dragSrc.innerText;),可以将鼠标拖拽的元素放入Drop here的盒子中
例如: 将"此段文字设置了属性draggable="true""放入id为target盒子中,
还可以在拖拽元素进入目的地实现样式的改变,使用target.classList.add('hover');
在触发函数时, 添加css(.hover)
drag + drop 良好用户体验模拟 css中可以添加cursor:move 拖拽时鼠标会变成手,实现鼠标抓那一下的动作
实现拖拽代码为:
<script>
let dragSrc = document.getElementById('txt'); // drag
let target = document.getElementById('target'); // drop
target.ondragenter = handle_enter;
target.ondrop = handle_drop
function handle_drop(event) {
event.preventDefault();
target.innerHTML = dragSrc.innerText;
}
function handle_enter(event) {
event.preventDefault();
// ('handle_enter -当元素进入目的地时触发');
target.classList.add('hover'); } }
</script>
二、拖拽多个元素:
<div class="main">
<div class="left" id="left">
<div class="txt-show">左边区域</div>
<div class="dargable txt" id="txt1" draggable="true">可移动的文字一</div>
<div class="dargable txt" id="txt2" draggable="true">可移动的文字二</div>
<div class="dargable txt" id="txt3" draggable="true">可移动的文字三</div>
<div class="dargable txt" id="txt4" draggable="true">可移动的文字四</div>
<div class="dargable txt" id="txt5" draggable="true">可移动的文字五</div>
</div>
<div class="right" id="right">
<div class="txt-show">右边区域</div>
</div>
</div>
进行监听要获得监听的对象,在此处五个元素, 怎么设置它的事件?
不可以在伪数组元素上一次性注册事件, 得一个个来,由于js 事件有冒泡机制 可以设置事件在它们的父元素上。然后使用addEventListener()可以添加事件处理程序,
addEventListener 添加事件处理(一般有三个属性)
1.事件名 2.事件处理函数 3.一个布尔值
let left = document.getElementById('left')
let target = document.getElementById('right')
left.addEventListener('dragstart', (event) => {
const target = event.target;
event.dataTransfer.setData('Text', target.id)
})
event.target; 在拖拽元素中,event会返回一个target属性告诉我们那个元素在进行拖动。left.addEventListener('dragstart', (event)在left的对象上添加(ondragstart)事件,当这个对象将被拖动时触发此事件
event.dataTransfer.setData('Text', target.id)拖拽, dataTransfer 属性 好像邮寄一个包裹把target.id带上去并命名为Text
target.addEventListener('drop', (event) => {
event.preventDefault();
let drag_id = event.dataTransfer.getData('Text');
target.appendChild(document.getElementById(drag_id))
})
event.dataTransfer.getData('Text');得到包裹Text('key')中的值
target.appendChild(document.getElementById(drag_id))
向target下最后一个结点后添加一个子节点(document.getElementById(drag_id)
大部分APP和浏览器会有默认的拖拽行为(会用整个显示拖拽内容)
event.preventDefault()可以阻止
实现拖拽代码为:
<script>
let left = document.getElementById('left')
let target = document.getElementById('right')
left.addEventListener('dragstart', (event) => {
const target = event.target;
event.dataTransfer.setData('Text', target.id)
})
left.addEventListener('drag', (event) => {
console.log('drag'); })
left.addEventListener('dragend', (event) => {
console.log('dragend'); })
target.addEventListener('dragenter', (event) => {
event.preventDefault(); console.log('dragenter') })
target.addEventListener('dragover', (event) => {
event.preventDefault();
console.log('dragover') })
target.addEventListener('dragleave', (event) => {
event.preventDefault();
console.log('dragleave') })
target.addEventListener('drop', (event) => {
event.preventDefault();
let drag_id = event.dataTransfer.getData('Text');
target.appendChild(document.getElementById(drag_id))
console.log('拖拽元素离开与原位置,来到目标地址'); })
</script>
**三、**拖拽过来的元素完成拖回去:
只有对元素的原地添加相应的事件处理可以了,在id为left对象中添加ondrap事件,再将拖拽回来的内容再将它首位子节点
target.addEventListener('dragstart', (event) => {
const target = event.target;
event.dataTransfer.setData('Txt', target.id)
})
left.addEventListener('drop', (event) => {
event.preventDefault();
let targe_id = event.dataTransfer.getData('Txt');
left.appendChild(document.getElementById(targe_id))
})
总结:
github 拖拽上传功能中巨大的坑
巨坑1:大部分APP和浏览器会有默认的拖拽行为(会用整个显示拖拽内容)
event.preventDefault()可以阻止
巨坑2:在一个盒子下的五个元素, 怎么设置它的事件?
解释:js 事件有冒泡机制 可以设置事件在它们的父元素上
document
.getElementById('left')
.addEventListener('dragstart', () => {
console.log('父元素上');
})
但会有 event.target会监听哪个子元素发生拖拽