Using jquery in third party js code - javascript

First of all I am new to javascript so this question might be stupid.
I have a requirement where i would provide a js script to other websites to include in their webpages.
Now my question is should I use jquery or plain javascript.Will/Can jquery effect the rest of the functionality of the site.
Plus what is the benefit I will get using jquery over plain javascript.
My requirement is to get all images of the website and do some processing on the images on these websites.
Thanks in Advance.

I would say, if the processing does not involve jQuery then do not use it.
You need to deal with the following issues if you include it
failure to load (for network reasons)
conflict with other versions locally loaded
conflict with other libraries locally loaded
All issues have workarounds/solutions but you have to implement each an everyone of those.
If you just need to find all images in page, then you can use the .getElementsByTagName() method
var imagelist = document.getElementsByTagName('img');
and just do the processing on that..
You might need of-course to attach your code at the load event to be sure that whatever your code does, the DOM is ready to accept it..
for modern browsers that would be .addEventListener(), while for IE it would be .attchEvent()
your script could be something like this
(function(){ // wrap in a self-invoking function to avoid global name-space pollution
// attach to the load event so out code runs once the page has loaded
if (window.addEventListener) { // modern
window.addEventListener('load', imageProcessor, false);
}
else if (window.attachEvent) { // IE
window.attachEvent('onload', imageProcessor );
}
function imageProcessor(){
// get all images
var imagelist = document.getElementsByTagName('img');
// loop the list of images to do something with each image
for (var img = 0; img < imagelist.length; img++)
{
var currentImage = imagelist[img];
// do processing on the currentImage which hold a reference to the image
}
}
})(); // do the self-invoking
demo: http://jsfiddle.net/gaby/nXPzk/

this would be much more easier to achieve with jQuery, mostly because you want to be able to distribute your script to any browser(and jQuery is a cross-browser library), but it does have it's downsides.
If it's your own project, your own page, you know exactly what and when to load/execute, but if you're giving your script to other folks, you have to think of 3 problems at least:
different libraries conflicts
This can be resolved using jquery's noConflict method, but I've seen it fail in some circumstances
same library conflicts
Say that the user already has loaded version X of jQuery. You oblige him to load version Y too, and besides the fact that this would be very inefficient, it may cause conflicts between different jQuery versions.
There are workarounds for this( to check if jQuery exists and load it asynchroniously if it doesn't) but the code gets a bit more complicated.
code size
When i think of a third party piece of code, I'm thinking...hmm a few kb to load to be able to run a function, but if you want to use jQuery, you may be forcing the one who uses your script to load a whole library just for your one functionality instead of a 1-2 kb (needles to say what the implications are if the user has a slow connection)
Having both the ups and downs in mind, it really depends on what are you doing, so, as Gaby aka G. Petrioli said, " if the processing does not involve jQuery then do not use it".

JQuery is much more convenient than plain javascript. You don't have to worry about cross-browser compatibility (e.g. IE vs. Firefox vs. Chrome). I would recommend this over javascript unless you are want to handle that yourself :)
You can load in the Jquery library, but that might be a little heavy than what you're looking for. Also, you will need to fetch the library from a server, which adds another point of failure (however, if you host this on your own server, then you will have more control).
TLDR: JQuery is convenient. If you have access to it, then you should use it.

Related

$(window).load fires too quickly in IE with asynchronous js libs

I have some serious problem with getting asynchronously some js libs and executing them in $(window).load in IE
all works in other browsers of course
so the problem is, that I'm doing something like
<script type="text/javascript">
var scr1 = document.createElement('script');
scr1.type = 'text/javascript';
scr1.src = 'some_lib.js';
$('BODY').prepend(scr1);
</script>
Just before </body> and use $(window).load method in html above it to operate on some plugins in some_lib.js, but it all happens to fast in IE, probable because of that asynchronous lib including, and I get an error, that method is not available for the element.
Is there any chance of maybe modyfying $(window).load method so I still could use it in the same way for every browser ?
Any code that you have in the window.load() call must be placed in a function (called onLoad in this example).
Every time you have a script that you dynamically load, increment a counter. Also include something to decrement that counter...
src1.onload = function() { counter--; onLoad(); }
Then in 'onLoad' have the first line...
if (counter > 0) return;
That means that onLoad will fire at window.load and after every script is loaded, but will only execute when it's all loaded.
It's scrappy, but it will solve your problem.
You haven't really described the reason you need to load these libraries asynchronously. Third party libraries often have "on script load" functionality that you can define before the script is loaded. If you need to load multiple libraries before you can execute your code, you may have to either 1. fire up some code every time a library is loaded to test to see if all libraries required are loaded and then fire off you code 2. for every library, create a jQuery promise/deferred to get resolved when that library is loaded and use $.when(promises).done(function/code) to test and run the code whenever a particular set is loaded, or 3. rewrite to use RequireJS. If these libraries are YOUR code, well, you may have to add start up code to your libraries anyway; It might be a good time to learn RequireJS.
I wish I could recommend further, but learning the basics behind RequireJS has always been on my todo list, but it hasn't been done; I just know of people here successfully using it. If that seems like too much trouble, I'd consider some variant of option 2. If you don't know what jQuery would be used eh... you may be stuck with option 1 or 3.
Edit:
Of course, that's not to say that jQuery has got the only promise library, I just often recommend using promises in some form for these kind of things..
Archer's technique looks interesting, I just don't know how reliable it is (it might be quite reliable, I just would like to see proof/documentation). You could combine that with option 2 also, quite well, if you want to short-cut execution for some things while leaving others to be dealt asynchronously and if those script onload methods really work as expected.

Is it possible changing DOM of an iframe from the parent frame (same document.domain)?

I want a simple and light-weighted way of making cross-domain requests to my api address (api.example.com) which is a subdomain of my main domain (example.com).
I've read A LOT about techniques and hacks to deal with XDRs and their incompatibilities with each used browser but XDR is still very complicated for me. I don't need a complete/complex solution as easyXDM, which I have implemented and worked perfectly.
So, I decided to 'enable CORS' which solved the problem for modern Webkit and Gecko browsers. But as always, there is the IE (and in this case Opera too) which is not compatible with CORS yet.
As I wanted to continue using jQuery AJAX methods, I searched for a solution that would allow XDR with jQuery methods. Then, I implemented a very nice solution by benvinegar which replaces jQuery.ajax() method and therefore all its dependent methods: https://gist.github.com/859940. His script is based on the document.domain/iframe trick.
Before calling the function proposed by Ben, I tested for CORS support with jQuery.support.cors (using jQuery 1.6.2). Everything is okay, working perfectly.
The only thing I'm not happy with the above linked script is that I need to load the jQuery library from api.example.com and I don't want that. I've made a bundle of minified javascript libraries/plugins/scripts in one file which is used by example.com; that gives me me 2 options (for using jQuery in api.example.com): load the entire bundle again or load a non-cached version of jQuery only. I don't like either.
My question is: is it possible to change the DOM of an iframe from the parent frame when both frames have the same document.domain? If so, could I clone jQuery from example.com into the child-iframe (api.example.com)? How? Or I'm just being crazy about this and there is a better solution taking in consideration what I described?
Thank you all in advance,
Leonardo.
file test.htm
<iframe name='my-iframe' src='test2.htm' onload="child();"></iframe>
<script>
function child(){
alert(window.frames['my-iframe'].my_var);
window.frames['my-iframe'].my_var = 'bye';
window.frames['my-iframe'].show_var();
}
</script>
file test2.htm
<script>
window.my_var = 'hi';
function show_var(){
alert(my_var);
}
</script>
The code above will alert 'hi' and then 'bye'

alternative when an older browser does not accept jquery

I have just been altered to the fact that a user of my website is using a very old browser which does not run jquery (in this case Safari 1.x) and as a result can not access the login panel which uses jquery's slideToggle function.
Can anyone think of a fix which detects whether a browser is able to use jquery - and if not make that link go to a different page rather than showing the login panel?
You could a little conditional check like
if(!'jQuery' in window) {
// jQuery is not available
}
or, if Safari 1.x doesn't know about the IN operator (I'm not sure) use
if(!window.jQuery) {
}
I think there are alternative answers to this, but for me, I would have to weigh up the time it will take you to support his obsolete browser (I'm sure there may be other things inside the site), versus the payback to you...
In the plain HTML source code for the the href= of the login link, set that to a plain HTML login page.
Using jQuery, attach the click handler to the link, if this part fails, thats ok, the browser will just follow the href in the link to the plain login page, allowing your old-browser-user to login still.
$(document).ready(function(){
$('#login_link_id').click(function(){
// Your code here
});
});
If you use javascript/jQuery you should ALWAYS ensure your site works perfectly without it. In this case if you have a login popup box; you probably assign a click event assigned after the DOM has loaded.
What you should do is ensure that if jQuery isn't present the link loads a "normal" login webpage as opposed to the popupbox. I use something similar to this:
Log in
<script>
if(!'jQuery' in window) {
$(document).ready(function(){
//assign on click event to loginlink
});
}
</script>
If jQuery doesn't exist then login.html will be opened normally.
Wow, seriously?! Safari 1.x?? Anyhow, try this...
var isJQSupported = false;
$(function() { //shorthand for document.ready
isJQSupported = true;
//your usual code
});
if (!isJQSupported) {
window.location = "http://www.apple.com/safari/download/";
}
To me it sounds like safari 1.X has problems with jQuery internally. Which means simple checks like whether $ exists in the global space or whether $(function) does anything are not going to help.
The most likely root cause will be that javascript throws an error in loading of jQuery itself which will then stop the rest of your javascript code from execution.
There are four viable options here.
Either make the website work with noscript. Replace your login control with pure HTML and postbacks and ask the user to turn javascript off. This option is useful since you won't be fixing the issue for safari 1.x problems specifically.
You can make javascript check for safari 1.X and other non-supported browsers and only load jQuery through script tag injection or ajax if your user is using a supported browser. If the user is using a browser not compatible with jQuery then you can instead use plain javascript.
Get a copy of safari 1.x and see why jQuery breaks. Then fix it and ask for it to pulled into the release of jQuery 1.5. This relies on the fix being something that does can be done without hacking and that the jQuery team agrees is worth adding in.
Ask the user to use a compliant browser.
There might be some more options. I would personally lean towards asking the user to use a compliant browser because supporting Safari 1.x is ridiculous.
This seems like a case where progressive enhancement is needed.
You have to do multiple checks
see if $ exists
see if $.fn exists
[not sure if needed] check if $.support is a function
check for feature support as needed with $.support() http://api.jquery.com/jQuery.support/
At the end of the check, when jQuery reports that features you need are present - the rest of the script can run.
If you're not sure which features mentioned in the support you use, then this might need a single test on Safari 1.x to see what are the values returned by $.support(), but that is what your nasty old-browser-user can do for you (if you prepare code and publish) and report the resulting text. Then you compare the list with other [old] browsers that are accessible and determine features that are required.
The easy way would be to require everything and cancel all scripts if suport for any feature is missing. This will also rule out IE6 and IE7 and opera below 9.something and firefox below 2.0 or including - I'm not sure.
Use a server side language to detect if it's the old safari based on user-agent and load a different javascript file

What's with the random Javascript errors?

I'm developing a site in javascript and jquery. Sometimes when I refresh I just get different random errors in firebug. What's the deal?
edit: I'm getting errors like a variable isn't defined, when clearly it is and working, and when i refresh again, the error is gone..
using Firefox V3.5.5 Firebug V.1.5.3 and I'm primarily working with jQuery 1.4.2
OK. While it's more or less impossible to give a reasonable solution to such a general question, I'll just add my 2 cents' worth:
One possible source of "undefined variable" errors comes from including several scripts, which may or may not always load and execute in the same order. If you define a variable in one script (let's call that script declare.js) and use it in another (let's say use.js), and use.js is executed before declare.js, then you will get such an error. If the scripts execute the other way around, everything will appear fine.
If you're interested in this very topic, have a look at e.g. Steve Souders' book Even faster web sites, published by O'Reilly. More specifically, look at the chapter about non-blocking script loading.
Most common cause is that you're trying to execute Javascript before the DOM is loaded and thus before all HTML elements are available in the DOM tree, which in turn may cause that simple calls like document.getElementById(id) and jQuery's $(selector) may return undefined elements. That it sometimes works is pure coincidence and a matter of timing.
You need to ensure that any Javascript/jQuery code which is supposed to be executed during page load and relies on the availability of the elements in the DOM tree, also really get executed after the DOM is loaded. In plain vanilla JS you can do so:
window.onload = function() {
document.getElementById(someId);
}
and in jQuery:
$(document).ready(function() {
$(someSelector);
});

How to help the debugger see my javascript, or how to best refactor my script to help make it debugger-friendly?

I have an ASP.NET MVC project that uses some simple AJAX functionality through jQuery's $.get method like so:
$.get(myUrl, null, function(result) {
$('#myselector').html(result);
});
The amount of content is relatively low here -- usually a single div with a short blurb of text. Sometimes, however, I am also injecting some javascript into the page. At some point when I dynamically include script into content that was itself dynamically added to the page, the script still runs, but it ceases to be available to the debugger. In VS2008, any breakpoints are ignored, and when I use the "debugger" statement, I get a messagebox saying that "no source code is available at this location." This fails both for the VS2008 debugger and the Firebug debugger in Firefox. I have tried both including the script inline in my dynamic content and also referencing a separate js file from this dynamic content -- both ways seemed to result in script that's unavailable to the debugger.
So, my question is twofold:
Is there any way to help the debugger recognize the existence of this script?
If not, what's the best way to include scripts that are used infrequently and in dynamically generated content in a way that is accessible to the debuggers?
I can not comment yet, but I can maybe help answer. As qwerty said, firefox console can be the way to go. I'd recommend going full bar and getting firebug. It hasn't ever missed code in my 3 years using it.
You could also change the way the injected javascript is added and see if that effects the debugger you're using. (I take it you're using Microsoft's IDE?).
In any case, I find the best way to inject javascript for IE is to put it as an appendChild in the head. In the case that isn't viable, the eval function (I hate using it as much as you do) can be used. Here is my AJAX IE fixer code I use. I use it for safari too since it has similar behavior. If you need that too just change the browser condition check (document.all for IE, Safari is navigator.userAgent.toLowerCase() == 'safari';).
function execajaxscripts(obj){
if(document.all){
var scripts = obj.getElementsByTagName('script');
for(var i=0; i<scripts.length; i++){
eval(scripts[i].innerHTML);
}
}
}
I've never used jquery, I preferred prototype then dojo but... I take it that it would look something like this:
$.get(myUrl, null, function(result) {
$('#myselector').html(result);
execajaxscripts(result);
});
The one problem is, eval debug errors may not be caught since it creates another instance of the interpreter. But it is worth trying.. and otherwise. Use a different debugger :D
This might be a long shot, but I don't have access to IE right now to test.
Try naming the anonymous function, e.g.:
$.get(myUrl, null, function anon_temp1(result) {
$('#myselector').html(result);
});
I'm surprised firebug is not catching the 'debugger' statement. I've never had any problems no matter how complicated the JS including method was
If this is javascript embedded within dynmically generated HTML, I can see where that might be a problem since the debugger would not see it in the initial load. I am surprised that you could put it into a seperate .js file and the debugger still failed to see the function.
It seems you could define a function in a seperate static file, nominally "get_and_show" (or whatever, possibly nested in a namespace of sorts) with a parameter of myUrl, and then call the function from the HTML. Why won't that trip the breakpoint (did you try something like this -- the question is unclear as to whether the reference to the .js in the dynamic HTML was just a func call, or the actual script/load reference as well)? Be sure to first load the external script file from a "hard coded" reference in the HTML file? (view source on roboprogs.com/index.html -- loads .js files, then runs a text insertion func)
We use firebug for debug javascript, profile requests, throw logs, etc.
You can download from http://getfirebug.com/
If firebug don't show your javascript source, post some url to test your example case.
I hope I've been of any help!
If you add // # sourceURL=foo.js to the end of the script that you're injecting then it should show up in the list of scripts in firebug and webkit inspector.
jQuery could be patched to do this automatically, but the ticket was rejected.
Here's a related question: Is possible to debug dynamic loading JavaScript by some debugger like WebKit, FireBug or IE8 Developer Tool?

Categories