lima
lima

Reputation: 113

Javascript loading incorrectly in firefox

First, my apologies to anyone who reads this. I've run into a fair number of JS issues, and this is the most intractable I've ever seen. I'll do my best to give a clear description, but I may have to revise it.

I have the following page loading within an inline frame in SugarCRM:

<head>
<link rel="stylesheet" href="style/style.css" />
</head>
<body>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script type="text/javascript" src="js/index_controller.js"></script>
<table class="form_text" style="width: 100%; height: 100%;" cellpadding="5">
    <tr>
        <td><iframe id="map_frame" 
                style="width: 100%; height: 100%; overflow-y: hidden; border: solid 1px #DDDDDD"
                scrolling="no"
                src="map.php?<?php
                    foreach ( $_REQUEST as $key => $value ) {
                        echo $key . "=" . $value . "&";
                    }?>"></iframe>
        </td>
        ...
        </td>
    </tr>
</table>
</div>
<script type="text/javascript">
    parent.$("iframe").each(function(iel, el) {
          if(el.contentWindow === window) {
              var to_remove = $(el).parent().prev();
              $(to_remove).remove();
              $(el).css("border", "none");
          }
    });
    $(document).ready(function(){
        updateMap();
    });
</script>
</body>

And in the iframe in that page, I have this:

<head>
<link rel="stylesheet" href="style/style.css" />
<!--[if lte IE 8]>
 <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.4/leaflet.ie.css" />
 <!--[endif]-->
<link rel="stylesheet"
href="http://cdn.leafletjs.com/leaflet-0.4/leaflet.css" />
<script src="js/jquery-1.9.1.js"></script>
</head>
<body>
<script type="text/javascript" src="../include/DashletContainer/Containers/DCMenu.js">    </script>
<script type="text/javascript" src="js/arrayList.js"></script>
<script type="text/javascript" src="js/custom_map_controls.js"></script>
<div id="map" style="height: 100%"></div>
<form action="../index.php" method="post" name="DetailView"
id="formDetailView">
<input type="hidden" name="module" value=""> <input type="hidden"
    name="record" value=""> <input type="hidden" name="return_action"> <input
    type="hidden" name="return_module"> <input type="hidden"
    name="return_id"> <input type="hidden" name="module_tab"> <input
    type="hidden" name="isDuplicate" value="false"> <input type="hidden"
    name="offset" value="1"> <input type="hidden" name="action"
    value="EditView"> <input type="hidden" name="sugar_body_only"> <input
    type="hidden" name="prospect_id" value="">
</form>
<script type="text/javascript" src="js/map_icons.js"></script>
<script type="text/javascript" src="js/map_controller.js"></script>
<script src="js/leaflet-0.4.5.js"></script>
</body>

the leaflet-0.4.5.js script, when evaluated, creates a globally available object known as L, which gives access to all the Leaflet mapping framework's functions. In my map_controller.js, I add some special features to L.Map, the function for creating the actual map objects. This works fine in Chrome, and it works fine in Firefox when I load the page directly in a browser tab. But when I load it as intended, in a SugarCRM page inside an inline frame, I get the error "L.insert function name here is not defined" in the JS console. If I refresh just the iframe without reloading the entire SugarCRM page, the map then appears as expected. I'm working around this now by catching the exception and forcing the page to reload when it occurs, but I'd really like to know why this is happening in the first place. I've rewritten the map controller so all the functions that use L are contained inside a $(document).ready() function (using jQuery for that) and tried putting the leaflet script tag at the top of the body on the page where it's supposed to load, and still no luck.

Upvotes: 1

Views: 432

Answers (2)

Boris Zbarsky
Boris Zbarsky

Reputation: 35074

Your problem is using $(document).ready on the parent page.

That will run as soon as the HTML parser is done parsing the parent. But it's then reaching inside the iframe and depending on various scripts inside the iframe having been loaded, which they may well not be at that point yet. It's a race between the HTTP response for the toplevel page and the HTTP responses for the scripts in the subframe, basically.

The right way to do this is to run the initialization from onload or at least from a point where DOMContentLoaded (which is what $(document).ready hooks into) has fired on the child.

Upvotes: 1

flup
flup

Reputation: 27104

You should use some kind of dependency management like LABjs or RequireJS to make sure your scripts are loaded and executed in the right order.

Upvotes: 0

Related Questions