原生拖拽实现
时间:2023-04-05 17:45:14
HTML5
定义事件操作工具letEventUtil=newObject;/*该方法用于给特定对象添加事件,oTarget为指定对象,sEventType为事件类型,如click,keydown等,fnHandler是事件回调函数*/EventUtil.addEventHandler=function(oTarget,sEventType,fnHandler){//在firefox中if(oTarget.addEventListener){oTarget.addEventListener(sEventType,fnHandler,false);}//在IE中elseif(oTarget.attachEvent){oTarget.attachEvent("on"+sEventType,fnHandler);}else{oTarget["on"+sEventType]=fnHandler;}};/*该方法用于移除特定对象的特定事件,oTarget为指定对象,sEventType为事件类型,如click、keydown等,fnHandler为事件回调函数*/EventUtil.removeEventHandler=function(oTarget,sEventType,fnHandler){if(oTarget.removeEventListener){oTarget.removeEventListener(sEventType,fnHandler,false);}elseif(oTarget.detachEvent){oTarget.detachEvent("on"+sEventType,fnHandler);}else{oTarget["on"+sEventType]=null;}};获取事件的方式不同,事件的属性也不同,通过这个方法提供一个一致的事件*/EventUtil.formatEvent=function(oEvent){//isIE和isWin引用一个js文件,判断浏览器和操作系统类型if(isIE&&isWin){oEvent.charCode=(oEvent.type=="keypress")?oEvent.keyCode:0;//IE只支持冒泡,不支持捕获oEvent.eventPhase=2;oEvent.isChar=(oEvent.charCode>0);oEvent.pageX=oEvent.clientX+document.body.scrollLeft;oEvent.pageY=oEvent.clientY+document.body.scrollTop;//防止事件的默认行为oEvent.preventDefault=function(){this.returnValue=false;};//将toElement、fromElement转换为标准relatedTargetif(oEvent.type=="mouseout"){oEvent.relatedTarget=oEvent.toElement;}elseif(oEvent.type=="mouseover"){oEvent.relatedTarget=oEvent.fromElement;}//取消冒泡oEvent.stopPropagation=function(){this.cancelBubble=true;};oEvent.target=oEvent.srcElement;//添加事件发生时间属性,IE没有oEvent.time=(newDate).getTime();}returnoEvent;};EventUtil.getEvent=function(){if(window.event){//格式化IE的事件returnthis.formatEvent(window.event);}else{返回EventUtil.getEvent.caller.arguments[0];}};高级自定义事件-观察者:functionEventTarget(){this.handlers={};}EventTarget.prototype={constructor:EventTarget,addHandler:function(type,handler){if(typeofthis.handlers[type]=="undefined"){this.handlers[type]=[];}this.handlers[type].push(handler);},开火:function(event){if(!event.target){event.target=this;}if(this.handlers[event.type]instanceofArray){lethandlers=this.handlers[event.type];对于(vari=0,len=handlers.length;i-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});}休息;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});}休息;case"mouseup":dragdrop.fire({type:"dragend",target:dragging,x:event.clientX,y:event.clientY});拖动=空;休息;}};//publicinterfacedragdrop.enable=function(){EventUtil.addHandler(document,"mousedown",handleEvent);EventUtil.addHandler(文档,“mousemove”,handleEvent);EventUtil.addHandler(文档,“mouseup”,handleEvent);};dragdrop.disable=function(){EventUtil.removeHandler(document,"mousedown",handleEvent);EventUtil.removeHandler(文档,“mousemove”,handleEvent);EventUtil.removeHandler(文档,“mouseup”,handleEvent);};返回拖放;}();DragDrop对象封装了拖放的所有基本功能,这是一个单例对象,使用模块模式隐藏了一些实现细节。拖动变量最初为null并将保存被拖动的元素,因此当变量不为null时,您知道正在拖动某些东西。handleEvent()函数处理拖放功能中的所有三个鼠标事件。它首先获取对事件对象和事件目标的引用。之后,使用switch语句来确定触发哪种事件样式。当mousedown事件发生时,它会检查目标的类是否包含“可拖动”类,如果是,则将目标存储在拖动中。这种技术对于通过标记而不是JavaScript识别可拖动元素很方便。handleEvent()的mousemove情况和前面的代码一样,只是检查dragging是否为null。当它不为null时,它知道dragging是要拖动的元素,所以它会被放到合适的位置。mouseup的情况只是把dragging重置为null,使得mousemove事件中的判断无效。DragDrop还有两个公共方法:enable()和disable(),它们只是相应地添加和删除所有事件处理程序。这两个函数提供了对拖放功能的额外控制。要使用DragDrop对象,只需将此代码包含在页面上并调用enable()。所有包含“draggable”类的元素都会自动启用拖放功能,如下例所示:
注意在为了让元素被拖放,它必须是绝对定位的。DragDrop.addHandler("dragstart",function(event){letstatus=document.getElementById("status");status.innerHTML="开始拖动"+event.target.id;});DragDrop.addHandler("拖动",function(event){letstatus=document.getElementById("status");status.innerHTML+="
Dragged"+event.target.id+"to("+event.x+","+event.y+")";});DragDrop.addHandler("dragend",function(event){letstatus=document.getElementById("status");status.innerHTML+="
Dropped"+event.target.id+"在("+event.x+","+event.y+")";});此代码定义了三个事件:dragstart、drag和dragend。它们都将拖动的元素设置为目标,并提供x和y属性来表示当前位置。它们在拖放对象上触发,然后在返回之前向该对象添加enable()和disable()方法。模块模式中的这些小变化使DragDrop对象支持事件。在这里,为DragDrop对象的每个事件添加了事件处理程序。元素还用于实现被拖动元素的当前状态和位置。放下元素后,您可以看到自第一次拖动以来它所经历的所有中间步骤。为DragDrop添加自定义事件使该对象更加健壮,并且它将处理Web应用程序中复杂的拖放功能。