2016-08-18 84 views
6

我目前正试图测试一些使用拖放的代码。我发现了一些与此有关的其他问题,但他们的方式太具体,无法帮助我,或者不够相关。如何使用自定义事件(特别是自定义dataTransfer属性)触发事件?

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

我想出了这样的jsfiddle充当的是什么,我试图做一个模板:https://jsfiddle.net/gnq50hsp/53/

从本质上讲,如果你能向我解释(如果这是在所有可能的),我怎么可能假冒dataTransfer财产,我应该全部设置。

旁注:

  • 我要的码内部莫名其妙地得到,例如像,也许它可能触发事件,并通过在假事件对象与其他方式完全开放一个假的dataTransfer对象。

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

  • 需要注意的是,我不能修改任何代码的事件处理程序里面,只有内外部功能

  • 使用噶/茉莉花所以使用这些工具也可以像间谍

  • 另外,我正在使用Chrome。

在此先感谢,并让我知道任何问题/澄清!

回答

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

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

+0

啊,这是完美的,正是我所期待的。非常感谢! – Ted

+0

当我需要将数据作为文件传递时,我会非常感兴趣的。 http://stackoverflow.com/questions/39487340/trigger-drop-event-while-providing-the-file-data在sait jamais上。 – oldergod

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方法:。对()和.trigger()。在Events章节中,我们看到了如何使用这些方法来处理用户事件;对于本章,重要的是要记住两件事:

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

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

下面是在这两种情况下使用自定义数据。对()和.trigger(的使用的一个例子):

OR

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特殊事件将自己映射到一个标准的单击事件,但使用一个句柄钩子,以便它可以监视事件,并且只在用户单击时才传递它n元素是事件绑定期间指定次数的倍数。

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

+0

拖放事件参考,http://api.jqueryui.com/draggable /#event-start,jquery UI已经为拖放实用程序提供了扩展 –

+0

我欣赏Haresh提供的非常详细和翔实的响应,但如果我解释你说的正确,这不是我所知道的寻找。不幸的是我无法编辑事件监听器本身,所以我不能传入额外的参数。因此,例如,在我的JSFiddle中,我只能在最终函数中添加代码,并在其中添加注释。 – Ted