目 录CONTENT

文章目录

DOM拖放事件

Administrator
2023-08-15 / 0 评论 / 0 点赞 / 23 阅读 / 7513 字

拖放事件

一个页面上面DOM元素默认是不允许拖动的,如果要想拖放需要添加属性dragable="true"

<div class="box" dragable="true">
    这是一个可以拖动的元素
</div>

当一个页面上面的元素可以拖动以后,当去拖动它时就会依次触发下面三个事件

  1. dragstart拖动开始的时候
  2. drag拖动的时候
  3. dragend拖动结束的时候

当元素被拖动到另一个有效的放置目录上面的时候就会依次触发事面几个事件

  1. dragenter拖动的元素进来了
  2. dragover拖动的元素悬停在上面
  3. drop拖动的元素在这里松开放置的时候
  4. dragleave拖动的元素又出来了

自定义放置目录

在HTML里面,默认情况下所有元素都支持放置目录事件(也就是drop事件)。但是这些元素默认是不允许放置的,所以也就无法触发ondrop事件,如果想触发这个事件,则要取消dragenterdropover事件的默认行为

 $(".big-box").on("dragenter", function (event) {
     // console.log("dragenter事件触发", event);
     event.preventDefault();
 }).on("dragover", function (event) {
     // console.log("dragover事件触发", event);
     event.preventDefault();
 })

当取消了事件的默认行为以后,这个元素上面就可以放置目录了,当我们再把元素拖放在这个目标元素上面时,你们就会发现它的鼠标指针图标已经发生改变了

dataTransfer对象

一个元素拖放到另一个元素上面去的时候,两个元素之前元素之前只发生事件触发,不会发生任何变化。为了实现数据交换的功能,event对象上面有一个属性叫dataTransfer,这个属性负责在两个元素之间传递数据。它有以下两个常用的方法

  1. setData()在拖动的元素上面设置数据
  2. getData()在放置的目标元素上面获取数据

在这里我说一下,因为我们讲课的时候使用的是jQuery 框架,所以我们要找到这个dataTransfer对象就需要从原生事件对象里面找,也就是event.originalEvent.dataTransfer

如果只是普通的DOM事件 ,则可以直接使用event.dataTransfer

以下案例就说明了事件拖放的功能

<style>
    .big-box {
        width: 200px;
        height: 200px;
        border: 2px solid black;
    }
    .box {
        width: 100px;
        height: 100px;
        background-color: deeppink;
    }
</style>
<body>
    <!-- 网页上面默认情况下是不能够进行拖动的 -->
    <div class="big-box">

    </div>
    <hr>
    <div class="box" draggable="true" id="box1">
        这是第一个盒子
    </div>
    <hr>
    <div class="box" draggable="true" id="box2">
        这是第二个盒子
    </div>
</body>
<script src="./js/jquery.js"></script>
<script>
    $(".box").on("dragstart", function (event) {
        console.log("小盒子已经开始拖动了", event);
        //我现在拖动元素上面设置了一个东西
        event.originalEvent.dataTransfer.setData("domId",$(this).attr("id"));
    });

    $(".big-box").on("dragenter", function (event) {
        // console.log("dragenter事件触发", event);
        event.preventDefault();
    }).on("dragover", function (event) {
        // console.log("dragover事件触发", event);
        event.preventDefault();
    }).on("drop",function(event){
        console.log("drop事件被触发",event);
        // 我现在在放置目标上面获取这个东西
        var domId = event.originalEvent.dataTransfer.getData("domId");
        var dragDom = document.querySelector("#"+domId);
        $(this).append(dragDom);
    });
</script>

代码分析:在.div1的元素上面,我们设置了dragstart事件,在这个事件当中,我们通过dataTransfer.setData()这个该当,把当前元素的的id放置进去了,然后在放置的目录元素big-box上面我们阻止了dragenterdragover事件的默认行为,这个元素就可以放置在上面从而触发drop事件,触发drop事件以后,我们再通过dataTransfer.getData()的方法获取到之前的元素ID,再通过这个ID找到这个元素把它append进来

扩展:如果我们想实现复制拖动的元素,可以按照下面的方法来进行

$(".box").on("dragstart", function (event) {
    console.log("小盒子已经开始拖动了", event);
    //我现在拖动元素上面设置了一个东西
    // console.log(this.outerHTML);
 event.originalEvent.dataTransfer.setData("dragOuterHTML",$(this).prop("outerHTML"));
});

$(".big-box").on("dragenter", function (event) {
    // console.log("dragenter事件触发", event);
    event.preventDefault();
}).on("dragover", function (event) {
    // console.log("dragover事件触发", event);
    event.preventDefault();
}).on("drop",function(event){
    console.log("drop事件被触发",event);
    // 我现在在放置目标上面获取这个东西
    var dragOuterHTML = event.originalEvent.dataTransfer.getData("dragOuterHTML");
    $(this).append(dragOuterHTML);
    // insertAdjacentElement/insertAdjacentText/insertAdjacentHTML
});

代码分析:在上面的代码里面,我们只是在设置setData的时候使用了outerHTML这个属性,然后再放置事件drop的时候,我们使用的了getData()获取到了之前的HTML文本代码,然后将这个HTML代码通过jQuery的append()方法追加到了放置元素的目录里面


文件的拖放

拖放最主要的使用点还是在文件的拖放上面,我们在操作的时候经常会涉及到将电脑上面的文件拖放到浏览器(如拖放一个文件以后直接打开,拖放一个文件以后直接上传,拖放一个音乐以后直接播放,或拖放一个图片直接在某个地方显示等…)

<style>
    #img1 {
        width: 200px;
        height: 200px;
        border: 1px solid gray;
    }
</style>
<body>
    <div class="box">
        <img id="img1">
        <input type="file" id="file1" style="display: none;">
        <button type="button" id="btnChooseFile" onclick="this.previousElementSibling.click()">选择文件</button>
    </div>
</body>
<script>
    let file1Dom = document.querySelector("#file1");
    file1Dom.addEventListener("change",function (event) {
        // console.dir(this);
        var file = this.files[0];
        //判断类型是否是图片
        var reg = /^image\/(jpeg|jpg|png|gif|svg|bmp)$/;
        if (reg.test(file.type)) {
            $("#img1").attr("src", URL.createObjectURL(file));
        } else {
            alert("请选择图片文件");
        }
    })
    document.addEventListener("dragenter",function(event){
        event.preventDefault();
    });
    document.addEventListener("dragover",function(event){
        event.preventDefault();
    });
    document.addEventListener("drop",function(event){
        event.preventDefault();
        // console.log(event.originalEvent.dataTransfer.files);
        if (event.originalEvent.dataTransfer.files.length > 0) {
            var file = event.originalEvent.dataTransfer.files[0];
            var reg = /^image\/(jpeg|jpg|png|gif|svg|bmp)$/;
            if (reg.test(file.type)) {
                //URL.createObjectURL是把对象变成一个URL地址,这样就可以设置在src属性上面了
                $("#img1").attr("src", URL.createObjectURL(file));
            } else {
                alert("请选择图片文件");
            }
        }
    });
</script>

代码分析:上面代码中用到了URL.createObjectURL()这个方法,关于这个方法的使用,可以看一下后面的笔记。它个方法可以理解为将一个对象转换为URL地址,这个得到URL地址以后我们就可以 赋值给某一个DOM的src

0
dom

评论区