簡體   English   中英

如何使用自定義事件(特別是自定義dataTransfer屬性)觸發事件?

[英]How to trigger an event with a custom event (specifically a custom dataTransfer property)?

我目前正在嘗試測試一些使用拖放的代碼。 我發現了一些與此相關的其他問題,但是它們太具體了而無法幫助我,或者相關性不夠。

這是一個測試,我努力嘗試在.on('drop',function(e){....}事件中自動執行代碼。主要問題不是我無法在其中運行代碼,但這是因為我無法傳輸dataTransfer屬性,而且由於它是只讀的,因此我似乎無法偽造它。是否總有可能偽造dataTransfer屬性或解決它?

我想出了這個JSFiddle,它充當了我想要做的事情的模板: https ://jsfiddle.net/gnq50hsp/53/

本質上,如果您能夠向我解釋(如果有可能的話)我如何可以偽造dataTransfer屬性,那么我應該已經准備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鏈接,您要實現拖放功能。 jQuery的可拖動的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()方法將事件類型和事件處理函數作為參數。 可選地,它還可以接收與事件相關的數據作為其第二個參數,從而將事件處理功能推到第三個參數。 傳遞的任何數據將提供給在事件對象的數據屬性的事件處理函數。 事件處理函數始終將事件對象作為其第一個參數。

.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特殊事件本身映射到一個標准的click事件,但使用的是手柄掛鈎,以便它可以監視活動,只有提供它在元素上的用戶點擊事件中的指定次數的倍數結合。

鈎存儲當前點擊計數在數據對象,所以multiclick處理程序不同的元件不相互干擾。 它改變事件類型為原始multiclick類型返回之前調用處理和恢復它映射的“點擊式”前:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM