Javascript 基于鼠标非div拖动元素

Javascript 基于鼠标非div拖动元素,javascript,jquery,draggable,Javascript,Jquery,Draggable,我正在使用,因为这是我能找到的唯一可以拖动只读输入元素的东西 问题是,在缩放元素()上拖动时,它关注的是div的移动,而不是鼠标,因此在大空间中移动时,鼠标与div分离 我发现在event上,我可以使用以下变量跟踪div中鼠标的精确移动: var elementNewXPosition = (event.offsetX != null) ? event.offsetX : event.originalEvent.layerX; var elementNewYPosition = (event.o

我正在使用,因为这是我能找到的唯一可以拖动只读输入元素的东西

问题是,在缩放元素()上拖动时,它关注的是div的移动,而不是鼠标,因此在大空间中移动时,鼠标与div分离

我发现在
event
上,我可以使用以下变量跟踪div中鼠标的精确移动:

var elementNewXPosition = (event.offsetX != null) ? event.offsetX : event.originalEvent.layerX;
var elementNewYPosition = (event.offsetY != null) ? event.offsetY : event.originalEvent.layerY; 
现在,当我移动div时,鼠标定位在div上,但是它仍然非常容易出错。你可以看到一个

如果有人能看一下上面的JSFIDLE并给我一些指导,我将不胜感激

我想我会在这里发布javascript我编辑过的draggable.js版本,以防万一有人想看看我在用什么

!(function(moduleName, definition) {
  // Whether to expose Draggable as an AMD module or to the global object.
  if (typeof define === 'function' && typeof define.amd === 'object') define(definition);
  else this[moduleName] = definition();

})('draggable', function definition() {
  function addEventListener(element, eventName, handler) {
                if (element.addEventListener) {
                    element.addEventListener(eventName, handler, false);
                } else if (element.attachEvent) {
                    element.attachEvent('on' + eventName, handler);
                } else {
                    element['on' + eventName] = handler;
                }
            }
  function removeEventListener(element, eventName, handler) {
      if (element.removeEventListener) {
          element.removeEventListener(eventName, handler, false);
      } else if (element.detachEvent) {
          element.detachEvent('on' + eventName,handler);
      } else {
          element['on' + eventName] = null;
      }
  }
  function toCamelCase(s){
    return s.replace(/(\-[a-z])/g, function($1){return $1.toUpperCase().replace('-','');});
  }
  function getStyle(el, styleProp) {
      var s='';
        if (typeof el['currentStyle']==='object')
            s = el.currentStyle[toCamelCase(styleProp)];
        else if (window.getComputedStyle)
            s = document.defaultView.getComputedStyle(el, null).getPropertyValue(styleProp);
        return s;
  }
  var currentElement;
  var fairlyHighZIndex = '10';

  function draggable(element, handle) {
    handle = handle || element;
    var index=parseInt(getStyle(element,'z-index'));
    fairlyHighZIndex = isNaN(index)? '10' : index ;
    setPositionType(element);
    setDraggableListeners(element);
    addEventListener(handle,'mousedown', function(event) {
        if (event.which == null)
        /* IE case */
            button = (event.button < 2) ? "LEFT" :
                ((event.button == 4) ? "MIDDLE" : "RIGHT");
        else
        /* All others */
            button = (event.which < 2) ? "LEFT" :
                ((event.which == 2) ? "MIDDLE" : "RIGHT");
      button==='LEFT' && startDragging(event, element);
    });
  }

  function setPositionType(element) {
    element.style.position = 'absolute';
  }

  function setDraggableListeners(element) {
    element.draggableListeners = {
      start: [],
      drag: [],
      stop: []
    };
    element.whenDragStarts = addListener(element, 'start');
    element.whenDragging = addListener(element, 'drag');
    element.whenDragStops = addListener(element, 'stop');
  }

  function startDragging(event, element) {
    currentElement && sendToBack(currentElement);
    currentElement = bringToFront(element);

    var elementNewXPosition = (event.offsetX != null) ? event.offsetX : event.originalEvent.layerX;
    var elementNewYPosition = (event.offsetY != null) ? event.offsetY : event.originalEvent.layerY; 

    var initialPosition = getInitialPosition(currentElement);
    currentElement.style.left = inPixels(elementNewXPosition);
    currentElement.style.top = inPixels(elementNewYPosition);
    currentElement.lastXPosition = elementNewXPosition;
    currentElement.lastYPosition = elementNewYPosition;

    var okToGoOn = triggerEvent('start', { x: initialPosition.left, y: initialPosition.top, mouseEvent: event });
    if (!okToGoOn) return;

    addDocumentListeners();
  }

  function addListener(element, type) {
    return function(listener) {
      element.draggableListeners[type].push(listener);
    };
  }

  function triggerEvent(type, args) {
    var result = true;
    var listeners = currentElement.draggableListeners[type];
    for (var i = listeners.length - 1; i >= 0; i--) {
      if (listeners[i](args) === false) result = false;
    };
    return result;
  }

  function sendToBack(element) {
    var decreasedZIndex = fairlyHighZIndex - 1;
    element.style['z-index'] = decreasedZIndex;
    element.style['zIndex'] = decreasedZIndex;
  }

  function bringToFront(element) {
    element.style['z-index'] = fairlyHighZIndex;
    element.style['zIndex'] = fairlyHighZIndex;
    return element;
  }

  function addDocumentListeners() {
    addEventListener(document,'selectstart', cancelDocumentSelection);
    addEventListener(document,'mousemove', repositionElement);
    addEventListener(document,'mouseup', removeDocumentListeners);
  }

  function getInitialPosition(element) {
  var rect={};
    if(getStyle(element,'position')=='absolute'){
        rect={top:parseInt(getStyle(element,'top')),left:parseInt(getStyle(element,'left'))};
    }else{
       rect = element.getBoundingClientRect();

    }
   return {
      top: rect.top,
      left: rect.left
    };
  }

  function inPixels(value) {
    return value + 'px';
  }

  function cancelDocumentSelection(event) {
    event.preventDefault && event.preventDefault();
    event.stopPropagation && event.stopPropagation();
    event.returnValue = false;
    return false;
  }

  function repositionElement(event) {
    event.preventDefault && event.preventDefault();
    event.returnValue = false;
    var style = currentElement.style;
    var elementXPosition = parseInt(style.left, 10);
    var elementYPosition = parseInt(style.top, 10);

    var elementNewXPosition = (event.offsetX != null) ? event.offsetX : event.originalEvent.layerX;
    var elementNewYPosition = (event.offsetY != null) ? event.offsetY : event.originalEvent.layerY; 

//    var elementNewXPosition = elementXPosition + (event.clientX - currentElement.lastXPosition);
//    var elementNewYPosition = elementYPosition + (event.clientY - currentElement.lastYPosition);

    style.left = inPixels(elementNewXPosition);
    style.top = inPixels(elementNewYPosition);

    currentElement.lastXPosition = elementNewXPosition;
    currentElement.lastYPosition = elementNewYPosition;

    $("#textbox_left").val(elementNewXPosition);
    $("#textbox_top").val(elementNewYPosition);

    triggerEvent('drag', { x: elementNewXPosition, y: elementNewYPosition, mouseEvent: event });
  }

  function removeDocumentListeners(event) {
    removeEventListener(document,'selectstart',cancelDocumentSelection);
    removeEventListener(document,'mousemove',repositionElement);
    removeEventListener(document,'mouseup',removeDocumentListeners);

    var left = parseInt(currentElement.style.left, 10);
    var top = parseInt(currentElement.style.top, 10);
    triggerEvent('stop', { x: left, y: top, mouseEvent: event });
  }

  return draggable;
});
!(函数(moduleName,定义){
//是将Draggable作为AMD模块公开还是将其公开给全局对象。
if(typeof define=='function'&&typeof define.amd=='object')定义(定义);
否则此[moduleName]=定义();
})('draggable',函数定义(){
函数addEventListener(元素、事件名、处理程序){
if(element.addEventListener){
元素addEventListener(事件名称,处理程序,false);
}else if(元素附件){
元素attachEvent('on'+eventName,handler);
}否则{
元素['on'+eventName]=处理程序;
}
}
函数removeEventListener(元素、事件名、处理程序){
if(element.removeEventListener){
元素。removeEventListener(eventName,handler,false);
}else if(element.detachEvent){
detachEvent('on'+eventName,handler);
}否则{
元素['on'+eventName]=null;
}
}
函数到内存库(s){
返回s.replace(/(\-[a-z])/g,函数($1){return$1.toUpperCase().replace('-','');});
}
函数getStyle(el、styleProp){
var s='';
如果(el['currentStyle']='object'的类型)
s=el.currentStyle[toCamelCase(styleProp)];
else if(window.getComputedStyle)
s=document.defaultView.getComputedStyle(el,null).getPropertyValue(styleProp);
返回s;
}
无功电流元件;
var fairlyHighZIndex='10';
可拖动的函数(元素、句柄){
句柄=句柄| |元素;
var-index=parseInt(getStyle(元素,'z-index'));
fairlyHighZIndex=isNaN(索引)‘10’:索引;
设置位置类型(元素);
SetDragableListeners(元素);
addEventListener(句柄、'mousedown',函数(事件){
if(event.which==null)
/*IE案例*/
按钮=(event.button<2)?“左”:
((event.button==4)?“中间”:“右”);
其他的
/*所有其他*/
按钮=(event.which<2)?“左”:
((event.which==2)?“中间”:“右边”);
按钮==='LEFT'&&startDraging(事件、元素);
});
}
函数setPositionType(元素){
element.style.position='absolute';
}
函数SetDragableListeners(元素){
element.DragableListeners={
开始:[],
拖动:[],
停止:[]
};
element.whenDragStarts=addListener(元素“start”);
element.whenDragging=addListener(元素“拖动”);
element.whenDragStops=addListener(元素“stop”);
}
函数启动跟踪(事件、元素){
currentElement和sendToBack(currentElement);
currentElement=bringToFront(元素);
var elementNewXPosition=(event.offsetX!=null)?event.offsetX:event.originalEvent.layerX;
var elementNewYPosition=(event.offsetY!=null)?event.offsetY:event.originalEvent.layerY;
var initialPosition=getInitialPosition(currentElement);
currentElement.style.left=inPixels(elementNewXPosition);
currentElement.style.top=inPixels(elementNewYPosition);
currentElement.lastXPosition=elementNewXPosition;
currentElement.lastYPosition=elementNewYPosition;
var-okToGoOn=triggerEvent('start',{x:initialPosition.left,y:initialPosition.top,mouseEvent:event});
如果(!OKTOGON)返回;
addDocumentListeners();
}
函数addListener(元素,类型){
返回函数(侦听器){
元素.DragableListeners[type].push(侦听器);
};
}
函数triggerEvent(类型,参数){
var结果=真;
var listeners=currentElement.DragableListeners[type];
对于(var i=listeners.length-1;i>=0;i--){
如果(侦听器[i](参数)==false)结果=false;
};
返回结果;
}
函数sendToBack(元素){
var递减指数=相当高的指数-1;
元素.style['z-index']=decreatedzindex;
元素.style['zIndex']=递减索引;
}
函数bringToFront(元素){
元素.style['z-index']=fairlyHighZIndex;
元素.style['zIndex']=fairlyHighZIndex;
返回元素;
}
函数addDocumentListeners(){
addEventListener(文档,'selectstart',取消文档选择);
addEventListener(文档,'mousemove',元素);
addEventListener(文档,'mouseup',removeDocumentListeners);
}
函数getInitialPosition(元素){
var rect={};
if(getStyle(元素,'position')=='absolute'){
rect={top:parseInt(getStyle(元素,'top')),left:parseInt(getStyle(元素,'left'))};
}否则{
rect=element.getBoundingClientRect();
}
返回{
top:rect.top,
左:rect.left
};
}
函数输入像素(值){
返回值+‘px’;
}
函数取消文档选择(事件){
event.preventDefault&&event.preventDefault();
event.stopPropagation&&event.stopPropagation();
event.returnValue=false;
返回false;
}
函数元素(事件){
event.preventDefault&&event.preventDefault();
event.returnValue=false