I encountered a problem that took me some time to debug where a plug-in that I was using for jQuery (in this case jFeed) was not working. The problem ended up being because we also used Amazon Associates product previews. The product previews code ends up including a number of other JS files through document.write(), including another copy of jQuery. Because the product previews code appeared below the jFeed script, jQuery was redefined without the getFeed function.
Is there a best practice to ensure that certain objects like jQuery only get defined once on a page? I'm thinking of something like #ifndef with C/C++, but I don't know how it would work in this case where I didn't write the code that dynamically pulled in jQuery again.
I think in your situation, it would probably be best to redefine the jQuery variable as something else. The other jQuery code might use a different version so you might want to define a new variable which would indicate which jQuery you're using.
You could so something like this:
<script>
var $jMain = jQuery;
</script>
You would then just use the $jMain instead of jQuery or $. It'll be up to you to you to ensure you have the correct jQuery object when you do this. Here's the documentation.
Unfortunately the environment inside one JS sandbox (like within a window or frame of a browser) was not really designed to support the modern world of pulling in scripts from various places; there's no way you can say "define this object and make it resistant to redefinition". (You can even redefine most of the Javascript built-ins if you try!)
Your best shot is to make sure that your code is eval'd last, which gives you final say over the state of the environment when it runs. That doesn't mean other code can't come along later and clobber your definitions, but that's generally really bad form. You can do this by having your script tag be the last element in the body of the document, for example.
See also this jQuery method, which won't help you directly, but gets you thinking about some solutions to page sharing: http://api.jquery.com/jQuery.noConflict/
Related
I often see in my code I am loading from my company's media central that jQuery is not available in the console normally. (No $ and jQuery)
But sometimes, to those elements to which jQuery is attached, it has a long number with it.
jQuery18306575689211022109_1378907534666
What is the purpose of doing this? Security?
Also, jQuery is sometimes available directly in the console, but only with the above numbers.
I am therefore unable to debug my apps in console, where I need to query using jQuery.
However, in the JavaScript code, jQuery is perfectly being used as $ and jQuery. So I apply a break-point and export as window.jQuery = jQuery.
Is this a proper way to debug the app, when jQuery is obfuscated?
UPDATE:
For eg., check this URL the app is calling. It seems that the URL knows what is the number appended to jQuery. How do I come to know of the same number while debugging? Any lights on what is going on?
It's a callback id automatically generated by jQuery. See the documentation for jsonpCallback.
It is preferable to let jQuery generate a unique name as it'll make it easier to manage the requests and provide callbacks and error handling.
It seems that you are confusing two different variables. You can make a quick test on this website : http://www.jquery4u.com/function-demos/jsonp/#demo. Click "run demo", open Chrome's console, type "jQuery" in order to retrieve the callback's name, then perform this simple comparison :
jQuery16409391013463027775_1379048051365 === jQuery // false
That said, the fact that the variables named "$" and "jQuery" are not available in your case may be due to a specific implementation. One possibility could be the use of jQuery.noConflict() which allows either to customize the name used as a reference to jQuery, or to completely remove all references to jQuery from the global scope (window), so there is no way to access it in the console.
I'm looking for some advice on the best way to hold my JavaScript (jQuery) functions.
I am developing in MVC/razor and therefore have a layout page. I include my jQuery library and an external JavaScript file in here so it's available in every single page.
This is working well, but I am now becoming very aware of the fact that I am adding almost 300 lines of JS to EVERY page, where maybe half of that is used in any one of these pages.
One function is not in the external file and instead sits inside the HTML because I need to use variables set in my razor code.
I have a couple of questions around this arrangement:
Is placing JS inside the HTML generally acceptable when variables set using razor are used? There does not appear to be a clean way of passing a variable into an external js file
Should I split my functions down in to individual JS files and just include what is needed for each page in the site?
If I were to split them into multiple files, how would that work with jQuery's (document).ready ? Do I need to use that if all the JavaScript I am including is to be used?
I'm sure this will more a matter of opinion than a black and white answer, but I want to consider all my options before moving on. Even though it works fine as is, I can't help but feel there is a better/cleaner way.
Remember once a user lands on your homepage and loads the javascript file it will be cached in their browser so subsequent pages will not download the Javascript again.
I would definitely keep the js separate, you could have a snippet on each page that initialise the JS that that particurlar view needs. Put something like the below in the views that need to run JS
$(document).ready(function() {
mysite.mypage();
});
Then the function mysite.mypage() can be defined in the external JS file.
300 lines isnt the end of the world, I would say its probably too early to be worryign about optimisation.
You could always look at minifying that JS file to decrease the size. A quick and easy way to do this is here:
http://www.minifyjavascript.com/
Have you ever heard of require.js? http://requirejs.org/ I find it really useful.
It's a module loader so you are able to split all of your JS code into individual files and load only the ones you need on each page.
I don't know about passing a variable to an external JS file, I don't think its possible / the 'right' way.
You can make each external JS file into a function that accepts and returns parameters. Then in the page you need to use it:
- include the file dependancy
- call the function
Thats what I do, seems like your 2nd suggestion.
for the $(document.ready) question its really up to you. You don't have to use it but its useful for some things , check out this overview:
http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
I have created an external JS file, this JS file contains some methodes that uses JQuery, i can't seem to find a way to refernece the JQuery file on JS file and user it there. Any help would be appreciated
Two things are important to reach your goal:
Include the javascript files. Include both files in your HTML via a script-tag, starting with jQuery to make sure it is loaded when used by your javascript.
Ensure jQuery. This is something way to less people tell you. If you write JS and jQuery for a long time, sooner or later you'll encounter a case where something is overwriting the $-variable. The $-variable is used by jQuery and everyone coding with it because of the obvious fact that it's just one char. However, jQuery doesn't have any "rights" or something for the $-variable, so basically anything or anyone could overwrite it. So I recommend your own javascript file looks like this:
(function($)
{
// your coding starts here.
})(jQuery);
You probably already encountered this when dissecting jQuery plugins from people who know what they're doing. It creates an anonymous function that takes one parameter which will be know by $ inside the function. The function is then immediately called and hands over the jQuery function. This way you can be sure that, whatever happens outside this function, inside of it $ stands for jQuery.
In your HTML file, include the jQuery file first and then your file:
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="myfile.js"></script>
As long as you include the jQuery core in your HTML, the global jQuery object is available in any of your scripts. Is there a specific problem you're having?
You must write a piece of script (plain JS) that checks for the presence of jQuery, if not, it must append a script reference to the page pointing to a jQuery file (or Google CDN) to include jQuery. After that, you can use jQuery in the rest of your script.
I think it will involve some interval that checks wheter the jQuery object is present or not and waits with executing the rest of your code till that it the case.
Google for this, I'm sure there is something out there.
This is how I'm currently creating a popup for a few links on my site.
function popitup(url) {
newwindow=window.open(url,'name','height=615,width=475');
if (window.focus) {newwindow.focus()}
}
Is there a cleaner way to write this? Also, how do I make the scrollbar appear?
Be sure to change newwindow= to var newwindow=; otherwise you are declaring a global variable every time you run this function.
Otherwise, I agree with fsong's answer that it's a pretty basic function and doesn't need much cleaning. Here's what I would do, but it's minor stuff:
function popItUp(url) {
var newWindow = window.open(url, 'name', 'height=615,width=475,scrollbars=yes');
if (newWindow.focus) {
newWindow.focus();
}
}
I'm not exactly sure what you mean by a cleaner way, the code seems fairly straight forward to me. But you could get rid of the return in the onclick of the anchor tag since it's useless there and perhaps you could use underscore/camel case to name your function (pop_it_up or popItUp) for better readability.
For scrollbars add ,scrollbars=yes to the last parameter (strWindowFeatures) in window.open.
JSLint
I would check your code through JSLint.
JSLint is a JavaScript program that looks for problems in JavaScript
programs. It is a code quality tool.
Like author says JSLint will hurt your feelings, but I think the error you should certainly fix is:
Problem at line 2 character 3: 'newwindow' was used before it was defined.
This is issue exactly like Domenic said.
When you check your code with JSLint your code will also have better success when using tools like Javascript Minifier.
Make Javascript external
I also think you should make Javascript and CSS external.
Using external files in the real world generally produces faster pages
because the JavaScript and CSS files are cached by the browser.
JavaScript and CSS that are inlined in HTML documents get downloaded
every time the HTML document is requested. This reduces the number of
HTTP requests that are needed, but increases the size of the HTML
document. On the other hand, if the JavaScript and CSS are in external
files cached by the browser, the size of the HTML document is reduced
without increasing the number of HTTP requests.
I think you should read Yahoo!'s best practices, because it has a lot of very good tips to optimize your website(javascript).
Why popups?
But Why should you use popups? Some users block these, which renders your site unusable. I would advice you to use JQuery and just load content into the DOM.
What is the general developer opinion on including javascript code on the file instead of including it on the script tag.
So we all agree that jquery needs to be included with a script file, like below:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"
type="text/javascript"></script>
My question is, in order to get functions on a page that is not on all pages of a site. Do we include the functions like below in the same page or in a global include file like above called mysite.js.
$(document).ready(function(){
$(".clickme").click(function(event){
alert("Thanks for visiting!");
});
});
ok. So the question is: if the code above is going to be called in every class="clickme" on a specific pages, and you have the ability to call it either from an include separate file called mysite.js or in the content of the page. Which way will you go?
Arguments are:
If you include it on the page you will only call it from those specific pages that the js functionality is needed.
Or you include it as a file, which the browser cached, but then jquery will have to spend x ms to know that that function is not trigger on a page without "clickme" class in it.
EDIT 1:
Ok. One point that I want to make sure people address is what is the effect of having the document.ready function called things that does not exist in the page, will that trigger any type of delay on the browser? Is that a significant impact?
First of all - $("#clickme") will find the id="clickme" not class="clickme". You'd want $(".clickme") if you were looking for classes.
I (try to) never put any actual JavaScript code inside my XHTML documents, unless I'm working on testing something on a page quickly. I always link to an external JS file to load the functionality I want. Browsers without JS (like web crawlers) will not load these files, and it makes your code look much cleaner to the "view source".
If I need a bit of functionality only on one page - it sometimes gets its own include file. It all depends on how much functionality / slow selectors it uses. Just because you put your JS in an external JS file doesn't mean you need to include it on every page.
The main reason I use this practice - if I need to change some JavaScript code, it will all be in the same place, and change site wide.
As far as the question about performance goes- Some selectors take a lot of time, but most of them (especially those that deal with ID) are very quick. Searching for a selector that doesn't exist is a waste of time, but when you put that up against the wasted time of a second script HTTP request (which blocks the DOM from being ready btw), searching for an empty selector will generally win as being the lesser of the two evils. jQuery 1.3 Performace Notes and SlickSpeed will hopefully help you decide on how many MS you really are losing to searching for a class.
I tend to use an external file so if a change is needed it is done in one place for all pages, rather than x changes on x pages.
Also if you leave the project and someone else has to take over, it can be a massive pain to dig around the project trying to find some inline js.
My personal preference is
completely global functions, plugins and utilities - in a separate JavaScript file and referenced in each page (much like the jQuery file)
specific page functionality - in a separate JavaScript file and only referenced in the page it is needed for
Remember that you can also minify and gzip the files too.
I'm a firm believer of Unobtrusive JavaScript and therefore try to avoid having any JavaScript code in with the markup, even if the JavaScript is in it's own script block.
I agreed to never have code in your HTML page. In ASP.net I programmatically have added a check for each page to see if it has a same name javascript file.
Eg. MyPage.aspx will look for a MyPage.aspx.js
For my MVC master page I have this code to add a javascript link:
// Add Each page's javascript file
if (Page.ViewContext.View is WebFormView)
{
WebFormView view = Page.ViewContext.View as WebFormView;
string shortUrl = view.ViewPath + ".js";
if (File.Exists(Server.MapPath(shortUrl)))
{
_clientScriptIncludes["PageJavascript"] = Page.ResolveUrl(shortUrl);
}
}
This works well because:
It is automagically included in my files
The .js file lives alongside the page itself
Sorry if this doesn't apply to your language/coding style.