我目前正在尝试测试一些使用拖放的代码。我发现了其他一些与此有关的问题,但它们太具体了,无法帮助我,或者说不够相关。
这是一个测试,我正在努力尝试在.on('drop',function(e){....}
事件中自动执行代码。主要问题不是我无法在里面运行代码,而是因为我无法传输dataTransfer
属性,我似乎无法伪造它,因为它是只读的。无论如何都要伪造dataTransfer
财产或以其他方式解决它?
我想出了这个JSFiddle,作为我正在尝试做的模板:https://jsfiddle.net/gnq50hsp/53/
基本上如果你能够向我解释(如果可能的话)我怎么可能伪造dataTransfer
属性,我应该全部设定。
附注:
我完全愿意以某种方式进入代码,例如,可能触发事件并使用伪造的dataTransfer对象传递假事件对象。
< / LI>要查看拖放行为,请将JavaScript加载类型从no-wrap head
更改为on-Load
,然后您应该看到我正在尝试模拟的内容。
需要注意的是,我无法修改事件处理程序中的任何代码,只能在外部函数内修改
使用Karma / Jasmine,也可以像间谍一样使用这些工具
此外,我正在使用Chrome。
提前致谢,如有任何问题/澄清,请与我联系!
答案 0 :(得分:5)
您应该能够使用 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)
}
答案 1 :(得分:1)
根据jsfiddel链接,您希望实现拖放功能。 jQuery Draggable UI 已经提供了此功能,为什么你不能使用它?
要在途中创建自定义活动,您必须遵循两种替代方式
$('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
类型,并将其还原到映射的&#34;单击&#34;返回前输入: