How to execute code fully before load xul file? - javascript

I have a script that I add to my xul file, like:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Bindings -->
<?xml-stylesheet href="chrome://test/content/bindings.css" type="text/css"?>
<mywindow id="myWindowID" width="800" height="600"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/x-javascript" src="chrome://greenfox/content/jquery-1.4.4.min.js" />
</mywindow>
and on mywindow constructor (at the binding) I use a function of my scrip, called 'print'.
The problem is that sometimes, my script doesn't load really fast before it's used, and I get the message
We are unable to Print or Print
Preview this page.
..which is related to the Printer usage.
Please note that I'm not trying to use the Printer, I'm trying to use my own print method (in the script that doesn't loaded in time) to simply write on the screen.
So, any idea how can I make the xul file wait till my script is completely loaded?

Solved it with a variable "window.scriptsLoaded" and a loop on my class constructor that wait..
-update
also, it didn't work with while(!window.scriptsLoaded), I needed to use:
function loadScripts() {
if (!window.scriptsLoaded)
setTimeout(loadScripts, 1)
else
loaded();
}
so the window.scriptsLoaded could be updated each time I check it. I don't really understand why.
-update
Actually, use "onload" showed itself a the better solution..

Related

Can't invoke function from external javascript file

My java script file is referenced in the body of my base template:
<body>
...
<script type="text/javascript" src="/static/js/test.js"></script>
</body>
I an another template which extends the base template, the java script function draw() defined in test.js can be invoked by using the onclick Event. Sadly I only get a picture when clicking over the canvas area. But invoking the function by <script> draw(); </script> occurs the following error: ReferenceError: draw is not defined How can this possibly be?
...
<div class="panel-body">
# works perfectly fine, somehow the function can be accessed
<canvas id="canvas" onclick="draw()" width="300" height="10"></canvas>
# occurs an error, somehow the function can't be accessed anymore...
<script> draw(); </script>
</div>
...
I use python flask framework for back end programming.
Because you initialized the <script> at the end of the webpage, and you call draw() before it's initialized.
I would put it in the head tag:
<head>
...
<script type="text/javascript" src="/static/js/test.js"></script>
</head>
You said that for the onclick it works, of course it works, when you click on the canvas the draw() function is already initialized.
The order of the script is what matters here. Scripts are loaded in the order encountered in the page.
Since "draw()" is a direct call, I presume this is defined before the tag in the body, so this why the browser says it is not defined. On the other hand, the onClick of the canvas can happen only after the page is loaded, so that's why it is working there.
I recommend to put the javascripts of a specific page below the scripts of the base template somehow (you have to use maybe you'll need two separate references for that), or you can use other techniques like JQuery's $(document).ready().
Here is a very similar question, hope that helps:
load and execute order of scripts
Why won't you wait for the document to load? That would be the proper solution to this problem.
document.addEventListener('load', function (){
draw();
});
Sorry about the ugly indentation, I'm using my phone

Variable is not defined error in my Firefox extension

I'm developing a Firefox add-on. When I run it, I open up the browser console and it says, AMO_Uedit_Beta_Firefox is not defined :browser.xul.
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://Uedit/skin/skin.css" type="text/css"?>
<!DOCTYPE Uedit SYSTEM "chrome://Uedit/locale/translations.dtd">
<overlay id="Uedit-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script src="Uedit.js" />
<toolbarpalette id="BrowserToolbarPalette">
<toolbarbutton id="Uedit" class="toolbarbutton-1" label="Edit HTML" tooltiptext="Edit HTML" oncommand="AMO_Uedit_Beta_Firefox.Uedit()" />
</toolbarpalette>
</overlay>
The toolbar button that calls a function which is part of an object (AMO_Uedit_Beta_Firefox).
I double-checked the names and they both match. Is it because the script doesn't load properly? I'm sure it's not that variable names can't start with capital letters.
var AMO_Uedit_Beta_Firefox={ // This is for "wrapping the loose variables."
Both the file's references are the exact same. Could it be because the script didn't load at all?
<toolbarbutton id="Uedit" class="toolbarbutton-1" label="Edit HTML" tooltiptext="Edit HTML" oncommand="AMO_Uedit_Beta_Firefox.Uedit()" />
I tried changing the relative URL (<script src="Uedit.js" />) to an absolute URL (<script src="chrome://Uedit/Uedit.js" />) in the browser.xul, but now it just returns a blank error message.
Weird blank error message.
These errors cause the rest of the add-on to not work at all, so I can't continue developing it until this is fixed. What're some possible solutions?
EDIT:
I figured out a solution. I have to put a line of JavaScript before the first statement.
var AMO_Uedit_Beta_Firefox = { // Will not work!
...
If I put a console.log in the front, for example.
console.log("");
var AMO_Uedit_Beta_Firefox = { // This will work!
...
The only question is, why does this work?
It looks like the path to the Uedit.js file is wrong. You should use an absolute path in your xul overlay.
As erikvold has said, the link to your Uedit.js script is wrong. This is the minimum that is wrong and is the thing that is complained about in the console: browser.xul:5 is line 5 in browser.xul, which is:
<script src="Uedit.js" />
You state that you have tried:
<script src="chrome://Uedit/Uedit.js" />
That will not work. At a minimum, it should be something like:
<script src="chrome://Uedit/content/Uedit.js" type="application/x-javascript" />
Note the content/ after //Uedit/. However, that being correct assumes you have set up your chrome.manifest with an appropriate content line in addition to the other ones implied by your code (skin and locale). It also assumes that Uedit.js is in that directory. Assuming that the directory structure of your add-on is normal, the content line in your chrome.manifest file would look something like:
content Uedit chrome/content/
As to it actually working, there is no way for us to know if it will work as you have not included the source code that defines all of AMO_Uedit_Beta_Firefox and specifically not AMO_Uedit_Beta_Firefox.Uedit(). For instance, in addition to the above problem, there could easily be a syntax error that prevents the script from loading. Such a syntax error would cause the console to report that AMO_Uedit_Beta_Firefox was undefined when you attempt to execute AMO_Uedit_Beta_Firefox.Uedit() as the code for the toolbarbutton's oncommand.
You can easily test to see if your Uedit.js script is loading by having something print in the console when the script loads (i.e. outside the definition of AMO_Uedit_Beta_Firefox).
I figured out a solution. I have to put a line of JavaScript before the first statement.
var AMO_Uedit_Beta_Firefox = { // Will not work!
...
If I put a console.log in the front, for example.
console.log("foo bar");
var AMO_Uedit_Beta_Firefox = { // This will work!
...
I solved the problem myself, although the solution is strange.

Is there a Javascript "Evoke" function available for <object> - if so, what is it?

I have inherited a large codebase, mostly in C++; this C++ is creating an HTML page that is being displayed in an Internet Explorer web browser.
The HTML does not included any Javascript (.js) files. There is, in addition, an <object> within the HTML; this object seems to be an entirely application-specific, custom object. Here is the skeleton code for the HTML:
<html>
<head>
(Nothing relevant here - no .js files are included)
</head>
<body>
<object
id=objAppIT
GUID_START=1 classid="CLSID:D19BF5B4-74E8-437D-8EB0-FCF709C36C77" GUID_END=1
VER_START=1 codebase="AppIT-Deployer-2,3,1,2.cab#version=2,3,1,2" VER_END=1
>
<param name="CFG"
value="ACTION=LAUNCH
SID=77cded6b-ddaf-441f-ae4a-d2764d519ab6
AID='0000000010000000-00000000000010AC-0005-11-17~05|34|32.149'
UID=N/A"
/>
</object>
<form id=formSubmit method=post action="valid_url_here">
(various <input> fields here)
</form>
<script type="text/javascript">
window.onload = function()
{
var objAppIT = document.getElementById("objAppIT");
objAppIT.Evoke("LAUNCH", "formSubmit");
}
</script>
</body>
</html>
The code above successfully submits the form - apparently, just as though the form was submitted in the usual fashion (not using the <object id=objAppIT>.
I have googled to see if Evoke() is a Javascript function that can be called on any <object> - because no .js file is included that could otherwise define that function. I can't find any documentation for Evoke().
Therefore, I do not understand how the above form is submitted.
Hence, my question: Is there a Javascript function Evoke()? If so, what does it do? If not, I would further appreciate if someone could explain how the above HTML/Javascript snippet is submitting this form.
I also have never heard of an evoke function, but it sounds like dispatchEvent.
It looks like the Evoke function is some user-defined function. We can't tell exactly what it does and what is done with each parameter that is passed into it, but I assume that it takes the second parameter (the ID of the <form> element) and submits that using something like this:
document.getElementById('formSubmit').submit();

How to call external JavaScript function in HTML

I have a small chunk of code I can't seem to get working. I am building a website and using JavaScript for the first time. I have my JavaScript code in an external file 'Marq_Msg.js' which looks like this:
var Messages = new Array();
Messages[0] = "This is message 1";
Messages[1] = "This is message 2";
Messages[2] = "This is message 3";
Messages[3] = "This is message 4";
function scroll_messages()
{
for (var i = 0; i < Messages.length; i++)
document.write(Message[i]);
}
and in my HTML file 'Index.html' I am trying to call it like this:
<div id="logo">
<marquee scrollamount="5" direction="left" loop="true" height="100%" width="100%">
<strong><font color="white"><script src="Marq_Msg.js">scroll_messages()</script></font></strong>
</marquee>
</div>
The 'logo' div is a CSS piece that I'm trying to marquee inside of. If I put the code embedded inside the 'head' tag and call it, it works perfectly! There are a few other things id like to do with this code (like space the messages out a little) but I can't get the code to work in the first place. I've also tried adding:
<script src="Marq_Msg.js"></script>
in the 'head' tag with a separate call, that was a no go. I also tried instead using:
<script type="text/javascript" src="Marq_Msg.js">scroll_messages()</script>
Hell, i even had the function try returning a string (even hardcoded a simple "hello" to be returned) but that didnt work either with and without the 'type':
//Marq_Msg.js
function scroll_messages()
{
return "hello";
}
//index.html
<script type="text/javascript" src="Marq_Msg.js">document.write(scroll_messages())</script>
What am I missing? Any help would be greatly appreciated!! I've looked all over Google, and every site I find wants to do it using some 'form'. I just want messages to be displayed across, no form attached.
If a <script> has a src then the text content of the element will be not be executed as JS (although it will appear in the DOM).
You need to use multiple script elements.
a <script> to load the external script
a <script> to hold your inline code (with the call to the function in the external script)
scroll_messages();
In Layman terms, you need to include external js file in your HTML file & thereafter you could directly call your JS method written in an external js file from HTML page.
Follow the code snippet for insight:-
caller.html
<script type="text/javascript" src="external.js"></script>
<input type="button" onclick="letMeCallYou()" value="run external javascript">
external.js
function letMeCallYou()
{
alert("Bazinga!!! you called letMeCallYou")
}
Result :
If anyone still has the reference error is probably because you are loading your Javascript with defer, or it's in the bottom of the body so when the function gets called your function still doesn't exist.

Dynamic (2 levels) Javascript/CSS Loading IE6

i am trying to dynamically include js (and css) files into a webpage like this:
index.html -> loader_a.js -> a_foo.js, a_bar.js, a_foo.css and so on.
While this works without a problem in FF (using appendChild) i cant get it to run in IE6.
I've tried various available solutions (adding to dom node, ajax call and eval and more from (http://ntt.cc/2008/02/10/4-ways-to-dynamically-load-external-javascriptwith-source.html) here and there and others like post #2013676) but it's not doing what its supposed to do.
When i check with DebugBar i see that my include files (eg a_foo.js) is actually loaded, but its content is empty - on other included files (1 Level/directly) this content is show so i assume there is the problem ...
The "error" i get is alway undefined object which is o/c b/c the function i call is not loaded properly so not much of a help. I dont get any errors on the includes.
I've validated the javascripts so those whould be ok.
Does anyone have the ultimate solution for this?
I can recreate my tests and post some code if it helps.
Thanks,
regards,
Thomas
Sample HTML:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML lang=en><HEAD><TITLE>Test</TITLE>
<script type="text/javascript" src="mmtest_files/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="mmtest_files/multiload.js"></script>
<script type="text/javascript" >
function init2() {
// using the data from the loaded js files
var a= mmf("a");
document.getElementById('status').innerHTML = "Variable set:" + a;
}
// magic...
include(['mmt.js'],init2);
</script>
<BODY >
<H2>Test me!</H2>
<SPAN id=status>status old</SPAN>
</BODY></HTML>
JS 1 is multiload from answer 1
JS2 is a test include:
function mmf(param)
{
return "Called with" + param;
}
You need to use document.write in ie, in order to load scripts in parallel.
See: Loading Scripts Without Blocking
I have such a script btw: Loading Multiple Javascript Files In Order Asynchronously
(it may need some enchancements in Chrome)
UPDATE
There is a callback function, it is optional. It can be used to couple dependent script to the files. EG:
function myjQueryCode() {
// ...
}
include(['jquery.js','jquery-ui.js'], myjQueryCode);
So that your jquery dependent code will run after the files has been loaded.

Categories

Resources