7

https://stackoverflow.com/a/10310815/698289の draghover プラグインのおかげで、Chrome/Safari でこれまでのところ正常に動作している画面全体の dragenter/leave を追跡しようとしています。

$.fn.draghover = function(options) {
    return this.each(function() {

        var collection = $(),
            self = $(this);

        self.on('dragenter', function(e) {
            if (collection.size() === 0) {
                self.trigger('draghoverstart');
            }
            collection = collection.add(e.target);
        });

        self.on('dragleave drop', function(e) {
            // timeout is needed because Firefox 3.6 fires the dragleave event on
            // the previous element before firing dragenter on the next one
            setTimeout( function() {
                collection = collection.not(e.target);
                if (collection.size() === 0) {
                    self.trigger('draghoverend');
                }
            }, 1);
        });
    });
};

function setText(text) {
    $('p.target').text(text);
}

$(document).ready(function() {
    $(window).draghover().on({
        'draghoverstart': function() {
            setText('enter');
        },
        'draghoverend': function() {
            setText('leave');
        }
    });
});

ただし、テキスト項目をドラッグすると、Firefox でまだ問題が発生します。デモ用のフィドルを次に示します: http://jsfiddle.net/tusRy/6/

これは Firefox のバグですか、それとも JS で対処できますか? または、これらすべてを実行するためのより堅牢な方法はありますか?

ありがとう!

更新:混乱を少し減らすために、フィドルをhttp://jsfiddle.net/tusRy/6/に更新しました。フィドルの予想される動作を説明するには:

  • ファイルをウィンドウにドラッグすると、p.target が黄色の「ENTER」になるはずです。
  • ファイルをウィンドウの外にドラッグすると、p.target が赤色の「LEAVE」になるはずです。
  • ウィンドウにファイルをドロップすると、p.target は赤色の「LEAVE」になります。

Firefox では、ファイルをテキスト上にドラッグすると、LEAVE イベントがトリガーされます。

4

4 に答える 4

9

バージョン 22.0 の時点で、Firefox はまだこれを行っています。テキスト ノードをドラッグすると、2 種類のdragenteranddragleaveイベントが発生します。1 つはイベント ターゲットと relatedTarget の両方がテキスト ノードの親要素であり、もう 1 つはターゲットが親要素で relatedTarget が実際のテキスト ノードです (適切な DOM 要素でさえありません)。

dragenter回避策は、ハンドラーとハンドラーでこれら 2 種類のイベントを確認し、それらdragleaveを無視することです。

try {
    if(event.relatedTarget.nodeType == 3) return;
} catch(err) {}
if(event.target === event.relatedTarget) return;

try/catch ブロックを使用して nodeType をチェックします。これは、ドキュメントの外部 (他の iframe など) からイベントが (不可解に) 発生することがあり、nodeType にアクセスしようとするとアクセス許可エラーがスローされるためです。

実装は次のとおりです。 http://jsfiddle.net/9A7te/

于 2013-07-17T05:59:09.530 に答える
2

1) ドロップゾーンには子要素が 1 つだけあり、それ以外に必要なものがすべて含まれている可能性があります。何かのようなもの

<div id="#dropzone">
    <div><!--Your contents here--></div>
</div>

2) この CSS を使用します。

#dropzone * { pointer-events: none; }

は適用されないため、 :beforeandを含める必要がある場合があります。:after*

Firefox と Chrome でドロップを機能させるには、これで十分です。あなたの例では、次を追加するだけで十分です。

body * { pointer-events: none; }

CSS の末尾。私はここでそれをやった:

その他の例:

于 2013-09-01T00:36:33.967 に答える
1

I came up with kind of a solution, yet to test on other browsers other than Chrome and FF but working so far. This is how the setTimeout looks now:

setTimeout( function() {
    var isChild = false;

    // in order to get permission errors, use the try-catch
    // to check if the relatedTarget is a child of the body
    try {
        isChild = $('body').find(e.relatedTarget).length ? true : isChild;
    }
    catch(err){} // do nothing

    collection = collection.not(e.target);
    if (collection.size() === 0 && !isChild) {
        self.trigger('draghoverend');
    }
}, 1);

The entire code here - http://jsfiddle.net/tusRy/13/.

The idea is to check if the related tag is a child of the body, in which case we are still in the Browsers and the draghoverend event should be not triggered. As this can throw errors when moving out of the windows, I used a try method to avoid it.

Well, perhaps somebody with more skills on JS could improve this :)

于 2013-03-31T18:05:00.587 に答える