为什么未包装的 jQuery 元素的事件侦听器与实际 jQuery 元素上的侦听器不同?

Why is the event listener for an unwrapped jQuery element different from the listener on the actual jQuery element?

JSFddle

问题:为什么展开 jQuery 元素并应用事件侦听器会起作用,但是当我将事件侦听器直接应用于 jQuery 元素时,却不起作用?见下文...

使用以下代码,我试图捕获从原始位置开始的拖动距离。当用户从原点拖动超过 120 像素时,我将打印到控制台,我们是 "outside of the boundary".

如果我通过展开 jQuery 元素来添加侦听器,它将按预期工作并触发调用:

$btnItem[0].addEventListener("drag", function (e) { self.handleDrag(e); }, false);

如果我将侦听器添加到实际的 jQuery 元素,它不会触发调用:

$btnItem.on('drag', e=> self.handleDrag(e));

关于为什么展开 jQuery 元素有效但实际 jQuery 方法无效的任何想法?似乎jQuery失去了与鼠标位置的联系。

HTML:

<div style="padding:100px;">
  <span id="dragMe" draggable="true">Drag</span>
</div>

CSS:

#dragMe{
    display: inline-block;
    padding: 6px 12px;
    margin-bottom: 0;
    font-size: 14px;
    font-weight: 400;
    line-height: 1.42857143;
    text-align: center;
    white-space: nowrap;
    vertical-align: middle;
    -ms-touch-action: manipulation;
    touch-action: manipulation;
    cursor: pointer;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    background-image: none;
    border: 1px solid transparent;
    border-radius: 4px;

    color: #fff;
    background-color: #337ab7;
    border-color: #2e6da4;
}

代码:

var oPos = [];
function handleDragStart(e) {
  oPos = [e.clientX, e.clientY];
  e.target.style.opacity = '0.4';  // this / e.target is the source node.
}

function handleDrag(e) {
  var nPos = [e.clientX, e.clientY];
  var d = Math.sqrt((oPos[0] - nPos[0]) * (oPos[0] - nPos[0]) + (oPos[1] - nPos[1]) * (oPos[1] - nPos[1]));
  if (d > 120) {
    console.log('outside of the boundary');
  }
}

function handleDragEnd(e) {
  e.target.style.opacity = '1.0';  // this / e.target is the source node.
}

function jQueryUnWrap(){
  var $btnItem = $("#dragMe");
    $btnItem[0].addEventListener("dragstart", function(e) {
      handleDragStart(e);
    }, false);
    $btnItem[0].addEventListener("dragend", function (e) {
      handleDragEnd(e);
    }, false);
    $btnItem[0].addEventListener("drag", function (e) {
      handleDrag(e);
    }, false);
}

function jQueryWrap(){
  var $btnItem = $("#dragMe");
  $btnItem.on('dragstart', e=> handleDragStart(e));
  $btnItem.on('dragend', e=> handleDragEnd(e));
  $btnItem.on('drag', e=> handleDrag(e));
}

$(document).ready(function(){
  jQueryUnWrap();
  //jQueryWrap();
});

JQuery 元素不是真实元素,它们是代表真实元素的对象的占位符或包装器。访问 Jquery 之外的真实元素的唯一方法是使用真实的 javascript。

el= document.getElementById(iDOfObject);

然后你可以一个监听器,但是,你应该使用一个函数来添加一个监听器,因为浏览器的方式不同

function addEvent (el, type, func, rtn) 
{
   if (el == null || el == undefined) return;
   if (el.attachEvent) {
      el.attachEvent("on"+type, func)
   } else if (el.addEventListener) {
      el.addEventListener(type, func, false)
   } else if (document.getElementById) 
   {
      var evFuncs = el["on"+type];
      if (evFuncs != 'undefined' && evFuncs != null) 
      {
         el["on"+type] = function() {
            evFuncs();
            func();
            if (rtn != null)
               return rtn;
         };

         }  else 
      {
            el["on"+type] = func;
         if (rtn != null)
            el["on"+type] += ';return '+ rtn;
      }
      evFuncs = null;
   }
   func = null;
};

这样称呼

addEvent(el, "drag", function (e) {
  self.handleDrag(e);
}, false);

jQuery 规范化事件对象以提供适用于所有浏览器的界面。不幸的是,这意味着要删除并非所有浏览器都支持的某些属性。您可以通过访问 originalEvent 属性.

返回到原始事件对象
$btnItem.on('dragstart', e=> self.handleDragStart(e.originalEvent));
$btnItem.on('dragend', e=> self.handleDragEnd(e.originalEvent));
$btnItem.on('drag', e=> self.handleDrag(e.originalEvent));