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



参见JSFddle

问题:为什么展开jQuery元素并应用事件监听器工作,但当我将事件监听器直接应用到jQuery元素时,它不工作?见下文…

使用下面的代码,我试图从原始位置捕获拖动距离。当用户从原点拖动超过120像素时,我将打印到控制台,我们"在边界之外"。

如果我通过展开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规范了事件对象,以提供一个在所有浏览器中都能工作的接口。不幸的是,这意味着要删除某些不受所有浏览器支持的属性。您可以通过访问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));

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);

最新更新