I found the following definition
$.fn.flex = function ( options ) {
var p = this.data("flex"),
opts = options || {};
if (p) return p;
this.each(function () {
p = new Flex( this, opts );
$(this).data("flex", p);
});
return opts.api ? p : this;
};
which defines function flex() in original code.
Unfortunately, it stops defining this function in my environment, i.e. function call causes an error that flex is not a function.
What is critical here for flex being a function?
UPDATE
Sorry, actually I didn't modify anything. I just put this javascript https://github.com/jasonenglish/jquery-flex/ into my environment (Liferay) and the code to run script
<script type="text/javascript">
$(function() {
$(".flex").flex();
});
</script>
caused an error. So I replaced $ to jQuery everywhere as I did before and it is still not working.
UPDATE 2
Hmmm. Error occurs in widget.js from Twitter. Says
TypeError: jQuery(...).flex is not a function
If I rename flex to flex1 everywhere, it says "flex1" is not a function.
Sorry, actually I didn't modify anything. I just put this javascript ... into my environment (Liferay) and the code to run script
Because that's a jQuery plug-in, you need to make sure you include that script after jQuery on the page. So
<script src="/path/to/jquery.js"></script>
<script src="/path/to/the-plugin.js"></script>
If you put them in the other order, the first script will fail because it will try to take the value of the jQuery symbol, which doesn't exist yet, throwing a ReferenceError (in both loose and strict mode).
First of all in $.fn.flex $ and fn are jQuery variables. they are not native to JavaScript. $.fn provided by jQuery to attach method/property to jquery object
Related
I am trying to write some userscripts in JavaScript to be used with browser extensions.
In a website, I tried overriding a function defined in an external javascript, with Object.defineProperty. but it seems that this breaks the external script, because other codes in the external scripts (that are essential to the original website) seems to be not executing as well.
<html>
<head>
<!-- injected script, injected via Userscript -->
<script>
Object.defineProperty(window, 'originalFunction', { get: function() { return overridingFunction; } });
</script>
<!-- injection end -->
</head>
<body>
<script src="/external-javascript.js">
<script> originalFunction(); </script>
<script> anotherEssentialFunction(); </script>
</body>
</html>
and http://domain/external-javascript.js looks like this"
...
function originalFunction() {
some codes here;
}
...
function anotherEssentialFunction() {
....
}
and this was preventing anotherEssentialFunction from running. In the console, I see TypeError: can't redefine non-configurable property originalFunction and ReferenceError: anotherEssentialFunction is not defined
Is this expected in this situation, or there should be other problem causing it that is not described here? How can I safely override original function without causing such an error?
Object.defineProperty takes the name of a function as a parameter, so you'd have to do this instead:
Object.defineProperty(window, 'originalFunction', {
get: function() {
return overridingFunction;
}
});
Or if that's all the getter does, simply:
window.originalFunction = overridingFunction;
But if the other functions need to call the original function, you can't really override it without breaking the functions that rely on its behavior. If you're just trying to execute custom code in addition to the original code, you can do this:
var origFn = window.originalFunction;
window.originalFunction = function () {
customFunction();
origFn.apply(this, [].slice.call(arguments));
};
Update:
Based on your comment, it sounds like you're wanting to not only override the original function but also prevent the external script from redefining that function. You can maybe add a no-op setter to avoid the external script from getting an error when trying to define it:
Object.defineProperty(window, 'originalFunction', {
get: function() {
return overridingFunction;
},
set: function(ignored) { }
});
I have used infragistics igGrid in my application but I am getting javascript error
Object doesn't support property or method "_super"
I know this can be avoided but I want to give it fake implementation (or real answer, may be adding some missing reference) for some reasons. I tried following but not working.
var _super = function(a,s,d,f,g,h) {
}
I have wrote above code before referencing igGrid JS libraries.
In code, _super has variable number of arguments when calling it.
You're probably referencing a version of jQuery UI that still doesn't have _super and _superApply implemented. Try referencing the latest version and the error should go away.
https://bugs.jqueryui.com/ticket/6861
If I understand correctly you are trying to use _super out of scope. You can use _super in the objects scope like this :
(function ($) {
$.ig.RPCDataSource = $.ig.RPCDataSource || $.ig.RESTDataSource.extend({
_processJsonResponse: function (data, context) {
try {
console.log('my special preprocessing');
return this._super(data, context);
} catch (e) {
console.log(e.message);
// my special error handling
}
},
});
}(jQuery));
UPDATE
_super is a method from the jQuery widget factory. iG controls are built upon jQuery Widget. Therefore _super is defined in jQuery widget.
I am trying to write a script for a dynamic drop down menu as a way to learn OOP javascript and jQuery. You can see the dummy site at www.industrialMerchants.com/industrialMerchants. The script can be found at www.industrialMerchants.com/industrialMerchants/javascript/horizontalDropMenu2.js
The script first defines a number of objects, after which I have a $(document).ready() with a closure designed to initiate the process of wrapping relevant jQuery objects and DOM elements into my object model.
The problem is, when I load the static html document serving as a dummy website, Firebug gives me the following error:
"TypeError: jqObject is undefined."
The error points to the fifth line of the following function.
function Menu(jqObject) {
self = this;
this.self = jqObject;
this.submenus = (function(){
jqObject.children().children("ul").each(function() { <<--- Error
submenu = new Submenu($(this), self);
submenus.push(submenu);
return submenus;
});
}());
}
The lines that call the function are here:
$(document).ready(function(){
menus = new Array();
$("ul.horizontalDropMenu").each(function(){
menu = new Menu($(this));
menus.push(menu);
});
});
As you can see, the call to the Menu() object constructor includes as an argument a reference to a jQuery object, so that jqObject clearly IS defined. So what gives?
When I insert breakpoints into the code starting at the $(document).ready() declaration, the execution completely skips it altogether, and starts at the function declaration itself. It's as if the browser is trying to execute the function declarations before any explicit call to them is made.
Setting a breakpoint and going up the call stack gives me this line (outside .ready - but that doesn't matter):
Submenu.prototype = new Menu();
You're creating a menu instance without a jQuery object but with undefined instead.
i was exploring in the last few days how big frameworks works , how they assign their function name and it can't(?) be override , i pretty much know how framework work with anonymous function , for example they do it this way or similar version :
(function(){
var Sizzle = function (){
var x;
};
Sizzle.f = function(){
alert("!");
};
window.Sizzle = Sizzle;
})();
i still don't get few things about those huge frameworks and i hope i can find answer :
how do they assign function name and the name can't be override?
in the code above to call the function i need to write Sizzle.f() to get the function to work , but when i use jquery i don't write Jquery.show() , just show() , how do they vanish the "jquery" from "jquery.show()" function call?
by saying the name can't be override i mean , if i create function with one of the jquery functions names , the jquery function will work.
thanks in advance.
As has been shown for #2, it's really easy for BIG_NAMESPACE.Functions.doStuff to be added to anything you want.
var _ = BIG_NAMESPACE.Functions.doStuff;
_(); // runs BIG_NAMESPACE.Functions.doStuff;
As for #1:
Most libraries DO let their functions be overwritten.
It's the values that are inside of the framework's closure which are preserved, for safety reasons.
So you could do something like:
BIG_NAMESPACE.Functions.doStuff = function StealEverything() {};
(BIG_NAMESPACE.Functions.doStuff === StealEverything) // true;
But doStuff would have NO access to any of the variables hidden inside of the framework's closure.
It would also mean that until the page was reloaded, doStuff would also not work the way you want it to.
HOWEVER, in newer versions of JavaScript (ECMA5-compatible browsers), it WILL be possible to do something like what you're suggesting.
BIG_NAMESPACE = (function () {
var do_stuff = function () { console.log("doin' stuff"); },
functions = {
set doStuff (overwrite) { }
get doStuff () { return do_stuff; }
};
return { Functions : functions };
}());
Then, this will work:
BIG_NAMESPACE.Functions.doStuff(); // "doin' stuff"
BIG_NAMESPACE.Functions.doStuff = function () { console.log("ain't doin' jack"); };
BIG_NAMESPACE.Functions.doStuff(); // "doin' stuff"
However, Frameworks aren't going to use this for a LONG time.
This is not even remotely backwards compatible. Maybe in 2016...
There were defineGetter and defineSetter methods as well, but they aren't a formal part of the JavaScript language. Like innerHTML, they're things that the browser vendors put in, to make life better... ...as such, there's no real guarantee that they're going to be in any/all browsers your users have. Plus, they're deprecated, now that new browsers use the get and set constructs that other languages have.
(function(){
var jqueree = {};
jqueree.someval = 22;
jqueree.somefunc = function(){ alert(this.someval); };
window.jqueree = jqueree;
window.somefunc = function(){ jqueree.somefunc.call(jqueree); };
window.$$$ = jqueree;
})();
// all equivalent
window.somefunc();
window.jqueree.somefunc();
$$$.somefunc();
somefunc();
Answering your Questions
At the top of jQuery you'll see: var jQuery = (function() {, which creates the local function (its incomplete; the }); occurs elsewhere).
At the very end of jQuery you'll notice the following, which is how it attaches it to the global namespace:
// Expose jQuery to the global object
window.jQuery = window.$ = jQuery;
I have never seen a jQuery function called without referencing the jQuery object. I think you always need to use jQuery.show() or $.show(); however maybe you're saying you don't have to call window.jQuery.show(), which you are permitted to drop the window, since that is the default.
Using your example
(function(){
/* This is where Sizzle is defined locally, but not exposed globally */
var Sizzle = function (){
var x;
};
/* If you put "window.f = Sizzle.f = function(){" then you could *
* call f() w/o typing Sizzle.f() */
Sizzle.f = function(){
alert("!");
};
/* The following line is what makes it so you can use Sizzle elsewhere *
* on your page (it exposes it globally here) */
window.Sizzle = Sizzle;
})();
use function _name_() {} and the name is static
the simply use var $ = jQuery; to create an alias.
jQuery works this way:
Supposed you have this jQuery code:
$("#title").show();
You have three elements to that line.
$ is a javascript function
"#title" is an argument to that function
.show() is a method call
Here's how it works.
Javascript executes the function named $ and passed it an argument of "#title".
That function does it's business, finds the #title object in the DOM, creates a jQuery object, puts that DOM element into the array in the jQuery object and returns the jQuery object.
The Javascript execution engine then takes the return value from that function call (which is now a jQuery object) and looks for and executes the .show() method on that object.
The .show() method then looks at the array of DOM elements in the jQuery object and does the show operation for each DOM element.
In answer to your question, there is no .show() all by itself. It's a method on a jQuery object and, in this example, that jQuery object is returned from the $("#title") function call.
I am writing a simple counter, and I would like to make installation of this counter very simple for users. One of the simplest counter code (for users who install it) I ever see was Google Analytics Code
So I would like to store main code in a file and user who will install my counter will need just to set websiteID like this:
<html><head><title></title></head><body>
<script type="text/javascript" src="http://counterhost.lan/tm.js">
var websiteId = 'XXXXX';
</script>
</body></html>
Here is my code:
<script type="text/javascript" src="http://counterhost.lan/tm.js">
var page = _gat.init('new');
</script>
and this is my JS file:
(function() {
var z = '_gat';
var aa = function init(data) { alert(data); alert(z);};
function na() {
return new z.aa();
}
na();
})();
I tried to understand Google Analytics javascript code but I failed to do this. Can anyone suggest how can I specify variable between tags and then read it in anonymous function which is located in a javascript file ?
Thanks.
In your example, websiteId is a global variable. So it is accessible everywhere including anonymous functions unless there is a local variable with the same name
<script> var websiteId = "something"; </script>
Later in the page or included js file...
(function() {
alert(websiteId); //this should work
})();
Can anyone suggest how can I specify variable between tags and then read it [...]
Not if your tag has both a SRC attribute and JS content.
<script type="text/javascript" src="http:/x.com/x.js"></script>
.. is different from,
<script type="text/javascript">
var x = 1;
</script>
One framework that optionally adds JS variables to SCRIPT tags is Dojo. So if you're using Dojo you can add variables to the global djConfig hash by writing,
<script type="text/javascript" src="mxclientsystem/dojo/dojo.js"
djConfig="
usePlainJson: true,
parseOnLoad: true
">
</script>
Dojo does this by running through the SCRIPT tags and evaluating the custom djConfig attribute.
This does not, however solve your problem.
You do really want two SCRIPT tags. One saying,
<script type="text/javascript">
var websiteId = '123456';
</script>
which will set a global variable websiteId and a second one,
<script type="text/javascript" src="http:/x.com/myreporter.js"></script>
which can load from anywhere and read out the websiteId variable and, I assume, report it back.
You can pass variables to an anonymous function like so:
(function(arg1, arg2, arg3) {
alert(arg1);
alert(arg2);
alert(arg3);
})("let's", "go", "redsox");
// will alert "let's", then "go", then "redsox" :)
I'm not entirely clear about what you're asking, but...
You can tag any HTML element with an id attribute, then use
document.getEntityById() to retrieve that specific element.
You can also give any HTML element user-defined attributes having names of your own choosing, then get and set them for that element within Javascript.
I think you've got a bit confused with how JS objects are called.
z is a String, '_gat'. You can't call aa() on it because a String has no member called aa. aa is a standalone function stored in a local variable. Even if you did call aa(), it doesn't return anything, so using the new operator on its results is meaningless. new can only be called on constructor-functions.
I guess you mean something like:
var _gat= function() {
// Private variable
//
var data= null;
// Object to put in window._gat
//
return {
// Set the private variable
//
init: function(d) {
data= d;
}
};
}();
Then calling _gat.init('foo') as in your second example would set the variable to website ID 'foo'. This works because the _gat object is the return {init: function() {...}} object defined inside the anonymous function, keeping a reference (a ‘closure’) on the hidden data variable.
If you specify a src attribute as part of a script element, any code within the script element tags themselves will not be executed. However, you can add this functionality with the following code. I got this technique from Crockford (I believe it was him), where he uses it in of his talks on the unrelated topic of rendering performance and asynchronously loading scripts into a page to that end.
JavaScript:
(function() {
// Using inner class example from bobince's answer
var _gat = (function() {
var data= null;
return {
init: function(d) {
console.info("Configuration data: ", d);
data = d;
}
}
})();
// Method 1: Extract configuration by ID (SEE FOOT NOTE)
var config = document.getElementById("my-counter-apps-unique-and-long-to-avoid-collision-id").innerHTML;
// Method 2: search all script tags for the script with the expected name
var scripts = document.getElementsByTagName("script");
for ( var i=0, l=scripts.length; i<l; ++i ) {
if ( scripts[i].src = "some-script.js" ) {
config = scripts[i].innerHTML;
break;
}
}
_gat.init( eval("(" +config+ ")") );
})();
HTML:
<script type="text/javascript" src="some-script.js" id="my-counter-apps-unique-and-long-to-avoid-collision-id">
{some: "foo", config: "bar", settings: 123}
</script>
Both methods have their draw backs:
Using a unique and non-colliding ID will make determining the proper script element more precise and faster; however, this is not valid HTML4/XHTML markup. In HTML5, you can define arbitrary attributes, so it wont be an issue at that time
This method is valid HTML markup; however, the simple comparison that I have shown can be easily broken if your url is subject to change (e.g.: http vs https) and a more robust comparison method may be in order
A note on eval
Both methods make use of eval. The typical mantra concerning this feature is that "eval is evil." However, that goes with say that using eval without knowing the dangers of eval is evil.
In this case, AFAIK, the data contained within the script tags is not subject to inject attack since the eval'ing script (the code shown) is executed as soon as that element is reached when parsing the HTML into the DOM. Scripts that may have been defined previously are unable to access the data contained within the counter's script tags as that node does not exist in the DOM tree at the point when they are executed.
It may be the case that a well timed setTimeout executed from a previously included script may be able to run at the time between the counter's script's inclusion and the time of the eval; however, this may or may not be the case, and if possible, may not be so consistently depending on CPU load, etc.
Moral of the story, if you're worried about it, include a non-eval'ing JSON parser and use that instead.