【问题标题】:Why is the event listener for an unwrapped jQuery element different from the listener on the actual jQuery element?为什么未包装的 jQuery 元素的事件侦听器与实际 jQuery 元素上的侦听器不同?
【发布时间】:2015-09-14 18:31:15
【问题描述】:

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?建议您创建一个复制您的问题的演示
  • jQuery 规范化事件对象,很可能规范化的事件对象不包含您期望的属性。我建议将其记录到控制台并检查它。或者,您可以使用e.originalEvent.whateverproperty 返回原始事件对象,但是,对于跨浏览器支持,我建议尽可能使用规范化事件对象。 在这种情况下,这似乎是不可能的。
  • @charlietfl - 它只是一个函数名,我重命名了它。我在上面添加了 JSFiddle 链接
  • @Pointy - self 是我从应用程序中提取出来的,我修复了它
  • 那么您根本不必使用箭头函数 - 只需 $("#dragMe").on("dragstart", handleDragStart) 即可。

标签: javascript jquery html draggable


【解决方案1】:

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

【讨论】:

  • 这在 JSFiddle 中有效,但在我的实际代码中,e.originalEvent 为空。任何想法为什么 e.originalEvent 将为空?我会在此期间寻找答案。
  • 我不知道,所有相同版本的jQuery?
  • 我们正在内部调查。由于我们有另一个插件,它可能是特定于应用程序的。感谢您的帮助!
【解决方案2】:

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 包装器中获得,实际上 OP 中的代码正在利用这一事实。
  • 没有真正的元素必须从 jquery 中检索,就像他对调用 (var $btnItem = $("#dragMe");) 所做的那样,但 Jquery 只是接受并应用 (el= document. getElementById(iDOfObject);) 找到并返回真实的给你。这个答案的前提是它不起作用,因为 Jquerys 元素不是真正的元素,除非 Jquery 调用 (el= document.getElementById(iDOfObject);),否则 Javascript 将无法识别它,因为 jquery 节省内存不会存储整个元素只是他们对它的解释。
  • 不,jQuery 包装了真实的 DOM 元素,而不是假的。我不知道你从哪里得到这个想法,但它是不正确的。
  • 我写过 Jquery 之类的包装器,并且我已经阅读了整个 jquery 脚本——我知道它的作用。
  • 在您的开发者控制台中输入$("body")[0],您将获得对&lt;body&gt; DOM 元素的引用。
猜你喜欢
  • 2011-01-28
  • 2012-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-30
  • 2019-01-29
  • 2015-09-20
  • 1970-01-01
相关资源
最近更新 更多