在Javascript/jQuery中克隆一个事件对象

3
我该如何创建一个全新的事件对象,它包含与给定事件对象 e 完全相同的所有属性?到目前为止,我尝试了以下方法,但没有成功:
function myHandler(e) {
   // ...

   e = e.originalEvent;

   // method 1
   var e2 = jQuery.extend(true, {}, e);

   // method 2
   var e2 = JSON.parse(JSON.stringify(e));

   // ...
}

编辑:我将添加更多细节以帮助澄清。与这个问题非常相似,我正在尝试执行:div.dispatchEvent(e.originalEvent),但是这样做会导致:

DISPATCH_REQUEST_ERR:DISPATCH_REQUEST_ERR:DOM事件异常1

为了避免这种情况,我需要复制事件对象。然而,此事件对象并不是特定的(即,有时etouchstarttouchmovetouchend),因此如果我可以获得通用的克隆函数,而不仅仅是硬编码具体属性,则会更容易一些。我所说的“没有运气”的意思是通过尝试上述方法并将其发送到分派函数中,我正在收到错误。希望这可以稍微澄清一下。


已更新。抱歉,之前有个笔误。 - paul smith
2
不加 e = e.originalEventjQuery.extend(true, {}, e) 怎么样? 还有你说的“no luck”是什么意思? :) - Michał Miszczyszyn
"DISPATCH_REQUEST_ERR: 如果事件对象已经在树中分派。" - Michał Miszczyszyn
为什么需要克隆一个事件? - Michał Miszczyszyn
就像我说的那样,我正在尝试将事件传递给另一个元素,这也类似于我发布的示例链接。你看了我的更新吗? :) - paul smith
4个回答

4

我用这段代码运气不错:

$.extend($.Event(event.type /* click, mousedown, touchstart, ect. ect. */), {
    which: 1,
    clientX: event.clientX,
    clientY: event.clientY,
    pageX: event.pageX,
    pageY: event.pageY,
    screenX: event.screenX,
    screenY: event.screenY
});

显然,这是全部内容;但你可以在其他对象中添加实际需要的内容。我在此创建一个新事件,因为我实际上是将事件转发到另一个元素。


更新:

我使用 jQuery Touch Punch Plugin,它基本上将点击/鼠标事件映射到相关的触摸事件:touchstart、touchesmoved、touchend。因此,如果您将此事件作为鼠标事件转发:

var newEvent = $.extend($.Event(event.type), {
    which: 1,
    clientX: event.clientX,
    clientY: event.clientY,
    pageX: event.pageX,
    pageY: event.pageY,
    screenX: event.screenX,
    screenY: event.screenY
});

// touch punch will convert to a touch event if needed
$('.some-other-element').trigger(newEvent); 

您只需要在页面上包含touch punch脚本。这也将允许jQuery UI元素在触摸设备上运行。

参考资料:


我添加了一些更多的信息。看起来我们正在实现类似的目标。 - Joe
+1. 最好编写自己的函数,复制所需的所有属性。 - Michał Miszczyszyn

2

下面的答案标记为 "只需传入本机事件参数"。

function (e) {
    var $event = $.Event(e.type, e);
}

如果您想更改事件类型,则以下方法不起作用:jQuery将使用您传递的事件对象中的事件类型替换您指定的事件类型参数。因此,此方法仅用作完全克隆事件对象的手段。在这样做时,建议将null替换为事件类型参数,作为语义提示,表明事件正在严格克隆:

function (e) {
    var event = $.Event(null, e); // clone event
}

当然,在克隆后您始终可以更改事件的类型值:

function (kind, e) {
    var event = $.Event(null, e); // clone event
    event.eventType = kind;

    return event;
}

1

只需传入本地事件参数

function (e) {
    var $event = $.Event(e.type, e);
}

因为您可以手动设置的所有属性已经存在于本机事件参数中,而且因为$.Event()构造函数将对象作为其第二个参数,所以您可以简单地将本机事件参数传递给它。
注意:必须单独传递事件类型作为第一个参数才能使此方法工作,否则jQuery将只会将您的事件对象存储在$event.originalEvent中。

1
很好,这应该是答案。 - kofifus

0
var eDemo = jQuery.Event("eventhandler", {
    target: e.currentTarget,
    relatedTarget: e.relatedTarget,
    pageX: e.pageX,
    pageY: e.pageY,
    which: e.which,    
});

var newObject = jQuery.extend(true, {}, eDemo);// deep copy

查看Jquery事件构造 -> http://api.jquery.com/category/events/event-object/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接