JQuery Event.preventDefault () सेट होने पर विंडो पर पॉपअप ब्लॉकर को बायपास करें


98

मैं हाइपरलिंक के क्लिक इवेंट पर सशर्त रूप से एक JQuery संवाद दिखाना चाहता हूं।

मुझे शर्त की आवश्यकता है जैसे कंडीशन 1 पर एक JQuery डायलॉग खोलें और अगर कंडीशन 1 संतुष्ट नहीं है, तो पृष्ठ पर नेविगेट करें, क्योंकि 'href' टैग से संदर्भित है जिसकी क्लिक ईवेंट प्रश्न में है।

मैं लिंक के क्लिक इवेंट पर एक फ़ंक्शन को कॉल करने में सक्षम हूं। यह फ़ंक्शन अब किसी अन्य URL को निष्पादित करके उक्त स्थिति की जांच करता है (जो मेरे स्प्रिंग नियंत्रक को निष्पादित करता है और प्रतिक्रिया देता है)।

सभी कार्य केवल विंडो के साथ सही काम करते हैं। पॉपअप ब्लॉकर द्वारा अवरुद्ध किया जा रहा है।

$('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();कोड से हटाता हूं , तो पॉपअप ब्लॉकर पृष्ठ को ब्लॉक नहीं करता है, हालांकि कंडीशन 1 के लिए यह फिर संवाद खोलता है और साथ ही 'href' पेज को खोलता है।

अगर मैं एक को हल करता हूं, तो यह दूसरे के लिए मुद्दा बनाता है। मैं एक साथ दोनों स्थितियों को न्याय नहीं दे पा रहा हूं।

कृपया आप मुझे इस मुद्दे को हल करने में मदद कर सकते हैं?

एक बार यह हल हो जाने के बाद मेरे पास एक और मुद्दा है हल करने के लिए यानी नेविगेशन ऑन डायलॉग ओके इवेंट :)


1
उपयोग करने के लिए नहीं की कोशिश करो। इसके पदावनत और .on () के लिए एक सूचक!
मास-डिजाइन 10

@ ईवीएलपी: जैसा कि अन्य लोगों ने पिछली बार कहा था, केवल 1.7 और ऊपर में। एक बहुत परियोजनाओं के अभी भी 1.5 या 1.6 पर होगा।
टीजे क्राउडर

10
Downvoter: सिर्फ इसलिए कि आप पॉपअप पसंद नहीं करते हैं, इसका मतलब यह नहीं है कि इस सवाल को कम किया जाना चाहिए। एक प्रश्न को अस्वीकृत कर दिया जाना चाहिए अगर यह "... कोई शोध प्रयास नहीं दिखाता है; यदि यह अस्पष्ट है या उपयोगी नहीं है" । प्रश्न स्पष्ट है, आलसी प्रतीत नहीं होता है, और कारकों के गैर-तुच्छ संयोजन से उपजी है।
टीजे क्राउडर

@TJCrowder: उन्होंने निर्दिष्ट नहीं किया कि वह किस संस्करण का उपयोग कर रहे हैं। इसलिए मुझे विचार करना चाहिए कि वह नवीनतम संस्करण का उपयोग कर रहा है। यदि वह एक अलग संस्करण का उपयोग कर रहा है, तो मुझे यकीन है कि वह यह उल्लेख करेगा कि क्योंकि वह इस तथ्य से अवगत होगा कि जीना अपूरणीय है और वह समझाएगा कि वह क्यों उपयोग कर रहा है। किसी ने कभी भी मुझे "अंतिम" समय नहीं बताया, इसलिए मुझे लगता है कि आपको अपने आप को एक ब्रेक लेना चाहिए और शांत होना चाहिए। इतना कठोर होने की आवश्यकता नहीं है ...
मैसेज-डिजाइन

उस बारे में कोई सूचना नहीं मिली। लेकिन क्या यह विचार करना सामान्य नहीं है कि यदि कोई यह सोचने के लिए अपने संस्करण को निर्दिष्ट नहीं करता है कि वे नवीनतम का उपयोग कर रहे हैं? मेरा मतलब है कि मुझे एक कारण के लिए 1.3 का उपयोग करना होगा और मुझे इस तथ्य के बारे में पता है कि एक नया और बेहतर संस्करण है।
मास-डिजाइन

जवाबों:


144

पॉपअप ब्लॉकर्स आम तौर पर केवल तभी अनुमति देगा window.openजब किसी उपयोगकर्ता ईवेंट के प्रसंस्करण के दौरान उपयोग किया जाता है (जैसे एक क्लिक)। आपके मामले में, आप window.open बाद में कॉल कर रहे हैं , घटना के दौरान नहीं, क्योंकि $.getJSONअतुल्यकालिक है।

आपके पास दो विकल्प हैं:

  1. इसके बजाय कुछ और करें window.open

  2. अजाक्स कॉल को सिंक्रोनाइज़ करें, जो कि ऐसी चीज है जिसे आपको सामान्य रूप से प्लेग से बचना चाहिए क्योंकि यह ब्राउज़र के 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);
            }
        }
    });

    यदि आप अपने लक्ष्य को प्राप्त करने का कोई अन्य तरीका खोज सकते हैं तो फिर से, मैं सिंक्रोनस अजाक्स कॉल की वकालत नहीं करता। लेकिन अगर तुम नहीं जा सकते, तो तुम जाओ।

    यहाँ कोड का एक उदाहरण है जो अतुल्यकालिक कॉल के कारण परीक्षण में विफल रहता है:

    लाइव उदाहरण | लाइव स्रोत (जेएसबीएन में परिवर्तन के कारण लाइव लिंक अब काम नहीं करते हैं)

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

    और यहाँ एक उदाहरण है कि काम करता है, एक तुल्यकालिक कॉल का उपयोग कर:

    लाइव उदाहरण | लाइव स्रोत (जेएसबीएन में परिवर्तन के कारण लाइव लिंक अब काम नहीं करते हैं)

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

3
बहुत - बहुत धन्यवाद। कॉल को तुल्यकालिक बनाने के आपके सुझाव ने एक आकर्षण की तरह काम किया। उसी ने संवाद के ओके इवेंट पर नेविगेशन को संभालने के मेरे संभावित अगले अंक में मेरी मदद की।
मारवा

जैसा कि TJ Crowder ने 2 प्रश्नों को खुला छोड़ दिया है, [1। window.open] और [2] का विकल्प खोजें। अजाक्स सिंक्रोनस कॉल से बचें] उन लोगों के सुझावों का समुदाय के लाभ के लिए स्वागत है। एल्से मैंने उनके जवाब को उक्त प्रश्न के लिए एक सही समाधान पाया :)
पिघला

4
मेरे लिए, मैंने उपयोगकर्ता को क्लिक करने के लिए संकेत देने के लिए लक्ष्य = "_ blank" के साथ एक लिंक जोड़ा।
हिरोशी

1
@ इवान: आपको सीधे एक्सएचआर का उपयोग करना होगा। सिंक्रोनस अनुरोधों को चित्रित करने के लिए टिकट में एक उदाहरण है ।
टीजे क्राउडर

2
@ मैं आपको लगता है कि आप दोनों मुद्दों से बच सकते हैं यदि आप विंडो को खोलने के लिए नियंत्रण प्रवाह को बदल सकते हैं, (सिंक), तो AJAX अनुरोध (async) करें और फिर प्रतिक्रिया का उपयोग करके त्रुटि संदेश दिखाएं या रीडायरेक्ट करें।
Stijn de Witt

61

आप window.open को बिना ब्राउजर ब्लॉक किए तभी कॉल कर सकते हैं जब यूजर सीधे कुछ एक्शन करता है। ब्राउज़र कुछ ध्वज भेजता है और निर्धारित करता है कि उपयोगकर्ता कार्रवाई द्वारा खोली गई खिड़की।

तो, आप इस परिदृश्य की कोशिश कर सकते हैं:

  1. var myWindow = window.open ('')
  2. इस विंडो में कोई भी लोडिंग मैसेज ड्रा करें
  3. जब अनुरोध किया जाता है, तो myWindow.location = ' http://google.com ' पर कॉल करें

2
यह सफारी मोबाइल (IPhone 4 पर परीक्षण) पर काम नहीं करता है। मैंने कई अन्य विचारों (जैसे myWindow.postMessage) की कोशिश की, लेकिन पृष्ठभूमि में जावास्क्रिप्ट को निष्पादित नहीं करने के सफ़ारीस प्रतिबंध के कारण, मूल विंडो कभी भी उस स्थान परिवर्तन को नहीं भेज सकती है।
राउंड्रोबिन

@BausTheBig मैंने IPhone 6, IOS8 पर परीक्षण किया। इसने एक जादू की तरह काम किया।
लवरायुत

पॉपअप को अवरुद्ध किए बिना Google Analytics के साथ बाहरी लिंक ट्रैक करने का एक तरीका खोज रहा था। यह वही था जो मुझे चाहिए था। IOS7 (वास्तविक फोन) और iOS 8 (iOS सिम्युलेटर) में iPhone 4s पर ठीक काम करने लगता है।
नोटाक्यूच

37

मुझे यह समस्या थी और मैंने अपना url तैयार नहीं किया जब तक कॉलबैक कुछ डेटा वापस नहीं करता। कॉलबैक शुरू करने से पहले रिक्त विंडो को खोलना था और कॉलबैक वापस आने पर बस स्थान सेट करना था।

$scope.testCode = function () {
    var newWin = $window.open('', '_blank');
    service.testCode().then(function (data) {
        $scope.testing = true;
        newWin.location = '/Tests/' + data.url.replace(/["]/g, "");
    });
};

1
मैंने एक नई विंडो खोलने के लिए इस समाधान का उपयोग किया और पॉपअपब्लॉकर को दरकिनार किया
VeldMuijz

अगर मुझे पॉपअप खोलने की आवश्यकता होगी तो क्या होगा अगर मुझे हाथ से पहले नहीं पता है? जैसे: action().then(doWindowOpenThing).catch(doSomethingElseThatDoesntOpenAPopup) तो मैं हाथ से पहले एक खिड़की नहीं खोल सकता (इसके संदर्भ, आदि को रखने के लिए) अगर बाद में मैं इसका उपयोग नहीं करूंगा, तो ठीक है?
लुइज़

नहीं, यह हर बार एक नया टैब खोलता है और मुझे लगता है कि आप उस मामले में नहीं चाहेंगे जहां आप इसका उपयोग नहीं करते हैं। बात यह है कि ब्राउज़र केवल आपको क्लिक फ़ंक्शन (उपयोगकर्ता द्वारा शुरू की गई कार्रवाई) में एक नया टैब खोलने की अनुमति देगा अन्यथा पॉपअप अवरोधक इसे उपयोगकर्ता की अनुमति के बिना स्क्रिप्ट खोलने वाले नए टैब के रूप में देखेगा और इसे ब्लॉक कर देगा।
नटूरो

कृपया, परीक्षण करें अगर newWull शून्य है!
फ्रांसेस्कोएम

क्यों ? मुझे इसका कोई कारण नजर नहीं आता।
नॉटूरो

18

यह कोशिश करो, यह मेरे लिए काम करता है,

$('#myButton').click(function () {
    var redirectWindow = window.open('http://google.com', '_blank');
    $.ajax({
        type: 'POST',
        url: '/echo/json/',
        success: function (data) {
            redirectWindow.location;
        }
    });
});

इस के लिए fiddle है http://jsfiddle.net/safeeronline/70kdacL4/1/


1
धन्यवाद, मेरे लिए भी काम किया है - अगर यह उस बेला के लिए नहीं था, तो मैं शायद इस पर विश्वास नहीं करता था, योग्य!
rmcsharry

3
यह स्वीकृत उत्तर होना चाहिए! यदि आप url बनाने के लिए async डेटा की आवश्यकता है, तो आप redirectWindow.location.assign ('new_url') का भी उपयोग कर सकते हैं।
Matheusr

अच्छा समाधान। इसे
बनाए रखें

कृपया, परीक्षण करें कि क्या रीडायरेक्ट किया गया है? विभिन्न ब्राउज़र विकल्पों के अनुसार आप अवरुद्ध हो सकते हैं या नहीं।
फ्रांसेस्कोएम

8

विंडोज को उपयोगकर्ता द्वारा शुरू किए गए ईवेंट के रूप में एक ही स्टैक (उर्फ माइक्रोटस्क ) पर बनाया जाना चाहिए , उदाहरण के लिए एक क्लिकबैकबैक - इसलिए उन्हें बाद में, अतुल्यकालिक रूप से नहीं बनाया जा सकता है।

हालाँकि, आप एक URL के बिना एक विंडो बना सकते हैं और आप उस विंडो के URL को एक बार बदलने के बाद बदल सकते हैं , वह भी अतुल्यकालिक रूप से!

window.onclick = () => {
  // You MUST create the window on the same event
  // tick/stack as the user-initiated event (e.g. click callback)
  const googleWindow = window.open();

  // Do your async work
  fakeAjax(response => {
    // Change the URL of the window you created once you
    // know what the full URL is!
    googleWindow.location.replace(`https://google.com?q=${response}`);
  });
};

function fakeAjax(callback) {
  setTimeout(() => {
    callback('example');
  }, 1000);
}

आधुनिक ब्राउज़र एक रिक्त पृष्ठ (जिसे अक्सर कहा जाता है about:blank) के साथ विंडो खोलेगा , और URL प्राप्त करने के लिए आपके async कार्य को संभालने के लिए काफी त्वरित है, जिसके परिणामस्वरूप UX ज्यादातर ठीक है। यदि आप इसके बजाय उपयोगकर्ता प्रतीक्षा करते समय विंडो में एक लोडिंग संदेश (या कुछ भी) प्रस्तुत करना चाहते हैं, तो आप डेटा यूआरआई का उपयोग कर सकते हैं ।

window.open('data:text/html,<h1>Loading...<%2Fh1>');

3

यह कोड मेरी मदद करता है। आशा है कि यह कुछ लोगों की मदद करेगा

$('formSelector').submit( function( event ) {

    event.preventDefault();

    var newWindow = window.open('', '_blank', 'width=750,height=500');

    $.ajax({

        url: ajaxurl,
        type: "POST",
        data: { data },

    }).done( function( response ) {

        if ( ! response ) newWindow.close();
        else newWindow.location = '/url';

    });
});

3

लिंक तत्व का उपयोग करने का प्रयास करें और इसे javascriipt के साथ क्लिक करें

<a id="SimulateOpenLink" href="#" target="_blank" rel="noopener noreferrer"></a>

और स्क्रिप्ट

function openURL(url) {
    document.getElementById("SimulateOpenLink").href = url
    document.getElementById("SimulateOpenLink").click()
}

इसे इस तरह इस्तेमाल करें

//do stuff
var id = 123123141;
openURL("/api/user/" + id + "/print") //this open webpage bypassing pop-up blocker
openURL("https://www.google.com") //Another link

यह मेरे लिए खाली खिड़की से निपटने से बच गया।
ponder275

यह पता चला है कि यह मेरी समस्या को हल नहीं करता है iPhone ने मेरी खिड़की को पॉप-अप के रूप में अवरुद्ध किया है।
ponder275

2

उपयोगकर्ता द्वारा ईवेंट को आरंभ करने के लिए किए गए अवलोकन ने मुझे इसके पहले भाग का पता लगाने में मदद की, लेकिन उसके बाद भी क्रोम और फ़ायरफ़ॉक्स ने नई विंडो को अवरुद्ध कर दिया। दूसरा भाग लिंक में लक्ष्य = "_ रिक्त" जोड़ रहा था, जिसका उल्लेख एक टिप्पणी में किया गया था।

सारांश में: आपको उपयोगकर्ता द्वारा शुरू की गई घटना से window.open को कॉल करना होगा, इस मामले में एक लिंक पर क्लिक करना होगा, और उस लिंक के लिए लक्ष्य = "_ blank" होना चाहिए।

नीचे दिए गए उदाहरण में लिंक वर्ग = "बटन-ट्विटर" का उपयोग कर रहा है।

$('.button-twitter').click(function(e) {
  e.preventDefault();
  var href = $(this).attr('href');
  var tweet_popup = window.open(href, 'tweet_popup', 'width=500,height=300');
});


1

मैं अपने रिएक्ट कोड में पॉपअप ब्लॉकर से बचने के लिए इस विधि का उपयोग कर रहा हूं। यह अन्य सभी जावास्क्रिप्ट कोड में भी काम करेगा।

जब आप क्लिक ईवेंट पर एक एसिंक्स कॉल कर रहे हैं, तो पहले एक खाली विंडो खोलें और फिर बाद में उस URL को लिखें, जब एक एसिंक्स कॉल पूरा हो जाएगा।

const popupWindow = window.open("", "_blank");
popupWindow.document.write("<div>Loading, Plesae wait...</div>")

async कॉल की सफलता पर, निम्नलिखित लिखें

popupWindow.document.write(resonse.url)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.