如何使用自定义事件(特别是自定义dataTransfer属性)触发事件?

我目前正在尝试测试一些使用拖放的代码。 我发现了一些与此有关的其他问题,但它们太具体了,无法帮助我,或者说不够相关。

这是一个测试,我正在努力尝试在.on('drop',function(e){....}事件中自动执行代码。主要问题不是我无法在里面运行代码,但这是我无法传输dataTransfer属性,我似乎无法伪造它,因为它是只读的。无论如何伪造dataTransfer属性或以其他方式解决它?

我想出了这个JSFiddle,作为我正在尝试做的模板: https ://jsfiddle.net/gnq50hsp/53/

基本上如果你能够向我解释(如果这是可能的话)我怎么可能伪造dataTransfer属性,我应该全部设置。

附注:

  • 我完全愿意以某种方式进入代码,例如,可能触发事件并使用伪造的dataTransfer对象传递假事件对象。

  • 要查看拖放行为,请将JavaScript加载类型no-wrap head更改为on-Load ,然后您应该看到我正在尝试模拟的内容。

  • 需要注意的是,我无法修改事件处理程序中的任何代码,只能在外部函数内部修改

  • 使用Karma / Jasmine可以使用这些工具,就像间谍一样

  • 另外,我正在使用Chrome。

在此先感谢,如有任何问题/澄清,请与我联系!

您应该能够使用Object.defineProperty覆盖您想要的所有内容。 根据您要测试的内容,它可能非常简单或非常复杂。 伪造dataTransfer可能有点棘手,因为有许多限制和行为与它相关联,但如果你只是想测试drop函数,那就相当容易了。

这是一种方式,这应该给你一些关于如何伪造一些事件和数据的想法:

 //Event stuff var target = $('#target'); var test = $('#test'); test.on('dragstart', function(e) { e.originalEvent.dataTransfer.setData("text/plain", "test"); }); target.on('dragover', function(e) { //e.dataTransfer.setData('test'); e.preventDefault(); e.stopPropagation(); }); target.on('dragenter', function(e) { e.preventDefault(); e.stopPropagation(); }); //What I want to simulate: target.on('drop', function(e) { console.log(e) //Issue is that I can't properly override the dataTransfer property, since its read-only document.getElementById('dataTransferDisplay').innerHTML = e.originalEvent.dataTransfer.getData("text"); }); function simulateDrop() { // You'll need the original event var fakeOriginalEvent = new DragEvent('drop'); // Using defineProperty you can override dataTransfer property. // The original property works with a getter and a setter, // so assigning it won't work. You need Object.defineProperty. Object.defineProperty(fakeOriginalEvent.constructor.prototype, 'dataTransfer', { value: {} }); // Once dataTransfer is overridden, you can define getData. fakeOriginalEvent.dataTransfer.getData = function() { return 'test' }; // TO have the same behavior, you need a jquery Event with an original event var fakeJqueryEvent = $.Event('drop', { originalEvent: fakeOriginalEvent }); target.trigger(fakeJqueryEvent) } 

https://jsfiddle.net/0tbp4wmk/1/

根据jsfiddel链接,您希望实现拖放function。 jQuery Draggable UI已经提供了这个function,为什么你不能使用它?

要在途中创建自定义事件,您必须遵循两种替代方法

 $('your selector').on( "myCustomEvent", { foo: "bar" }, function( event, arg1, arg2 ) { console.log( event.data.foo ); // "bar" console.log( arg1 ); // "bim" console.log( arg2 ); // "baz" }); $( document ).trigger( "myCustomEvent", [ "bim", "baz" ] ); 

在上面的例子

在自定义事件的世界中,有两个重要的jQuery方法:.on()和.trigger()。 在“事件”一章中,我们了解了如何使用这些方法来处理用户事件; 对于本章,重要的是要记住两件事:

.on()方法将事件类型和事件处理函数作为参数。 可选地,它还可以接收与事件相关的数据作为其第二个参数,将事件处理函数推送到第三个参数。 传递的任何数据都可用于事件对象的data属性中的事件处理函数。 事件处理函数始终接收事件对象作为其第一个参数。

.trigger()方法将事件类型作为其参数。 或者,它也可以采用一组值。 这些值将作为事件对象之后的参数传递给事件处理函数。

以下是在两种情况下使用自定义数据的.on()和.trigger()的使用示例:

要么

 jQuery.event.special.multiclick = { delegateType: "click", bindType: "click", handle: function( event ) { var handleObj = event.handleObj; var targetData = jQuery.data( event.target ); var ret = null; // If a multiple of the click count, run the handler targetData.clicks = ( targetData.clicks || 0 ) + 1; if ( targetData.clicks % event.data.clicks === 0 ) { event.type = handleObj.origType; ret = handleObj.handler.apply( this, arguments ); event.type = handleObj.type; return ret; } } }; // Sample usage $( "p" ).on( "multiclick", { clicks: 3 }, function( event ) { alert( "clicked 3 times" ); }); 

在上面的例子

multiclick特殊事件将自身映射到标准单击事件,但使用句柄挂钩,以便它可以监视事件,并且仅在用户单击事件绑定期间指定的次数的倍数时才传递它。

钩子将当前点击计数存储在数据对象中,因此不同元素上的multiclick处理程序不会相互干扰。 它在调用处理程序之前将事件类型更改为原始的multiclick类型,并在返回之前将其还原为映射的“click”类型: