How to trigger an event with a custom event (in particular, the dataTransfer custom property)?

I'm currently trying to test code that uses drag-and-drop. I found some other questions that were related to this, but they were too specific to help me or were not related enough.

This is a test, I'm struggling to automatically execute the code inside the .on('drop',function(e){....} event. The main problem is not that I cannot run the code inside, but I cannot pass the dataTransfer and I can't fake it because it is read-only Is there a way to fake the dataTransfer or otherwise get around it?

I came up with this JSFiddle, which serves as a template for what I'm trying to do: https://jsfiddle.net/gnq50hsp/53/

Essentially, if you are able to explain to me (if at all possible) how I can fake the dataTransfer , I should be set.

Side notes:

  • I am completely open to other ways to somehow get inside this code, for example, perhaps it can be triggered by an event and passed to a fake object with a fake dataTransfer object.

  • To see the drag and drop behavior, change the JavaScript loading type from no-wrap head to on-Load , then you should see what I'm trying to simulate.

  • It is important to note that I cannot change any code inside event handlers, only inside an external function

  • The use of karma / jasmine, so the use of these tools is also possible as spies

  • In addition, I use Chrome.

Thanks in advance, and let me know for any questions / clarifications!

+6
source share
2 answers

You can completely redefine everything you want using Object.defineProperty . Depending on what you want to check, it can be very simple or very difficult. Faking dataTransfer can be a bit complicated, as it has many limitations and behaviors, but if you just want to test the drop function, it's pretty simple.

Here is the way, this should give you some ideas on how to fake some events and data:

 //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/

+5
source

By jsfiddel link you want to get drag and drop function. jQuery Draggable UI already provides this feature, why can't you use it?

To create a custom event in your path, you must follow two alternative methods.

 $('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" ] ); 

In the example above

In the world of custom events, there are two important jQuery methods: .on () and .trigger (). In the Events chapter, we saw how to use these methods to work with custom events; For this chapter, it is important to remember two things:

.on () takes an event type and an event handling function as arguments. In addition, it can also receive event-related data as its second argument by pressing the event-processing function on the third argument. Any transmitted data will be available for the event processing function in the data property of the event object. The event handling function always takes an event object as its first argument.

. The trigger () method takes an event type as an argument. If desired, it can also take an array of values. These values ​​will be passed to the event processing function as arguments after the event object.

Here is an example of using .on () and .trigger (), which uses user data in both cases:

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

In the example above

This special multiclick event maps itself to the standard click event, but uses a handle to the handle so that it can track the event and only deliver it when the user clicks on an element multiple of the number of times specified during the binding event.

The hook stores the current number in the data object, so multiclick handlers on different elements do not interfere with each other. It changes the type of the event to the original multiclick type before calling the handler and restores it to the display type "click" before returning:

+1
source

All Articles