call a function onload of external script - javascript

I'm playing around with Google Drive API, and noticed that they are calling a handleClientLoad function onload of the client.js.
<script src="https://apis.google.com/js/client.js?onload=handleClientLoad"></script>
Trying to avoid creating globals, I thought I would start with creating another js file, that would contain a module pattern and return handleClientLoad.
var module = (function (window, $) {
'use strict';
var module = {
handleClientLoad: function () {
console.log('ok, can access');
}
};
return module;
}(window, jQuery));
And then I assumed I could just call the handleClientLoad by doing module.handleClientLoad, but that doesn't seem to be working.
<script src="scripts/main.js"></script>
<script src="https://apis.google.com/js/client.js?onload=module.handleClientLoad"></script>
Questions:
Is it possible to call the module.handleClientLoad from onload of client.js?
Appending onload and calling a function from a script file seems sloppy and obtrusive, no? Is there a cleaner way to know when the client.js has loaded?

Have you tried debugger, and are you sure module. hanfleClientLoad exists at the time the callback is fired?
You can poll for the existence of gapi.client as a global object. Give it a few milliseconds to initialise before invoking its methods.

I found that jQuery.getScript() worked quite nicely for this. Documentation here.
Instead including the <script> tag in the html page, I simply included the following line in my js file:
jQuery.getScript( "https://apis.google.com/js/api.js", handleClientLoad );
It might require slight tweaking for the way you structured your module, but I think this will be easier than passing a parameter to your <script> tag (at least I found it easier).

I know this is old, but I was messing around with this because this was related to a question on a test I was studying for. You can use onload like this when you call the script:
<script src="https://apis.google.com/js/client.js" onload="handleClientLoad()"></script>
For anyone wanting to know why this won't work:
<script src="https://apis.google.com/js/client.js">handleClientLoad()</script>
It's because any code between a script tag with "src=" in it will be ignored.
And I'm not sure why using onload= in the script tag calling the external script is any more obtuse than appending ?onload=module.handleClientLoad to the source? But that's just me.
In the end, I'm not sure why exactly this was a question on the test, because based on searching, this doesn't seem to be a common thing that anyone does.

Related

How can I import this in JavaScript?

I have a JavaScript function that runs in an HTML file, but in order to avoid "angular is not defined", I put the following before my HTML script
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js">
Is there a way to do this in a actual JavaScript file? I want to write my function in a JavaScript file not HTML so I can't use src HTML code.
I tried copying all the code and putting it in a file and referencing the file in the JavaScript but it doesn't work.
Any workarounds?
A simple technique that I use to load dependencies is to dynamically append them to the document head and use a load EventListener to run my code after the external script has finished loading.
let s = document.createElement('script');
s.src = 'https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js';
s.addEventListener('load', init);
document.head.appendChild(s);
function init() {
// your code here
}
Source: I build a lot of plugins/widgets.
There are a variety of solutions to this problem and you should review how scripts load and the onready events for an html document. One simple solution would be coding your custom function to be called in an approach something like this:
<script onload="myCustomFunction();"
src ="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js" >
</script>`
Of course, there are really many different approaches and I would consider this one only to use in a quick and dirty situation.
Something like:
const libname = require("https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js")
Should import the .js file into your project.

Unresolved function or method in module loaded in different <script> tag

PyCharm is reporting me Unresolved function or method in the following pattern:
<script src="some-lib.js"></script>
<script>
var foo = use_some_lib();
foo.do.stuff();
</script>
use_some_lib() method that is part of some-lib.js is "Unresolved".
Is there any proper way or best practice to handle it? I found workarounds suggesting to append second code in second tag to the code of some-lib.js, but it does not seem to be an elegant solution.

Access variable from 1 .js source file (jqTree), from within different .js file, to override method

(new to JS, jQuery, & jqTree)
I am trying to override a method (JqTreeWidget.prototype.openNode) from one .js file (tree.jquery.js) in another (my own custom.js).
I've read that to override a js method in general, I just need to redefine it. So I am trying to do that on the method, and I think I am stuck on accessing the variable that has the original method (JqTreeWidget). I think the challenge is that the original method is in tree.jquery.js (source) that is separate from my own other custom.js file where I want to do the override.
The goal of this Question would be to allow me to write something like this in my custom.js (<reference to JqTreeWidget.prototype.openNode> would be the Answer to this Question):
var originalMethod = <reference to JqTreeWidget.prototype.openNode>;
// Override of originalMethod
<reference to JqTreeWidget.prototype.openNode> = function( node, slide ){
// my code I want to happen 1st here
changeAncestorHeightRecursively( node, true);
// my code is done, and now I'm ready to call the original method
originalMethod.call( this, node, slide );
}
I think that would be the most non-intrusive way to do the override, without actually hacking in to the tree.jquery.js source.
See my custom.js at http://codepen.io/cellepo/pen/LGoaQx
The separate source tree.jquery.js is added externally in the JS settings of that codepen.
How can I get access (from within my custom.js file) to JqTreeWidget variable that is in the source file (tree.jquery.js)? Is it even possible? Is JqTreeWidget not in scope outside of tree.jquery.js, or is it not a global variable? I was hoping treeContainer.tree.prototype would have it, but I haven't had luck so far...
Thanks!
The prototype object can be obtained via:
jQuery.fn.tree("get_widget_class").prototype
Note that this is not a generalized solution for any jQuery plugin. This is something explicitly implemented by the tree plugin.
I found this hacky workaround. But since it's a hack, I'd still prefer to find the Answer as posed in this Question (so please, continue to Answer with respect to the <reference to JqTreeWidget.prototype.openNode> I mentioned in the Question, thanks)...
As stated in this Question, the goal involves making it possible to override JqTreeWidget.prototype.openNode (from tree.jquery.js) externally in custom.js. As such, calls to changeAncestorHeightRecursively (my code) & JqTreeWidget.prototype.openNode would both be made from the override in custom.js, and tree.jquery.js source is not modified at all.
Workaround:
Declare global var in html:
<script type='text/javascript' language="javascript">
changeAncestorHeightRecursively = 1;
</script>
In custom.js, set the globar var to the function (the one I want to be called before JqTreeWidget.prototype.openNode):
window.changeAncestorHeightRecursively = changeAncestorHeightRecursively;
Call the global-var-referenced function at the beginning of JqTreeWidget.prototype.openNode (hack into tree.jquery.js):
JqTreeWidget.prototype.openNode = function(node, slide) {
// Only way I could figure out to get this to execute before the rest of this method
// (global-var-referenced function in custom.js)
changeAncestorHeightRecursively( node, true );
// Rest of original openNode code...
}
This calls my code function from within tree.jquery.js, as opposed to calling the overridden method from within custom.js. So this is hacky because of the global var, and modifying tree.jquery.js source.
This will work for now, but hoping for a less hacky Solution as stated in this original Question... Thanks!

JavaScript top or bottom - location sensitive?

Why does a linked JavaScript file sometimes not work when it is included at the top of the page and not at the bottom?
<script type="text/javascript" src"..."></script>
For example, if you want to manipulate DOM items, and those are not yet existing, it won't work. If the JavaScript file is included in the head, the body is not existing yet, but if you include it at the end of the body, those items are valid.
If you don't want to rely on this behaviour, you may define a callback, which is run, when the document is ready, i.e. when the whole of the DOM is loaded already.
This is what e.g. jQuery achieves with $(document).ready(function() {}), or more shortly $(function () {});. In vanilla JavaScript (using modern browsers, so IE9+) this can be achieved using
document.addEventListener("DOMContentLoaded", function() {
// code...
});
The best way to know why is it not working is by checking for JS error. Try to find out what errors you are getting when the script has been included at the top. As mentioned in the other response it can be because of DOM items. You can circumvent this issue by adding a "defer" tag to the script.
It can also be because of some JS object you are expecting to be present when this script runs. For example if your script tag is serving a JSONP request then you must have the function that processes the data. Otherwise you will get a "undefined function" error when the script runs.
JS code is executed instruction by instruction from top to bottom.
The code that calls a function needs to be under that functions definition.
This code works:
var func = function()
{
alert('it works');
};
func();
While this doesn't:
func();
var func = function()
{
alert('it works');
};
It throws an undefined error. The reason for this is that JS compiler is not aware of the func definition at the time it tries to call it.
Same goes for the JS files included in your HTML page. You can include them at the bottom as long as there are not dependencies in above sections, or, if they do not try to manipulate HTML code before page load.

jquery-extension not executing in chrome app

I've encountered a strange problem with my chrome app i'm developing at the moment.
I want to use the "knob" extension to use it for a alarm-clock slider (to set the time)
This wouldn't be a really difficult matter, wouldn't it be for the restrictions and strange issues found while programming a chrome app.
In my index.html file I included the jquery library and the knob extension. And that is where the problems started. Somehow, my scripts only can use the Id's of elements that are above them. So when I include the tags between the tags, nothing executes, if I put them after the first tags they only work with the things that are in this div container. thats why I put the script just before the tag. That works well for "normal" javascript usability. But because I have a that referes to a jquery function (for the knob) the jquery library should be already loaded before the function gets executed (if not, it just doesn't work). I tried to get a workaround by using these posibilities:
document.onload=test();
function test(){
$(function() {
$(".dial").knob();
});
}
document.onload=test();
$(function test() {
$(".dial").knob();
});
}
document.onload=$(function() {
$(".dial").knob();
});
}
well.... It didn't work. I also tried window.onload, with the same reuslt. does someone have a solution? It would be of great help.
Thank you,
neissen
Try like this:
$(function() { //document ready function
function test(){ //inside the ready function
$(".dial").knob();
}
test(); // and call the function here
});
Your Problems:
jQuery may not be loaded but you used some vanilla JS to handle jQuery, which will cause errors.
May be related to global and local.
For the external scripts, functions are only fired locally, which means the global object which contains the html won't be able to be accessed.
To make a global function and a jQuery library - JS:
if ("undefined" === typeof jQuery) {throw new Error("This library requires jQuery"); }
$(function() {
window.myFunction = function() {
doSomething();
}
doSomething();
})
Works calling from HTML - HTML:
<script>
$(function() {
doSomething();
})
</script>
Above is the safest way to approach a jQuery library. The $(function() {... part means exactly the same as $( document ).ready(function() {..., execute if loaded and ready, ensures the browser knows how to deal with all the functions used.

Categories