I'm trying to get lightbox2 working with my site,
http://www.therussianfrostfarmers.com/
, however i seem to be having a problem with conflicting external js files. I'm not entirely sure i know where the problem is with this code, but i believe its got todo with how the onload events are called. the blog content on the homepage is loaded into iframe, the iframe is dynamically resized to fit the content using the onload event, but when i import the files required for lightbox2 (as per normal)....
<script type="text/javascript" src="js/prototype.js"></script>
<script type="text/javascript" src="js/scriptaculous.js?load=effects,builder"></script>
<script type="text/javascript" src="js/lightbox.js"></script>
....it cancels my updateSize() being called on the iframe. lightbox2 does still work.
I've narrowed the problematic js file to the prototype.js.
I've tried handling the sequence of events with the function dhtmlLoadScript().
Using the following code, the page loads properly, the iframe resizes properly, but then the page turns white and firefox loading icon just keeps spinning.
<script type='text/javascript'>
// function to resize iframe
function updateSize()
{
// get width
frame_x = $('#content').width() -5;
// apply width
$('#iframed').css('width', frame_x);
//get height
var the_height = document.getElementById('iframed').contentWindow.document.body.scrollHeight +120;
//apply height
document.getElementById('iframed').height = the_height;
}
// function to load external js files
function dhtmlLoadScript(url)
{
var e = document.createElement("script");
e.src = url;
e.type="text/javascript";
document.getElementsByTagName("head")[0].appendChild(e);
}
// function to handle each event on onload callback
function callbackHandler()
{
updateSize();
dhtmlLoadScript("http://www.therussianfrostfarmers.com/ndxz-studio/site/js/prototype.js");
dhtmlLoadScript("http://www.therussianfrostfarmers.com/ndxz-studio/site/js/scriptaculous.js?load=effects,builder");
dhtmlLoadScript("http://www.therussianfrostfarmers.com/ndxz-studio/site/js/lightbox.js");
}
</script>
<iframe src='$url' frameborder='0' id='iframed' onload="callbackHandler()"></iframe>
Sorry if anything is unclear.
Thanks
Cam
something quick to check, see if the function name updateSize() is not getting remapped in prototype
Related
I have been battling with this issue for a few days now and finally found a partial solution but I think it could be improved.
In my project, I have a series of iframes that contain videos. When a link is clicked are displayed with a slide transition and when the link is clicked again the video stops and the span containing the iframe is hidden also with a transition.
This is achieved by adding and removing a css class of "open" that has a height and a transition in it. In addition to this I have an event listener that collapses the containing span also when the video finishes. All this works fine and to save time I am not posting the code.
The issue I was having was with slow page loading times, so I removed the src attribute for the iframes from the html and moved it to my js file and assigned it only after the click is performed. This wasn't working and I realised I needed the iframe to fully load before running the rest of the code inside the "click" method. So I delayed this part of the code by 100ms.
All this works, but I feel it would be better to have the rest of the code run not after a 100ms lapse but when the iframe is loaded (in case page viewed by slower computers). Not sure how to do this.
Here is the code as it stands now:
var player;
var frame = $("#frame");
frame.bind("load", function () {
player = $(this).contents().find("#myVid");
player.on('ended', function () {
frame.removeClass("open");
});
});
$("#clickableLink").click(function(){
if (frame.hasClass("open")) {
frame.removeClass("open");
frame.contents().find('#myVid').get(0).pause();
} else {
function delayed(){
frame.addClass("open");
frame.contents().find('#myVid').get(0).play();
}
frame.attr("src","iframe.html");
setTimeout(delayed, 100);
}
});
Fairly new to development so I am looking for the simplest way to do this. Any help appreciated.
Here is a super simple example of calling code when the iframe has loaded. Check out the onload attribute of the iframe tag:
<head>
<script>
function frameLoaded() {
alert('frame loaded!');
};
</script>
</head>
<body>
<iframe id="frame" src="https://en.wikipedia.org/wiki/HTML_element#Frames" onload="frameLoaded(this)" />
</body>
I have the script audiojs for changing the style of audios tag in html when I go to my page it work without problems, but when I click a button to reload div (this div contain audios tags) with function load jQuery the style of audiojs removed, I tried to get script after load the div with jQuery getScript, but the script load many times that caused to stop of my browser.
this is the function to call the audiojs
audiojs.events.ready(function() {
audiojs.createAll();
});
I want a solution to call this function one time no more, thanks
Try to adding a new script tag to with the script to re-load in your code something like below:
<script language="text/javascript">
function audiojs()
{
var div= document.getElementsByTagName('head')[0];
var script= document.createElement('script');
script.type= 'text/javascript';
script.src= 'audiojs.js';
div.appendChild(script);
}
audiojs();
</script>
I hope you will get some ideas now. Also check your caching.
It's hard to know without any link to the audio.js library, but most API's or libraries will give some indication that they are loaded. I would use an if statement to create something like:
(function () {
function checkForLoaded(){
if (audiojs.state !== null) { //or something similar
audiojs.createAll();
}
}
})();
Thanks everyone,
i found the solution,
after loading the div with ajax i added this code to remove the class audiojs
$("audio").removeClass("audiojs");
I'm trying to run my site's script.js main javascript file inside my tinyMCE instance. The idea is to have functionality, such as my sites slideshow, also running inside tinyMCE for optimal realistic editing.
I'm not even sure this is possible how I intend it.
Here's the function I use to initialize:
function set_html_tinymce() {
tinymce.init({
selector:'#edit_html_textarea',
... ...
});
// LOAD jQUERY AND SCRIPT.JS INSIDE TINYMCE
var scriptLoader = new tinymce.dom.ScriptLoader();
scriptLoader.add('http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js');
scriptLoader.add('../js/script.js');
scriptLoader.loadQueue(function() {
alert('All scripts are now loaded.');
});
}
Here's the contents of my test script.js:
$( document ).ready(function() {
alert('a');
$('.slideshow').on('click', function() {
alert('b');
});
$('.slideshow').click(function() {
alert('c');
});
});
I get the first alert a and All scripts are now loaded., so the script.js is indeed loaded. However when I click on a .slideshow class div inside tinyMCE I get neither b nor c alert.
How can I load and run a jQuery/JS file inside tinyMCE, and have it execute in the same manner it would on the site itself?
I would love an officially supported solution but if this isn't possible I will settle for a 'hack'.
the problem is that TinyMCE uses designMode, so in order to add a js file to the iframe, you must first turn off designMode.
This solution worked for me:
var editor = $(tinymce.activeEditor.getBody())[0];
var iframe = $R('txtTinyMCE_ifr');
editor.designMode = 'off';
var script = iframe.contentDocument.createElement('script');
script.setAttribute('src', '../../scripts/tinymce/iframe.js');
editor.appendChild(script);
editor.designMode = 'on';
You should add this code to the init_instance_callback function for TinyMCE.
On a page i try to fill an empty <iframe id="myFrame"></iframe> with the HTML code of an ajax result. That works well, except script tags in the code are not being executet, so i have to readd them to the iframe's page:
$.post('page.php', function(code) {
$("#myFrame").contents().find("html").get(0).innerHTML = code;
$("#myFrame").contents().find("script").each(function() {
$old_script = $(this);
$frame = document.getElementById("myFrame");
$new_script = $frame.contentWindow.document.createElement("script");
$new_script.type = "text/javascript";
$new_script.src = $old_script.attr("src");
$old_script.remove();
$frame.contentWindow.document.head.appendChild($new_script);
});
});
That works basically, but the document seems to load the Javascript files in a different order. There are 3 js files to load: jquery.min.js, a jquery plugin and a main.js file to control the bahavior inside the iframe:
// main.js:
$(document).ready(function() {
alert("frame document loaded");
// call the jquery plugins etc...
});
The page alerts me "frame document loaded", but cannot execute the jquery plugins. Double-checked the script paths, but they're right. Seems that the jquery.min.js and main.js are loaded before the plugin files.
How could i achieve to load the javascript files one by one as specified originally in the code returned by the ajax request?
EDIT: Forgot to say that sometimes everything works well and the javascript seems to be loaded correctly. On reload it breaks again.
What tricks can be used to stop javascript callouts to various online services from slowing down page loading?
The obvious solution is to do all the javascript calls at the bottom of the page, but some calls need to happen at the top and in the middle. Another idea that comes to mind is using iframes.
Have you ever had to untangle a site full of externally loading javascript that is so slow that it does not release apache and causes outages on high load? Any tips and tricks?
window onload is a good concept, but the better option is to use jQuery and put your code in a 'document ready' block. This has the same effect, but you don't have to worry about the onload function already having a subscriber.
http://docs.jquery.com/Core/jQuery#callback
$(function(){
// Document is ready
});
OR:
jQuery(function($) {
// Your code using failsafe $ alias here...
});
edit:
Use this pattern to call all your external services. Refactor your external script files to put their ajax calls to external services inside one of these document ready blocks instead of executing inline. Then the only load time will be the time it takes to actually download the script files.
edit2:
You can load scripts after the page has loaded or at any other dom event on the page using built in capability for jQuery.
http://docs.jquery.com/Ajax/jQuery.getScript
jQuery(function($) {
$.getScript("http://www.yourdomain.com/scripts/somescript1.js");
$.getScript("http://www.yourdomain.com/scripts/somescript2.js");
});
Not easy solution. In some cases it is possible to merge the external files into a single unit and compress it in order to minimize HTTP requests and data transfer. But with this approach you need to serve the new javascript file from your host, and that's not always possible.
I can't see iframes solving the problem... Could you please elaborate ?
See articles Serving JavaScript Fast and Faster AJAX Web Services through multiple subdomain calls for a few suggestions.
If you're using a third-party JavaScript framework/toolkit/library, it probably provides a function/method that allows you to execute code once the DOM has fully loaded. The Dojo Toolkit, for example, provides dojo.addOnLoad. Similarly, jQuery provides Events/ready (or its shorthand form, accessible by passing a function directly to the jQuery object).
If you're sticking with plain JavaScript, then the trick is to use the window.onload event handler. While this will ultimately accomplish the same thing, window.onload executes after the page--and everything on it, including images--is completely loaded, whereas the aforementioned libraries detect the first moment the DOM is ready, before images are loaded.
If you need access to the DOM from a script in the head, this would be the preferred alternative to adding scripts to the end of the document, as well.
For example (using window.onload):
<html>
<head>
<title>Test Page</title>
<script type="text/javascript">
window.onload = function () {
alert(document.getElementsByTagName("body")[0].className);
};
</script>
<style type="text/css">
.testClass { color: green; background-color: red; }
</style>
</head>
<body class="testClass">
<p>Test Content</p>
</body>
</html>
This would enable you to schedule a certain action to take place once the page has finished loading. To see this effect in action, compare the above script with the following, which blocks the page from loading until you dismiss the modal alert box:
<html>
<head>
<title>Test Page</title>
<script type="text/javascript">
alert("Are you seeing a blank page underneath this alert?");
</script>
<style type="text/css">
.testClass { color: green; background-color: red; }
</style>
</head>
<body class="testClass">
<p>Test Content</p>
</body>
</html>
If you've already defined window.onload, or if you're worried you might redefine it and break third party scripts, use this method to append to--rather than redefine--window.onload. (This is a slightly modified version of Simon Willison's addLoadEvent function.)
if (!window.addOnLoad)
{
window.addOnLoad = function (f) {
var o = window.onload;
window.onload = function () {
if (typeof o == "function") o();
f();
}
};
}
The script from the first example, modified to make use of this method:
window.addOnLoad(function () {
alert(document.getElementsByTagName("body")[0].className);
});
Modified to make use of Dojo:
dojo.addOnLoad(function () {
alert(document.getElementsByTagName("body")[0].className);
});
Modified to make use of jQuery:
$(function () {
alert(document.getElementsByTagName("body")[0].className);
});
So, now that you can execute code on page load, you're probably going to want to dynamically load external scripts. Just like the above section, most major frameworks/toolkits/libraries provide a method of doing this.
Or, you can roll your own:
if (!window.addScript)
{
window.addScript = function (src, callback) {
var head = document.getElementsByTagName("head")[0];
var script = document.createElement("script");
script.src = src;
script.type = "text/javascript";
head.appendChild(script);
if (typeof callback == "function") callback();
};
}
window.addOnLoad(function () {
window.addScript("example.js");
});
With Dojo (dojo.io.script.attach):
dojo.addOnLoad(function () {
dojo.require("dojo.io.script");
dojo.io.script.attach("exampleJsId", "example.js");
});
With jQuery (jQuery.getScript):
$(function () {
$.getScript("example.js");
});
If you don't need a particular script ad load time, you can load it later by adding another script element to your page at run time.