77

ユーザーが特定のリンクをクリックすると、確認ダイアログが表示されます。「はい」をクリックすると、元のナビゲーションを続行したいと思います。キャッチ 1 つ: 私の確認ダイアログは、ユーザーが [はい] ボタンをクリックした場合にのみ解決される jQuery.Deferred オブジェクトを返すことによって実装されます。したがって、基本的に確認ダイアログは非同期です。

だから基本的に私はこのようなものが欲しい:

$('a.my-link').click(function(e) {
  e.preventDefault(); e.stopPropogation();
  MyApp.confirm("Are you sure you want to navigate away?")
    .done(function() {
      //continue propogation of e
    })
})

もちろん、フラグを設定してクリックを再トリガーすることもできますが、それは面倒です。これを行う自然な方法はありますか?

4

8 に答える 8

14

以下は、驚いたことに、Chrome 13 で実際に機能したコードの一部です。

function handler (evt ) {
    var t = evt.target;
    ...
    setTimeout( function() {
        t.dispatchEvent( evt )
    }, 1000);
    return false;
}

これはあまりクロスブラウザーではなく、セキュリティ上のリスクがあるように感じられるため、将来的に修正される可能性があります。

イベントの伝播をキャンセルすると、何が起こるかわかりません。

于 2011-10-18T20:19:09.177 に答える
4

リスクが高いかもしれませんが、少なくとも執筆時点では機能しているようです。本番環境で使用しています。

これは ES6 と React です。テストしたところ、以下のブラウザで動作することがわかりました。ボーナスの 1 つは、例外がある場合 (これを作成する途中でカップルがいた場合)、通常のリンクのようにリンクに移動し<a>ますが、SPA ではなく、ofc になります。

デスクトップ:

  • クローム v.76.0.3809.132
  • サファリ v.12.1.2
  • Firefox Quantum v.69.0.1
  • エッジ 18
  • エッジ 17
  • IE11

モバイル/タブレット:

  • アンドロイド v.8 サムスン インターネット
  • アンドロイド v.8 クローム
  • アンドロイド v.9 クローム
  • iOS11.4 サファリ
  • iOS12.1 サファリ

.

import 'mdn-polyfills/MouseEvent'; // for IE11
import React, { Component } from 'react';
import { Link } from 'react-router-dom';

class ProductListLink extends Component {
  constructor(props) {
    super(props);
    this.realClick = true;

    this.onProductClick = this.onProductClick.bind(this);
  }

  onProductClick = (e) => {
    const { target, nativeEvent } = e;
    const clonedNativeEvent = new MouseEvent('click', nativeEvent);

    if (!this.realClick) {
      this.realClick = true;
      return;
    }

    e.preventDefault();
    e.stopPropagation();

    // @todo what you want before the link is acted on here

    this.realClick = false;
    target.dispatchEvent(clonedNativeEvent);
  };

  render() {
    <Link
      onClick={(e => this.onProductClick(e))}
    >
      Lorem
    </Link>  
  }
}
于 2019-09-20T10:29:12.127 に答える
3

私のプロジェクトの1つで、この方法で問題を解決しました。この例は、クリックなどのいくつかの基本的なイベント処理で機能します。確認用のハンドラーは、最初のハンドラーにバインドする必要があります。

    // This example assumes clickFunction is first event handled.
    //
    // you have to preserve called function handler to ignore it 
    // when you continue calling.
    //
    // store it in object to preserve function reference     
    var ignoredHandler = {
        fn: false
    };

    // function which will continues processing        
    var go = function(e, el){
        // process href
        var href = $(el).attr('href');
        if (href) {
             window.location = href;
        }

        // process events
        var events = $(el).data('events');

        for (prop in events) {
            if (events.hasOwnProperty(prop)) {
                var event = events[prop];
                $.each(event, function(idx, handler){
                    // do not run for clickFunction
                    if (ignoredHandler.fn != handler.handler) {
                        handler.handler.call(el, e);
                    }
                });
            }
        }
    }

    // click handler
    var clickFunction = function(e){
        e.preventDefault();
        e.stopImmediatePropagation();
        MyApp.confirm("Are you sure you want to navigate away?")
           .done(go.apply(this, e));
    };

    // preserve ignored handler
    ignoredHandler.fn = clickFunction;
    $('.confirmable').click(clickFunction);

    // a little bit longer but it works :)
于 2012-05-17T08:37:38.847 に答える
0

私たちのプロジェクトには同様の要件があり、これは私にとってはうまくいきます。Chrome と IE11 でテスト済み。

$('a.my-link').click(function(e) {
  e.preventDefault(); 
  if (do_something === true) {
    e.stopPropogation();
    MyApp.confirm("Are you sure you want to navigate away?")
    .done(function() {
      do_something = false;
      // this allows user to navigate 
      $(e.target).click();
    })
  }

})
于 2017-08-09T10:48:21.637 に答える
-2

これはテストされていませんが、回避策として役立つ可能性があります

$('a.my-link').click(function(e) {
  e.preventDefault(); e.stopPropogation();
  MyApp.confirm("Are you sure you want to navigate away?")
    .done(function() {
      //continue propogation of e
      $(this).unbind('click').click()
  })
})
于 2011-10-18T18:46:48.190 に答える