最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • HTML5拖放详解

    正文概述 掘金(阿里云数据库前端团队)   2021-02-05   536

    1. 拖放的基本概念

    拖(drag)放(drop)是 HTML5 标准的组成部分,拖放是一种常见的特性,即抓取对象以后拖到另一个位置,任何元素都可以被拖放。 **

    2. 拖放的几个事件

    下面举一个简单的栗子来详细说明拖放的常用事件及其应用: HTML5拖放详解 需求说明:如上图,这是一个常见的三栏布局,要求图中箭头部分可上下、左右拖动,使得三个box可以根据用户需要调整内容的长宽,从而扩大缩小展示区域。 特殊说明:以下代码片段均为react的伪代码,不保证正常运行哦。

    第一步:骨架搭建

    很明显的布局方式就是利用css3的Flex(弹性布局)来搭建,代码如下

    <style>
      .container{ width: 100%; height: 100vh; display: flex; flex-direction: row; }
    	.panel-left{ width: 200px; position: relative; }
    	.left-move-bar{ width: 6px; height: 100%; position: absolute; top: 0; right: -6px;
       background-color: '#eee'; cursor: 'ew-resize'; }
    	.panel-right{ flex: 1; display: flex; flex-direction: column; }
    	.panel-right-body{ flex: 1; }
    	.panel-right-bottom{ position: relative; height: 400px }
    	.bottom-move-bar{ width: 100%; height: 6px; position: absolute; top: 0; left: 0;
       background-color: '#eee'; cursor: 'ew-resize'; }
    </style>
    
    <div className="container">
      <div className="panel-left" style={{ width: this.state.leftWidth }}>
        <div className="left-move-bar"></div> // 可左右拖动bar
      </div>
      <div className="panel-right">
        <div className="panel-right-body"></div>
        <div className="panel-right-bottom" style={{ height: this.state.bottomHeight }}>
          <div className="bottom-move-bar"></div> // 可上下拖动bar
        </div>
      </div>
    </div>
    

    第二步:处理被拖对象

    设置被拖元素为可拖放 ** 好了,我们的代码布局已经写好了,接下来就要一步步实现拖拽了;首先,为了使元素可拖动,把被拖对象的draggable 属性设置为 true:

    <div class="left-move-bar" draggable="true"></div>
    

    被拖对象事件监听

    <div
    	class="left-move-bar"
    	draggable="true"
    	onDragStart={handleLeftBarDragStart}>
    </div>
    <div
    	class="bottom-move-bar"
    	draggable="true"
    	onDragStart={handleBottomBarDragStart}>
    </div>
    

    handleDragStart方法如下,主要是获取被拖对象的鼠标位置

     handleLeftBarDragStart = (e) => {
        this.startX = e.clientX; // 获取鼠标起点位置
        e.dataTransfer.setData('target', 'x'); // 设置传输数据,用于区分拖拽的是横向bar还是竖向bar
     }
      
     handleBottomBarDragStart = (e) => {
        this.startY = e.clientY;
        e.dataTransfer.setData('target', 'y');
     }
    

    ondragstart 表示被拖对象开始拖放时触发,全程只执行一次。

    此外,还有2个不太常用的事件对象(存在兼容性问题,结尾有说明): ondrag 表示被拖对象处于拖动过程中触发,全程一直触发,直到被成功放置。 ondragend 表示被拖对象被成功放置后触发,全程只执行一次

    第三步:处理目标对象

    允许放置 ** 默认地,我们是无法将数据/元素放置到其他元素中。如果需要设置允许放置,我们必须阻止对元素的默认处理方式。这就要通过调用 ondragover 事件的 event.preventDefault() 方法:

    <div class="panel-left" onDragOver={e => e.preventDefault()}></div>
    <div class="panel-right" onDragOver={e => e.preventDefault()}></div>
    

    ondragover 被拖对象接触到目标对象开始触发,只要不停止拖放动作,就会一直触发。

    注意:因为我们拖动bar的可拖动范围是全屏幕,所以必须把左侧box和右侧box都要阻止默认事件

    此外,还有2个过程对象的事件也可以了解一下: ondragenter 被拖对象进入到目标对象触发,只执行一次。 ondragleave 被拖对象离开目标对象以后触发,全程一直执行,直到拖放结束。

    进行放置 ** 当放置被拖对象时,会发生 ondrop 事件,全程只执行一次。

    <div class="panel-left" onDragOver={e => e.preventDefault()} onDrop={handleOnDrop}></div>
    <div class="panel-right" onDragOver={e => e.preventDefault()} onDrop={handleOnDrop}></div>
    
    handleOnDrop = (e) => {
      const target = e.dataTransfer.getData('target');
      if (target === 'x') {
        this.setState({ // 计算左侧box的宽度
          leftWidth: this.state.leftWidth + (e.clientX - this.startX),
        });
      } else if (target === 'y') {
        this.setState({ // 计算底部box的高度
          bottomHeight: this.state.bottomHeight + (e.clientY - this.startY),
        });
      }
    }
    

    经过上面简单的三个步骤,我们就基本实现了一个支持可拖拽的流式布局。在上面主要用到了拖拽的三个事件:

    ondragstart 获取鼠标的起始位置 ondragover 阻止默认事件 ondrop 获取鼠标的终点位置,重新计算div的宽高

    3. 总结说明

    官方文档称 Internet Explorer 9、Firefox、Opera 12、Chrome 以及 Safari 5 均支持拖放。 **注释:**在 Safari 5.1.2 中不支持拖放。但在各个浏览器上仍然有不同的表现:

    如何获取鼠标位置

    在拖拽过程中,最重要的就是获取被拖对象、被拖对象的起始位置和放置位置,这些属性都可以通过 ondragstart 和 ondrop 来获取;而在某些业务场景中,我们是需要获取拖拽过程中鼠标的位置;但在Firefox中,ondrag、ondragover 的event对象中的clientX、clientY、offsetX、offsetY等值都是0,这个时候我们是可以通过监听document对象的dragover事件来实时获取鼠标所在的位置,代码示例如下:

    document.addEventListener(
      'dragover',
      (e) => {
        e = e || window.event;
        const dragX = e.pageX;
        const dragY = e.pageY;
        console.log("X:" + dragX +"Y:" + dragY)
      },
      false
    )
    

    拖拽元素为img对象

    当你的拖放元素为img对象或者包含img对象时,在Firefox中总是会在新窗口中打开图片链接,而其他浏览器不会。解决办法是在ondrop事件中添加阻止事件冒泡的行为 event.stopPropagation()。


    起源地下载网 » HTML5拖放详解

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元