1. ホーム
  2. jquery

[解決済み] JQuery event.preventDefault() が設定されているときに window.open でポップアップブロッカーを回避する。

2023-01-19 09:24:43

質問

ハイパーリンクのクリックイベントに応じて、JQueryダイアログを表示したいのですが。

条件1を満たすとJQueryダイアログを表示し、条件1を満たさない場合は、そのクリックイベントのhrefタグで参照されるページに移動するような要件があります。

リンクのクリックイベントで関数を呼び出すことができました。この関数は、別のURL(Springコントローラを実行し、レスポンスを返す)を実行することによって、前述の条件をチェックするようになりました。

ポップアップ ブロッカーによって window.open がブロックされただけで、すべてが完璧に動作しています。

$('a[href*=/viewpage?number]').live('click', function(e) {
    e.preventDefault();
    redirectionURL = this.href;
    pageId= getUrlVars(redirectionURL)["number"];
    $.getJSON("redirect/" + pageId, {}, function(status) {
        if (status == null) {
            alert("Error in verifying the status.");
        } else if(!status) {
            $("#agreement").dialog("open");
        } else {
            window.open(redirectionURL);
        }
    });
});

もし私が e.preventDefault(); を削除すると、popoup blocker はページをブロックしませんが、条件1ではダイアログを開くと同時に 'href' ページを開いてしまいます。

一方を解決すると、もう一方に問題が発生します。両方の条件を同時に満たすことはできません。

この問題を解決する手助けをしていただけないでしょうか。

これが解決されると、私はダイアログのOKイベントでのナビゲーションという別の問題を解決する必要があります :)

どのように解決するのですか?

ポップアップブロッカーは、通常 window.open が使われている場合 の間に ユーザーイベント(クリックなど)の処理中。この場合、あなたは window.open 後に というのは、イベント中ではなく $.getJSON は非同期だからです。

2つのオプションがあります。

  1. 何か他のことをする、むしろ window.open .

  2. ajax呼び出しを同期にします。これは、ブラウザのUIをロックしてしまうので、通常、疫病のように避けるべきことです。 $.getJSON とは同等です。

    $.ajax({
      url: url,
      dataType: 'json',
      data: data,
      success: callback
    });
    
    

    ...というわけで、あなたの $.getJSON の呼び出しを同期にするには、パラメータを上記のようにマッピングして async: false :

    $.ajax({
        url:      "redirect/" + pageId,
        async:    false,
        dataType: "json",
        data:     {},
        success:  function(status) {
            if (status == null) {
                alert("Error in verifying the status.");
            } else if(!status) {
                $("#agreement").dialog("open");
            } else {
                window.open(redirectionURL);
            }
        }
    });
    
    

    繰り返しますが、あなたの目標を達成するために他の方法を見つけることができるなら、私は同期ajax呼び出しを勧めません。しかし、それができないのであれば、そこに行きます。

    非同期呼び出しのためにテストに失敗するコードの例です。

    ライブの例 | ライブ音源 (JSBinの変更に伴い、ライブリンクは機能しなくなりました)

    jQuery(function($) {
      // This version doesn't work, because the window.open is
      // not during the event processing
      $("#theButton").click(function(e) {
        e.preventDefault();
        $.getJSON("http://jsbin.com/uriyip", function() {
          window.open("http://jsbin.com/ubiqev");
        });
      });
    });
    
    

    そして、同期呼び出しを用いて動作する例を示します。

    ライブの例 | ライブ音源 (JSBinの変更に伴い、ライブリンクは機能しなくなりました)

    jQuery(function($) {
      // This version does work, because the window.open is
      // during the event processing. But it uses a synchronous
      // ajax call, locking up the browser UI while the call is
      // in progress.
      $("#theButton").click(function(e) {
        e.preventDefault();
        $.ajax({
          url:      "http://jsbin.com/uriyip",
          async:    false,
          dataType: "json",
          success:  function() {
            window.open("http://jsbin.com/ubiqev");
          }
        });
      });
    });