JQuery function call from out of context - javascript

A js/css template is provided to me.
It is very talented in interactive event handling, but i am not talented on js/jquery.
In its js library, there is a .js file,
and the file has some code like:
(function ($) {
...
})(jQuery);
most of thing happens in it.
There are some "little independent functions" in this upper function.
And some lines in this upper/wrapper/non-named function, call these "little-independent functions".
Also, i want to call these "little independent functions" BUT i could not find out how.
Because in the lines in "(function ($) {...})(jQuery);" those call these "little independent functions" there are some local variables.
I think some code help me to tell:
(function ($) {
if(...){
var items;
addItem(items)
}
function addItem(funcitems){}
...
})(jQuery);
My question is that, how can i call additem, how can i pass "items" into it?
I want to call it in a custom part of my page after a custom event.

Since they're not exposed in any way, it's impossible without some crazy js hacks or editing the code. If you're sure the library doesn't expose an equivalent method, then the only real solution is to edit it.

You have two options to achieve this:
1) Add your code into this anonymous function, so that your code is in the same scope like these encapsulated functions. (Not so good since you are compromising the library)
2) Make a variable assignment and add a return-statement with the functions you need: (better, since you dont mix the library code with your own and just expose a few of the functions)
var extLib = (function ($) {
...
return{
/* return the functions you need - written in object literal notation */
addItem : addItem
/*[,exposedName : internalName] */
}
})(jQuery);
Now you can access the addItem function by calling extLib.addItem(item).

Related

Overriding core JS commands?

I'm trying to modify/limit/prevent access to certain JS commands of my browser. For example commands like navigator.clipboard; However, I'm not sure how to approach this.
Is it possible to override these commands with user-defined javascript injected in the page, or do i have to edit the browser's javascript compiler and re-compile it from source for this?
I'm not really familiar with browsers and want to save time by knowing a general direction to follow. Thanks
First of all navigator.clipboard is not a function, but here is an example using the read function of navigator.clipboard:
navigator.clipboard.read = function (originalFunction) {
return function (yourParamsYouWantForThisFunction) {
// Do Stuff you wanna do before the real call. For example:
console.log(yourParamsYouWantForThisFunction);
// Call the original function
return originalFunction.call();
};
}(navigator.clipboard.read); // Pass the original function reference as a parameter
You may wonder, why there are two function statements:
The first one is there, so that we can pass the original function at runtime. If we would not do that, we would not be able to access the original navigator.clipboard.read function.
The second function is the actual function, that you will be using later, when you call navigator.clipboard.read().

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!

What is the difference between Template.created and Template.onCreated in Meteor?

Template.templatename.onCreated is mentioned in the documentation (along with the .onRendered and .onDestroyed methods).
But when I call these nothing happens. If i call Template.templatename.created for instance, this works.
Any idea whats going on? Am I misreading something in the docs? is this a reference to something else ?
EDIT : I've just found this in the source :
https://github.com/meteor/meteor/blob/master/packages/blaze/template.js#L65
on line 180, these are marked as deprecated in 1.1, but I'm still not getting any love from onCreated....
anyone know what I'm doing wrong?
Template.channels_admin.onCreated = function () {
// .... doesn't run
};
Prior to meteor 1.0.4, created was a function available to all templates that ran prior to any of the template logic (events, rendering, helpers, etc.). In 1.0.4, it was replaced with onCreated which is a function that registers callbacks (again each callback runs once before any template logic).
created was left in place so as not to break existing code, but is considered deprecated in favor of onCreated.
Because created was a function on the template, it could be assigned via:
Template.myTemplate.created = function() {console.log('here');};
created should not be called directly.
As you can see from the docs, onCreated is called with a function like so:
Template.myTemplate.onCreated(function() {
console.log('hello');
});
The nice thing about onCreated is that you can register multiple callbacks for the same template. In practice this may not come up often, however it's nice in cases where you need to attach to a template provided by an external package. This same logic applies to onRendered and onDestroyed.
As of meteor 1.1 the created, rednered and destroyed methods have been deprecated in place of onCreated, onRendered and onDestroyed.
Secondly there is a small change to the syntax previously it was declared like so :
Template.channels_admin.created = function () {
// .... this is deprecated
};
But as of 1.1 it should be declared like so :
Template.channels_admin.onCreated(function () {
// .... works like a charm.
});
created is the old onCreated.
use it like this .onCreated(function() {
this makes it really nice when you write packages.

Require.js and reusable UI functions

I'm working on a project written using Require.js. There are a number of reused functions that are currently being called from the global scope. These functions involve ui transitions, hide/show, and general on hover events. I want to organize these functions right into require, but not quite sure where/how to include them.
For example let's say in the app there are multiple spots that may call a common function of showDropdown(). And let's say it requires jQuery for the animation. Where or how would be the best place to store the showDropdown function?
Say a simple function like:
function showDropdown(id) {
var thisdropdown = $(id).find('.dropdown');
$(thisdropdown).slideDown();
}
I could create a UI folder, with the different js functions all being their own file. Then simply require them on any other files that are dependent on them. But regardless, those files will need to export their function to the global scope to be accessible correct?
I feel there is an obvious answer/setup as this must be fairly common item.
In addition, I am writing this in a backbone app, but I don't believe that has any direct impact, more of a require.js question.
Create a util library or something like that:
// util.js
define({
showDropdown: function(id) {
var thisdropdown = $(id).find('.dropdown');
thisdropdown.slideDown();
}
});
Then use it elsewhere:
require(['util'], function(util) {
util.showDropdown('my-id');
});

break js to files with $(document).ready() but keep scope

I would like to break my javascript code to several .js files. Each of those .js has code that need to be inside the $(document).ready(..). So in each file a new $(document).ready(..) will start.
How could I call from filea.js functions declared in fileb.js (both inside a $(document).ready block) ?
If this is not possible, can you propose an alternative?
Thank you.
Edit: I would like to clarify that I would like to avoid using the global scope. I was hoping something in the line of using named functions as handlers for the event but I can't really see how to do it.
You can make a local variable global with
window.globalname = localname;
Remember that functions are variables.
You really can't get away from declaring a global. Creating a single global isn't so bad, you can then namespace all your functions under it.
Put this in something like a main.js file, so you can keep your shared functions here:
// name this something unique to your page/site/app
var MYAPP = {};
// now we can attach functions to it
MYAPP.funcA = function() { /* ... */ };
MYAPP.funcB = function() { /* ... */ };
Then, in each of your anonymous functions you can access MYAPP.funcA(), MYAPP.funcB(), etc. You can also modify MYAPP on the fly to add functions, properties, etc.
In the end you have a single global (darn it!), but if you've named it properly you are creating a global namespace where your app code can safely reside.
As long as the files are loaded in order (i.e. functions in filea.js get loaded before fileb.js calls them, you should be fine.
In order to make sure files load their dependencies first, you could consider require.js or head.js
I've had luck with the latter: http://headjs.com/

Categories