拖放 js

之前被小伙伴问自己能不能写一个简单的原生的 我稍微犹豫了下  这次重新学习下拖拽的过程  分享下  参考 JavaScript高级程序设计

必要的准备

自定义事件(实现事件模型) 

简单来说事件模型就是观察者模式的一种使用,主体负责发布和管理事件,观察者通过订阅特定的事件类型来观察主体发布的事件,举个例子你有一个按钮,它触发click事件就是在发布事件,事件处理程序就是观察者

  function EventTarget(){
    this.handlers = {};
  }

  EventTarget.prototype = {
    constructor:EventTarget,
    addHandler:function(type,handler){
      if(typeof this.handlers[type] == "undefined") {
        this.handlers[type] = [];
      }
      this.handlers[type].push(handler);  //通过数组的方式储存特定类型的事件处理程序(先后)
    },
    fire:function(event){  //触发特定的事件处理程序 就分别将event对象传递给特定类型下数组中每个事件处理函数
      if(!event.target) {
        event.target = this;
      }
      if(this.handlers[event.type] instanceof Array) {
        var handlers = this.handlers[event.type];
        for(var i = 0,len = handlers.length;i < len;i+=1) {
          handlers[i](event);
        }
      }
    },
    removeHandler:function(type,handler) {
      if(this.handlers[type] instanceof Array) {
        var handlers = this.handlers[type];
        for(var i = 0,len = handlers.length;i < len;i+=1) {
          if(handlers[i] == handler) {
            break;
          }
        }
        handlers.splice(i,1);
      }
    }

  }

我们可以这样使用上面的事件处理程序

  function test() {
    alert(1);
  }
  var target = new EventTarget();
  target.addHandler("message",test); //订阅了一个type是message的事件处理函数
  target.fire({type:"message"}); //触发该事件   会发现alert1

理解:自定义事件能使我们定义我们自己的事件type,能在我们需要进行交互的时刻触发特定的事件处理程序代码

实现跨浏览器的事件对象EventUtil   参考之前的blog  js事件小记

下面来完成拖动的代码

其实简单的理解拖动的过程就是当鼠标mousedown的时候(如果元素可以拖动),让它的绝对定位的left top是鼠标的event.clientX event.clientY 并且在mousemove的时候,时刻去跟随鼠标的位置更新自己的left top 最后在mouseup的时候不让改元素可以移动  我们通过在拖动中加入自定义事件就能够在特定的时刻相应我们的行为,例如网络传输数据,通过页面的元素与用户交互,输出拖动元素的信息等

    var DragDrop = function(){
      var dragdrop = new EventTarget(),
          dragging = null,
          diffX = 0,//diffX diffY 是为了处理每次拖动的时候鼠标位置的问题
          diffY = 0;

      function handlerEvent(event) {
          var event = EventUtil.getEvent(event);
          var target = EventUtil.getTarget(event);
          switch(event.type) {
            case "mousedown":
              if(target.className.indexOf("draggable") > -1) {
                dragging = target;
                diffX = event.clientX - target.offsetLeft;
                diffY = event.clientY - target.offsetTop;  //获取鼠标位置和元素的左上角的位置差
                dragdrop.fire({
                    type:"dragstart",
                    target:dragging,
                    x:event.clientX,
                    y:event.clientY
                });
              }
              break;
            case "mousemove":
              if(dragging !== null) {
                dragging.style.left = (event.clientX - diffX) + "px";
                dragging.style.top = (event.clientY - diffY) + "px";
                dragdrop.fire({
                    type:"drag",
                    target:dragging,
                    x:event.clientX,
                    y:event.clientY
                });
              }
              break;
            case "mouseup":
              dragdrop.fire({
                type:"dragend",
                target:dragging,
                x:event.clientX,
                y:event.clientY
              });
              dragging = null;
              break;
          }

      };

      dragdrop.enable = function(){
        EventUtil.addHandler(document,"mousedown",handlerEvent);
          EventUtil.addHandler(document,"mousemove",handlerEvent);
          EventUtil.addHandler(document,"mouseup",handlerEvent);
      };
      dragdrop.disable = function(){
          EventUtil.removeHandler(document,"mousedown",handlerEvent);
          EventUtil.removeHandler(document,"mousemove",handlerEvent);
          EventUtil.removeHandler(document,"mouseup",handlerEvent);
      };
      return dragdrop;

    }();
    DragDrop.enable();

上面的例子通过单例的模式,模块化的封装了拖动模块

其他相关点

z-index z-index 只在position:absolute relative fixed 下生效

时间: 2024-08-01 09:11:01

拖放 js的相关文章

js高级技巧---拖放

拖放:点击某个对象,并按住鼠标按钮不放,将鼠标移动到另一个区域,然后释放鼠标按钮将对象“放”在某处. 涉及到event的对象的属性: clientX,clientY:当事件被触发时鼠标指针相对于浏览器页面(或客户区)的坐标. screenX,screenY:当事件发生时鼠标指针相对于屏幕的坐标. offsetX,offsetY:当事件发生时鼠标指针相对于触发事件的元素内边界的坐标. x,y:当事件发生时鼠标指针相对于触发事件的元素外边界的坐标. 1.声明了一个对象DragDrop,该对象是一个单

nw.js如何处理拖放操作

其实拖放(drag-drop)操作是Html5的功能,不是nw.js的内置API,那么我们采用Html5应用一般的处理方法就可以了. 首先我们看一下一个正常的页面,直接拖放一个文件过来的效果. 页面代码: <html> <head> <title>拖放测试</title> </head> <bodystyle="background-color:rgba(0,0,0,0);"> <pid="outp

支持移动触摸设备的纯js元素拖放插件

Dragula是一款支持移动触摸屏设备的元素拖放纯js插件.这个元素拖放插件使用简单,浏览器兼容性好,能够实现通过鼠标或在移动设备中通过手指来拖动DOM元素的位置.它的特点有: 设置非常简单 没有外部依赖 可以自动对数据进行排序 被移动项带有半透明的视觉效果 支持移动触摸设备 兼容性好,支持IE7+的所有现代浏览器 效果演示:http://www.htmleaf.com/Demo/201504171695.html 下载地址:http://www.htmleaf.com/jQuery/Layou

Vue.js学习笔记(8)拖放

小颖在目前负责的项目中,负责给同事提供所需组件,在这期间,我们家大颖姐姐让我 写个拖拽组件,一开始我是用click实现,先将你要拖拽的dom点一下,然后再点你要放的位置,这个dom再通过小颖写的方法,渲染在你要显示的地方,虽然功能实现了,可是没有实现拖拽,我那是点击,所以小颖今天就看了下html5的拖放,然后写了个小示例,希望对大家有所帮助. 小颖是用vue写的嘻嘻,大家要是用js实现的话看看HTML 5 拖放 代码请看这里,当当当当: html: <template> <div cla

使用touch-punch.js实现移动端的拖放效果

一.下载文件并引入 下载地址:http://touchpunch.furf.com/ 引入: <script src="js/jquery-ui.min.js"></script> <script src="js/jquery.ui.touch-punch.min.js"></script> 这里可以查看参数http://www.cnblogs.com/ganqiyin/archive/2013/12/12/34716

支持元素惯性拖放和多点触摸手势的js插件

interact.js是一款支持元素惯性拖放和多点触摸手势的js插件.该插件支持在桌面设备和移动手机设备中拖放元素,拖动结束时带有惯性效果.并且支持移动设备的多点触摸手势.它的特点有: 带惯性和吸附效果 支持多元互动 跨浏览器和设备,支持桌面和移动版本的Chrome, Firefox 和 Opera浏览器以及IE8+浏览器 可以和SVG元素相互作用 轻量级,无任何外部依赖 除非要支持IE8或修改鼠标样式,否则不用修改任何DOM元素 效果演示:http://www.htmleaf.com/Demo

JS实现div块的拖放,调换位置

主要是HTML5 的拖放(Drag 和 Drop) 例子(不需要对div设置ID): <!DOCTYPE HTML> <html> <head> <script type="text/javascript"> function allowDrop(ev) { ev.preventDefault(); } var srcdiv = null; function drag(ev,divdom) { srcdiv=divdom; ev.data

hammer.js实现移动端的拖放效果

hammer.js可以实现移动端的多种触摸效果.详细可以点击http://www.cnblogs.com/iamlilinfeng/p/4239957.html 不过发现hammer.js实现功能时,只能是原生js,jquery代码在hammer中不起效果. 一.引入hammer.js 下载http://hammerjs.github.io/ <script type="text/javascript" src="js/hammer.min.js">&l

js学习

 一.什么是对象      所谓对象就是真实世界中的实体,对象与实体是一一对应的,也就是说现实世界中每一个实体都是一个对象,它是一种具体的概念. 二.原型链因为每个对象和原型都有原型,对象的原型指向原型对象, 而父的原型又指向父的父,这种原型层层连接起来的就构成了原型链. 三.局部变量.全局变量 局部变量可以与全局变量重名,但是局部变量会屏蔽全局变量.要使用全局变量,需要使用::.在函数体内引用变量会用到同名的局部变量而不是全局变量,对于一些编译器来说,在同一个函数体内可以定义多个同名的局部变量