jQuery dialog over content from another site

2019-06-19 02:32发布

问题:

I'm using jQuery's lovely and simple dialog command to open a dialog box in front of some embedded 3rd party content. This embedded content could be a page from any website. I CAN get this to work on some sites (Yahoo, Google) but I CANNOT get it to work on other sites (MSN, Johnlewis, FT).

I've stripped out as much as possible from the code below to give the bare bones of the problem - the code as it is shown works fine and the dialog box does display. But, comment out the YAHOO line and uncomment the MSN line, then the dialog won't display!!

<head>
    <script src="http://code.jquery.com/jquery-latest.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js"></script>
    <style>
        .ui-widget-header { border: 1px solid #aaaaaa; background: #1f84f5 url(images/ui-bg_highlight-hard_75_1f84f5_1x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; font-size: 20pt; }
        .ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222;  font-size: 20pt;}
    </style>
        <script>
            $(document).ready(function() {
                $( "#thedialog" ).dialog( "destroy" );
                $( "#thedialog" ).dialog({height:400, width:600, modal: true,
                    buttons: {Cancel: function() {$( this ).dialog( "close" );}}
                });
            });
    </script>
</head>
<body>
    <?php 
        // WORKING - these pages DO launch a dialog:
        $targetlink = 'http://www.yahoo.com';
        // $targetlink = 'http://www.bbc.co.uk';
        // $targetlink = 'http://www.google.com';

        // NOT WORKING - these pages do NOT launch a dialog:
        // $targetlink = 'http://www.msn.com';
        // $targetlink = 'http://www.johnlewis.com';
        // $targetlink = 'http://www.ft.com';

        echo file_get_contents($targetlink);
    ?>
    <div id="thedialog" title="Simple dialog box" style="display:none">My girl lollipop</div>
</body>

The only thing I can think is it must be something on one of the non-working websites that's conflicting with my code - I've tried everything to error-trap the issue but can't find what's causing it.

Can anyone help me please?

NOTES: - (1) I know the example as shown doesn't need PHP, but the fuller version does (I just stripped most of the PHP code away to keep this example small). - (2) I'm using JQuery elsewhere in the page on the fuller version so ideally I'd like to stay with JQuery, rather than introducing an alternative framework/method.

回答1:

[edit] Apparently it is working for some people.. I myself cannot get it to work without the changes below though.. [/edit]

The Firebug console is useful for debugging stuff like this. In this case, I got a $('#thedialog') is not a function error message.

I got it working using jQuery noConflict:

<script>
    var $j = jQuery.noConflict();
        $j(document).ready(function() {
            $j( "#thedialog" ).dialog( "destroy" );
            $j( "#thedialog" ).dialog({height:400, width:600, modal: true,
                buttons: {Cancel: function() {$( this ).dialog( "close" );}}
            });
    });
    </script>

My guess is that something on those pages is conflicting/overriding $, but this seems to work fine (tested msn.com).

Have a look at this page for more information.



回答2:

even though I was unable to reproduce the problem on my end, Terry Seidler's answer is valid. You will experience collisions with sites that already have dialogs and JQuery.

You have 2 methods to attack this problem (I don't think the 'no conflict' method will do as you are also using UI plugins )

  1. check if $ is defined and $.dialog is defined. If it is defined, use what the site has, otherwise use dynamic loading

  2. use raw JS to add handler to onload for page/window, and run a function. In this function you should paste JQuery's and JQuery-UI's code. This method uses the function's scope to avoid namespace issues.

Just to make method 2 more clear, image the following JS code

function printMe() { alert("this will print me"); }

function printMeToo(){

     function printMe(){ alert("this will print me too"); }
     printMe(); 

}

printMeToo();

This code should alert "this will print me too" - and running printMe anywhere else on page will alert "this will print me". This way you will not harm the pages you are loading (which is also something you should consider) and they will not have an effect on you.

How will it look like? In order to see how to add raw JS onload handler, you can have a look at this stackoverflow question. lets say it is something like document.addEventListener( 'onload', function () { ... /* important stuff */ });

The important thing is how will this function look like? So this is the expected structure

function(){ /* important stuff function */ 

       // paste here JQuery definition code (copy paste into here... ) make sure to use the minified code!
       (function(a,b){function G(a) ... {return p})})(window);

      // paste other plugins code as well. dialog + ... 

      .... 


      // now your code should be here, exactly like you posted it untouched

      $("myelement"); // this uses MY JQuery version, and my JQuery-UI version and my plugins without the possibility of an override. The site cannot override my code, and I cannot override the site's code. 

} /* end of really important stuff function here */ 

Wanna see this method live and running? I protect my site with Incapsula - and so they show their seal on my site (kind of like your dialog) - see the floating div on bottom right? They use JQuery and other stuff there too just like I specify here.

BTW - regarding CSS - you might get same problems there. For example you refer to class .bottom - other sites might have that exact class and CSS of their own. make sure you wrap the entire dialog code with a very unique ID (something like gjkelrgjkewrl849603856903ID - and start all your CSS selectors with it to avoid collisions).



回答3:

You need to remove the style="display:none" code if you want that the dialog will be opened automatically.

Try this code:

<head>
    <script src="http://code.jquery.com/jquery-latest.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js"></script>
    <style>
        .ui-widget-header { border: 1px solid #aaaaaa; background: #1f84f5 url(images/ui-bg_highlight-hard_75_1f84f5_1x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; font-size: 20pt; }
        .ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222;  font-size: 20pt;}
    </style>
    <script>
        $(document).ready(function() {
            $( "#thedialog" ).dialog( "destroy" );
            $( "#thedialog" ).dialog({height:400, width:600, modal: true,
                buttons: {Cancel: function() {$( this ).dialog( "close" );}}
            });
    });
    </script>
</head>
<body>
    <?php 
        $targetlink = 'http://www.yahoo.com';   
        echo file_get_contents($targetlink);
    ?>
    <div id="thedialog" title="Simple dialog box">My girl lollipop</div>
</body>


回答4:

I've tried your code, and it worked for me. Maybe you have a php error message in the generated source and it conflict with you JS code.

Check the generated source in browser.