一、拖拽事件
图片自带拖拽功能
其他元素可设置draggable属性
设置 draggable =true 就可以实现对盒子拖拽
拖拽元素(被拖拽元素对象)事件 :
ondragstart : 拖拽前触发
ondrag :拖拽前、拖拽结束之间,连续触发
ondragend :拖拽结束触发
目标元素(拖拽元素被拖到的对象)事件 :
ondragenter :进入目标元素触发
ondragover :进入目标、离开目标之间,连续触发
ondragleave :离开目标元素触发
ondrop :在目标元素上释放鼠标触发
1、被拖拽元素事件
ondragstart : 拖拽前触发
ondrag :拖拽前、拖拽结束之间,连续触发
ondragend :拖拽结束触发
如:
<div id="div1" draggable="true"></div> //这里设置了draggable
<div id="div2"></div>
<script>
var div1 = document.getElementById("div1");
var div2 = document.getElementById("div2");
div1.ondragstart = function(){ //拖拽开始的一刻触发
this.style.background = "yellow";
}
div1.ondrag = function() { //拖拽过程中触发,阻止默认事件是由于在鼠标松手后阻止浏览器的其他默认事件的阻碍
var ev = ev||window.event;
ev.preventDefault();//阻止默认事件
this.style.background = "blue";
}
div1.ondragend = function(){
this.style.background = "red"; //拖拽结束的那一刻开始触发触发
this.innerHTML = "jieshus-";
如:
目标元素(拖拽元素被拖到的对象)事件 :
ondragenter :进入目标元素触发
ondragover :进入目标、离开目标之间,连续触发
ondragleave :离开目标元素触发
ondrop :在目标元素上释放鼠标触发
var div1 = document.getElementById("div1");
var div2 = document.getElementById("div2");
div2.ondragenter = function(){ // 拖拽物进入目标盒子的那一刻开始触发
this.innerHTML = "可以将文件拖放到这里";
//this.style.background = "#000";
}
div2.ondragover = function(ev){ //在盒子内部拖拽的时候触发,这时候需要阻止默认事件,否则无法显示结果
var ev = ev||window.event;
ev.preventDefault();//阻止默认事件
this.style.background = "#000";
}
div2.ondragleave = function(){ //离开目标盒子的那一刻
this.innerHTML = "";
this.style.background = "red";
}
div2.ondrop = function(){ //在盒子内部松开鼠标的那一刻
alert("拖拽结束");
this.innerHTML = "";
this.style.background = "red";
}
如:
3、为什么上面两个案例在拖拽过程中都要阻止默认事件呢,因为比如在把一张照片拖拽到浏览器中的时候,当鼠标松开的那一刻,会自动在打开一个网页给图片放着,所以就是为了阻止这个事件,让图片在本页放着才会去阻止默认事件
4、火狐浏览器中实现拖拽
dataTransfer对象
setData() : 设置数据 key和value(必须是字符串)
getData() : 获取数据,根据key值,获取对应的value
如:
<div id="div1" draggable="true"></div> //火狐浏览器不兼容这个属性
<div id="div2"></div>
<script>
var div1 = document.getElementById("div1");
var div2 = document.getElementById("div2");
div1.ondragstart = function(ev){//拖拽开始触发
var ev = ev||window.event;
ev.dataTransfer.setData("data","div1"); // 添加数据:火狐浏览器,必须设置这个参数 ,火狐才能实现拖拽
this.style.background = "yellow";
}
div1.ondrag = function(){//拖拽过程中触发
this.innerHTML = "被拖拽中...";
}
div1.ondragend = function(){
this.style.background = "blue";
this.innerHTML = "";
}
div2.ondragenter = function(){
this.innerHTML = "可以将文件拖放到这里";
//this.style.background = "#000";
}
div2.ondragover = function(ev){
ev.preventDefault();//阻止默认事件
this.style.background = "#000";
}
div2.ondragleave = function(){
this.innerHTML = "";
this.style.background = "red";
}
div2.ondrop = function(ev){
//alert("拖拽结束");
//alert( ev.dataTransfer.getData("data"));
this.innerHTML = ev.dataTransfer.getData("data");
this.style.background = "red";
}
效果:也实现了数据传输
4、在进入目标盒子后展示不同的鼠标样式方法 effectAllowed : 设置光标样式
在进入目标盒子的事件中:
div1.ondragstart = function(ev){//拖拽开始触发
var ev = ev||window.event;
ev.dataTransfer.setData("data","div1"); // 添加数据:火狐浏览器,必须设置这个参数 ,火狐才能实现拖拽
effectAllowed : copy; //值有 none, copy, copyLink, copyMove, link, linkMove, move, all 和 uninitialized ,不同值不同样式
this.style.background = "yellow";
}
5、setDragImage :三个参数(指定的元素,坐标X,坐标Y) xy坐标为拖拽过程中的拖拽点,设置拖拽过程中,被拖拽的元素。
如:让目标元素变成拖拽元素
var div1 = document.getElementById("div1");
var div2 = document.getElementById("div2");
var img = document.getElementById("img");
div1.ondragstart = function(ev){//拖拽开始触发
var ev = ev || window.event;
ev.dataTransfer.setData("data","div1");//添加数据
ev.dataTransfer.effectAllowed = "copyLink";
ev.dataTransfer.setDragImage(div2,0,0); //这里设置指定的元素,坐标X,坐标y
this.style.background = "yellow";
}
div1.ondrag = function(){//拖拽过程中触发
this.innerHTML = "被拖拽中...";
}
div1.ondragend = function(){
this.style.background = "blue";
this.innerHTML = "";
}
div2.ondragenter = function(){
this.innerHTML = "可以将文件拖放到这里";
//this.style.background = "#000";
}
div2.ondragover = function(ev){
ev.preventDefault();//阻止默认事件
this.style.background = "#000";
}
div2.ondragleave = function(){
this.innerHTML = "";
this.style.background = "red";
}
div2.ondrop = function(ev){
//alert("拖拽结束");
//alert( ev.dataTransfer.getData("data"));
this.innerHTML = ev.dataTransfer.getData("data");
this.style.background = "red";
}
6、
files: 获取外部拖拽的文件,返回一个filesList列表
filesList下有个type属性,返回文件的类型
如:
div2.ondrop = function(ev){
ev.preventDefault();//阻止默认事件
this.innerHTML = "";
this.style.background = "red";
var file = ev.dataTransfer.files; //获取从外面拖进来的照片
alert(file[0].type); //显示第一张的类型结果是 image/jpg
}
6、文件读取
FileReader(读取文件信息) 与files配合使用
readAsDataURL
参数为要读取的文件对象
onload当读取文件成功完成的时候触发此事件
this. result 获取读取的文件数据
var box = document.getElementById("box");
box.ondragenter = function(){
this.innerHTML = "请释放鼠标";
this.style.background="#000";
}
box.ondragover = function(ev){
var ev = ev||window.event;
ev.preventDefault();
}
box.ondrop = function(ev){
var ev = ev||window.event;
ev.preventDefault();
this.innerHTML = "";
this.style.background="red";
var file = ev.dataTransfer.files;//获取外部拖拽的文件 第一
var read = new FileReader();//新建一个读取文件对象 第二
read.readAsDataURL(file[0]);//读取拖拽进来的文件 第三
read.onload = function(){//读取文件完成之后触发 第四
alert(this.result);//弹出读取到的数据 第五
}
}
具体使用方法:
var box = document.getElementById("box");
box.ondragenter = function(){
this.innerHTML = "请释放鼠标";
this.style.background="#000";
}
box.ondragover = function(ev){
var ev = ev||window.event;
ev.preventDefault();
}
box.ondrop = function(ev){
var ev = ev||window.event;
ev.preventDefault();
this.innerHTML = "";
this.style.background="red";
var file = ev.dataTransfer.files; //获取外部拖拽的文件
for (var i=0;i<file.length ; i++) //假如一次性拖3张图片进来
{
if (file[i].type.indexOf("image")!=-1) //indexOf() 方法如果要检索的字符串值没有出现过,则该方法返回 -1。
{
var read = new FileReader(); //新建一个读取文件对象
read.readAsDataURL(file[i]); // 读取拖拽进来的文件 ,这里就使用到了
read.onload = function() { //读取文件完成之后触发 ,这里触发onload 事件
var img = document.createElement("img");//创建一个img标签
img.src = this.result;//把读取到的数据赋值给src
box.appendChild(img);
}
}else{
alert("请上传图片!"); //验证失败
}
}
}
8、来实现文件上传
如:
<a href="#">
<input type="file" onchange="upload(this)"> //input改变的时候触发 ,this代表input
</a>
<input type="text" id="txt">
<div id="box">
<img id="img" src="">
</div>
function upload(val){
if (!val.value.match(/.jpg|.gif|.png|.bmp/i)) //match 比较两边数据的相同或者不同
{
alert("请选择图片文件");
}else{
var txt = document.getElementById("txt");
txt.value = val.files[0].name; //val.files[0] 在此能用原因,在把外部的照片弄进来的时候,会返回一个filesList列表,files[0] 表示里面的第一个照片
var img = document.getElementById("img");
img.src = window.URL.createObjectURL(val.files[0]); //创造一个路径,然后把路径的结果是这个照片
}
}
二、最后拖拽排序项目:
<div>
<ul id="ul">
<li style="background:#66c" draggable="true">1</li>
<li style="background:#c06" draggable="true">2</li>
<li style="background:#903" draggable="true">3</li>
<li style="background:#96f" draggable="true">4</li>
<li style="background:#993" draggable="true">5</li>
<li style="background:#693" draggable="true">6</li>
<li style="background:#03c" draggable="true">7</li>
<li style="background:#0c3" draggable="true">8</li>
</ul>
</div>
</body>
<script>
var oUl = document.getElementById('ul');
var oLi = oUl.getElementsByTagName('li');
var mark;
function range(){ //把函数封装,因为下面会使用到序列号也就是下标,然后会通过拖拽又改变元素,因此下标会乱掉,把实现过程 封装起来,每执行一次后,又从新执行自己,把下标从新排序
for ( var i=0;i<oLi.length;i++ )
{
oLi[i].index = i;
oLi[i].ondragstart = function(){
mark = this.index; //把被拖拽的元素的下标记录起来
}
oLi[i].ondragenter = function(){ //这个方法是一开始先把所有boeder属性给去掉,然后给除了被拖拽元素,其他元素碰到的时候增加border 属性
for ( var i=0;i<oLi.length;i++ )
{
this.style.border = "none";
}
if ( mark != this.index )
{
this.style.border = "2px solid #000";
}
}
oLi[i].ondragover = function( ev ){ //去掉在目标元素拖拽过程中的默认属性
ev = ev || window.event;
ev.preventDefault();
}
oLi[i].ondrop = function(){
insertAfter(oLi[mark],this);
this.style.border = "none";
range(); //这里就是上面说的自己在执行一次自己,已达到序列号的从新排序
}
}
}
range();
function insertAfter( newItem , targetItem ){ //这个方法是实现把拖拽元素放到目标元素后面的方法
var parentItem = targetItem.parentNode;
if ( parentItem.lastChild == targetItem )
{
parentItem.appendChild(newIltem);
}
else
{
parentItem.insertBefore( newItem , targetItem.nextSibling ) //在目标元素下一个兄弟元素的前面 parentItem.insertBefore(拖拽元素 ,目标元素的下一个元素) 拖拽元素放到目标元素的下一个元素的前面
}
}
</script>