In my HTML-head i have this script included:
<script id="mode" type="text/javascript" src="article.js"></script>
With a button click I'd like to change the source of the script to customers.js so that it then looks like this:
<script id="mode" type="text/javascript" src="customers.js"></script>
The point is that I don't want the article.js to be included in my page then anymore, so I can't just use .append().
So, click on the article button -> only article.js included, click on the customers button -> only customers.js included.
I tried to solve this with jQuery this way, but I doesn' seem to work...:
$("#btArticle").click(function(){
$("#mode").attr("src","article.js");
});
$("#btCustomers").click(function(){
$("#mode").attr("src","customers.js");
});
Do you know where my mistake is?
Update: There are methods with the same name in customers.js and article.js. So there's a onSave() method in both of them and when I clicked the customer button before, I want the onSave() method of customers.js to be executed, not the one in articles.js.
The point is that I don't want the article.js to be included in my page then anymore, so I can't just use .append().
Once the script has been downloaded and evaluated, anything it leaves lying around will remain unless explicitly removed; they're not linked to the script element itself and removing it won't have any effect on them.
The only way to get rid of the stuff article.js leaves lying around is to remove or overwrite each and every thing it creates and keeps.
Concrete example:
// article.js
var foo = "bar";
jQuery(function($) {
$(".stuff").click(function() {
alert("You clicked stuff!");
});
});
If the article.js listed above is processed, you can remove the script element that loaded it, and that will have no effect on the foo global variable or the event handler that it hooked up.
If you want to have scripts that you can unload, have them use the module pattern with a single global symbol they add by assigning to a property on window, e.g.:
// article.js
window.articleScript = (function() {
var foo = "bar";
jQuery(function($) {
$(".stuff").bind("click.article", function() {
alert("You clicked stuff!");
});
});
function remove() {
$(".stuff").unbind("click.article");
try {
delete window.articleScript;
}
catch (e) { // Early IEs throw incorrectly on the above
window.articleScript = undefined;
}
}
return {
remove: remove
};
})();
You can then remove it by doing this:
articleScript.remove();
Re your comment on the question:
Maybe I should've mentioned that there are methods in both files with the same name.
If you have global function declarations in customers.js that use the same name as global function declarations in articles.js, when you load customers.js, it will replace those functions.
So if you have this in articles.js:
function foo() {
alert("Articles!");
}
...and this in customers.js:
function foo() {
alert("Customers!");
}
And you have a button:
<input type="button" onclick="foo();" value="Foo">
When you've loaded just articles.js and not customers.js, clicking that button gives you "Articles!". If you then load customers.js, clicking the button will give you "Customers!".
That works because the event handler calls foo(), but the event handler itself is not foo. The onclick attribute creates a hidden event handler for you. The equivalent jQuery would be:
$("input[type='button'][value='Foo']").click(function() {
foo();
});
Note that just doing .click(foo) will do something very different: It will hook up the function that foo points to at that moment as the event handler. Even if you change what foo points to later (by loading customers.js), that won't change the fact that the old function is hooked up as a handler.
FWIW, from the question and your comments, I think I'd recommend sitting back and reviewing your strategy for this page/app. All of this swapping of code in and out and such seems like a design problem.
You are not actually loading and running the respective scripts, you are just changing the source for that tag. Use .getScript() to load and run the appropriate JavaScript file:
http://api.jquery.com/jQuery.getScript/
Related
I wrote a function named search that I expected to be called when the link was clicked, as the code snippet below shows:
<script>
function search() {
console.log('Searching');
}
</script>
Click here
However, the code does not work as I expected, which causes this error (in Chrome) when the link is clicked:
Uncaught TypeError: search is not a function
I tried logging search to see why the error was thrown:
Click here
<script>
function search() {
console.log('Searching');
}
</script>
Click here
This time, the console logged an empty string each time the link is clicked. What puzzles me is that search is actually defined somewhere else as an empty string, making my function definition useless.
So I want to know what happens when a click event is triggered, and when is search here defined?
It turns out search actually is referring to to the a element's search property which is a property that controls search parameters, which happens to be an empty string in this case. This is because with an HTMLAnchorElement, it is special as it is used to create hyperlinks and navigate to other addresses, and thus the search property is used to control parameters of searches by hyperlinks (similar to that of the Location) object. Setting the search property of an anchor element will then in turn set the global Location instance's window.location.search. This creates a naming conflict and because an empty string is not a function the error is thrown.
Use a different name for the function to remove this conflict. Note that if you don't use an a, you'll see it work just fine:
<script>
function search() {
alert("foo");
}
</script>
<div onclick="search();">Click me!</div>
Li357's answer explains most of what's going on, but to add a point, the reason that
<a onclick="search();">Click me!</div>
results in search referring to the anchor's search property is that inline handlers have an implicit with(this) surrounding them. To the interpreter, the above looks a bit like:
<a onclick="
with(this) {
search();
}
">Click me!</div>
And search is a property of HTMLAnchorElement.prototype, so that property gets found first, before the interpreter gets to looking on window for the property name.
It's quite unintuitive. Best to avoid inline handlers, and to avoid using with as well. You could add the event listener properly using Javascript to solve the problem too:
function search() {
console.log('Searching');
}
document.querySelector('a').addEventListener('click', search);
Click here
Change the name of the function. Just tried your code and it worked once I changed the name of the function.
<body>
<script type="text/javascript">
function test() {
console.log('Searching');
}
</script>
Click here
I've been working through the MDN tutorials, but I haven't been able to get JS event listeners to work yet. I'm up to the last bit of this page: https://developer.mozilla.org/en-US/docs/XUL/Tutorial/Adding_Event_Handlers
In XUL I have a menuitem:
menuitem id="appmenu-libraryHistory" label="History"/>
And in JS I have this:
var HistoryWatch = document.getElementById("appmenu-libraryHistory");
HistoryWatch.addEventListener('command', showLibrary, "History");
function showLibrary(aLeftPane) { ... }
I thought this would pass the string "History" to the function showLibrary when the menu entry "History" was pressed. The showLibrary function does work if I pass parameters directly from the XUL, but if I do that it won't let me pass a URI which is what I'll want to do eventually.
I suspect the JavaScript you have shown is in a file that is included as part of a <script> tag. It may not work because by the time the document.getElementById() line runs, the page hasn't been constructed yet, and there is no element with this id yet.
You need to wait for the page to fully load to be sure that your menu exists. If you are working on a separate window you can call an initialization function from its onload attribute in xul. If you are overlaying just a menu in an existing window, you will need to listen to the load event of the parent window and call your initialization from there :
function init()
{
window.removeEventListener("load", init, false); // Remove the handler as we don't need it anymore.
var historyWatch = document.getElementById("appmenu-libraryHistory");
historyWatch.addEventListener('command', showLibrary, "History");
}
window.addEventListener("load", init, false);
Note that in this example, init (and showLibrary) are polluting the global namespace, it would be better to encapsulate them in an object.
Also note that the order matters because when the last line runs, the init function must have been declared already, otherwise it will attach nothing (undefined).
Is it possible for a button to call a function that would 'prettify' a dynamic <code><pre>? I can't get it to work.
After the page loads, the initial <code> is prettified(?), but when I change it and call prettyPrint() afterwards, it no longer works.
Example: http://jsfiddle.net/uwBjD/2/
Edit: Sorry, I was using a local prettify.js. Updated it, still encountered the same error.
Apparently after the code is prettified, an additional class is added which is prettyprinted. Anything with the class of prettyprinted is not re-prettified. You need to remove that class before recalling the function:
$('input[type=button]').click( function() {
$("#jsExample").text(" var user = 'private'; //Do NOT store your API Key on a script.")
.parent().removeClass("prettyprinted");
prettyPrint();
});
http://jsfiddle.net/uwBjD/3/
here is the problem..
i have a javascript file which is named javascript.js like this
$(document).ready(function(){
function init()
{
//code goes here
}
}
now the index.html file has a command button which should call the init() function.
<html>
<head><script src=javascript.js ....></script>
<body><button type="button" onclick="init()">Call Init!</button></body>
</html>
But it doesn't call it. Nothing happens as expected. Please suggest a solution.
You should define your function outside $(document).ready() scope.
The onclick attribute will be executed in a global context. Your init function is scoped to the anonymous function which you pass to jQuery. Three solutions:
Move the init function outside of the ready function, into the global scope
export the init function by making it a property of the global object: window.init = function() {…};
as you use jQuery, you should not need to define any handlers in attributes. Instead use (inside the ready function): $("button").click(function init() {…}); Even better use an id to reference the button.
Try viewing the page in chrome. Hit F12 to view the console. You'll be able to quickly debug the issue. At first glance, however, I do see that your $(document).ready function is not closed properly. Add ');' at the end of the code you included. Also, add quotes around javascript.js in your script tag. See if that helps.
Why don't you use
function init()
{
$(document).ready(function() {
//code goes here
});
}
You can use flag too in order to keep track if the "//code goes here" proceeded or not. So in case of document not ready yet, you can use while loop with setTimeOut function for some pause interval "In order to not hang the client browser".
First I am using the jQuery colorbox plugin that is working fine so far but then I want to close the colorbox using a button. Unfortunately I can't just trigger the click event on that button by selecting its ID using jQuery, instead of that the button must call a javascript function called closepan() (this behavior is unfortunately mandatory for me).
I tried to create the function
closepan() {
$.colorbox.close();
}
first case : inside the
$(document).ready(function(){...});
but then I got the error closepan is undefined.
second case : before the
$(document).ready(function(){...});
but then it's the colorbox method that is undefined!
I gave up after gazillion hours of fiddling with several solutions I've found all around stackoverflow.com regarding this topic! I can't figure out how to make this working!
In other words, how to create a function named closepan() that can execute $.colorbox.close(); while being available globally for my button?
No matter where you create a variable or function if you create it on window it will be available globally.
window.closepan = function() {
// hello there
}
function closepan() {
if($.colorbox) {
$.colorbox.close();
}
}
However, at the point where someone clicks your button all external scripts should have been loaded so that check shouldn't be necessary...
Don't forget to put the keyword function in front of your declaration...
function closepan() {
$.colorbox.close();
}
Working JSFiddle