I'm trying to build a polyfill for getting the actual scrollposition.
function getScLPos() {
if (self.pageXOffset) return self.pageXOffset;
if (document.documentElement && document.documentElement.scrollLeft)
return document.documentElement.scrollLeft;
if (document.body.scrollLeft) return document.body.scrollLeft;
return 0;
}
But as it goes through the same condition checking procedure every function call.
I wanted to optimize the function by assigning a function reference to a global variable when it is called for the first time. Afterwards it reads the global variable (containing the funtion) and executes the function, but actually it doesnt work. When i call getScLPos() it still returns a function.
How ca I make getScLPos return an integer value?
Edit: typeof pageXOffset() says "function".
var getScLCallback = null;
function getScLPos() {
if (getScLCallback != null) {
return getScLCallback();
} else {
if (self.pageXOffset) {
getScLCallback = pageXOffset;
//says "function() {...}"
console.log(getScLCallback());
return getScLCallback();
} else if { ... }
} else {
return 0;
}
}
}
function pageXOffset() {
return self.pageXOffset;
}
Yes, function references exist in JavaScript. Functions are just objects. The thing you are doing wrong is you are assigning the result of the function to the variable, instead of assigning the function itself. To assign a function to a variable, simply use the function name, without the () at the end.
So, instead of:
getScLCallback = docScrollLeft();
do this:
getScLCallback = docScrollLeft;
Here is your updated code:
var getScLCallback = null;
function getScLPos() {
if (getScLCallback != null) {
return getScLCallback();
} else {
if (self.pageXOffset) {
// REMOVED the parentheses
getScLCallback = pageXOffset;
//says "function() {...}"
console.log(getScLCallback());
return getScLCallback();
} else if (document.documentElement && document.documentElement.scrollLeft) {
// REMOVED the parentheses
getScLCallback = docScrollLeft;
return getScLCallback();
} else if (document.body.scrollLeft) {
// REMOVED the parentheses
getScLCallback = bodyScrollLeft;
return getScLCallback();
} else {
return 0;
}
}
}
function pageXOffset() {
return self.pageXOffset;
}
function docScrollLeft() {
return document.documentElement.scrollLeft;
}
function bodyScrollLeft() {
return document.body.scrollLeft;
}
I actually made it work by renaming the pageXOffset function to pXOffset.
pageXOffset actually interfered with self.pageXOffset
Related
I was trying to call another function inside function iseven(n):
function iseven(n) {
function remainder(n) {
if (n%2==0) {
return true;
} else {
return false;
}
}
}
console.log(iseven(4));
It returns undefined.
a right way to do this:
function a(x) { // <-- function
function b(y) { // <-- inner function
return x + y; // <-- use variables from outer scope
}
return b; // <-- you can even return a function.
}
console.log(a(3)(4));
nested functions JS
You want something more like this
function iseven(n) {
if (n%2==0) {
return true; }
else {
return false;
}
}
console.log(iseven(4));
And something a bit more succinct:
function isEven(n) {
return n % 2 === 0;
}
Not quite sure why the original was structure that way..
Try
function iseven(n) { return n % 2 === 0; }
Your Main function iseven() does not return anything. Based on your code it should return false. Here's the fix:
function iseven(n) {
function remainder(n) {
if (n%2==0) {
return true;
}
else {
return false;
}
}
//iseven() should return something
return false;
}
console.log(iseven(4));
My question is, if I have a function like this
function f(a) {
if (a == undefined) {
alert(1)
return f
} else {
alert(2)
}
}
and I call it like this, for example, f()()()()('123'), how can I keep track of how many times f was called?
Edit:
I had a play around and worked out a solution:
function f(a) {
if (!f.count) {
f.count = 0;
}
if (a == undefined) {
alert(1);
++f.count;
return f;
} else {
f.count = 0;
alert(2);
}
}
alert(1) and alert(2) are essentially placeholders for the moment. The count variable would be used in the else section in the actual function.
Thank you all for your help.
Rather than pollute the global space, attach the counter to the function itself.
function f(a)
{
++f.counter;
if (a) {
doAThing();
return f;
} else
doAnotherThing();
}
f.counter = 0;
Now you can access the number of calls by evaluating f.counter at any point.
Just create a count variable outside of the function scope and whenever you enter the function, you increase its value.
var count = 0;
function f(a) {
count++;
if (!a) {
alert(1);
return f;
} else {
alert(2);
}
}
By "wrapper function) do you mean "closure"?
var f = (function (a) {
var count = 0;
return function () {
console.log(count);
count += 1;
if (!a) {
alert(1);
return f;
} else {
alert(2);
}
}
})();
I'm trying to build a function in JS that has a return composed of different nested functions based on a parameter passed by the user.
function addA(otherFunction)
{
//gets the result from some base function and modifies it
//e.g. +1
}
function addB(otherFunction)
{
//does the same thing as addA, except different values. Consider it a variation of addA.
//eg. -1
}
function constr(input)
{
//based on the chars in input, we will recursively select a new function to be applied.
//the value of this function should be a function
if (...) return addA(constr(shorterInput))
if (*last char) return addA
if (*last char) return addB
if (...) return addB(constr(shorterInput))
}
So far, my script is recognizing addA and and addB as functions. But when it strings two functions together, for example
addB(addA)
The type becomes undefined. Can anybody let me know why it does not register as a function and/or the proper way to return nested functions. Thanks!
Edit: Here is the real code:
function cons(a,b)
{
return function (selector) {
return selector(a,b);
};
}
function a(list)
{
function aHelper(a,b)
{
return a
}
return list(aHelper);
}
function d(list)
{
function dHelper(a,b)
{
return b
}
return list(dHelper);
}
function abc(input)
{
if (input.length==0 || input==null) return null;
var x=input.charAt(input.length-1);
if (x==='a')
{
if (input.length>1)
{
var z=a(abc(input.substr(0,input.length-1)));
return z;
}
return a;
}
if (x==='d')
{
if (input.length>1)
{
var z=d(abc(input.substr(0,input.length-1)));
return z;
}
return d;
}
}
function show(list) {
var sval;
if (list == null) return '()';
else if (typeof list!='string')
{
sval = '(' + show(a(list)) + ' ' + show(d(list)) + ')';
}
else
{
sval=list;
}
return sval;
}
var func=abc('ad');
var func2=abc('a');
var list=cons('a',cons('b','c'));
console.log(typeof func);
console.log(typeof func2);
console.log(typeof list);
console.log(typeof func2(list));
console.log(typeof func(list));
Your function abc is supposed to return a function that can process lists, like a or d. However, you match that signature only in 2 out of 7 cases:
return a, return d are fine
return null - that's not a callable value
z = d(…); return z does return a list
z = a(…); return a does return an element of the list (of whatever type)
d(abc(…)) and a(abc(…)) use abc as if it would return a list
A correct implementation would look like this:
function abc(directions) {
if (directions.length == 0) {
return function id(list) { return list; }; // a function that does nothing
}
var f = directions[0] == 'a' ? car : cdr; // ignoring other values, you might also throw an error
var processRest = abc(input.slice(1));
return function(list) { // make a function to process a list
var z = f(list); // do the current operation
return processRest(z); // do the rest of operations
};
}
Or even better/shorter with the help of higher-order function composition:
function id(x) { return x; }
function compose(f, g) {
if (f == id) return g;
if (g == id) return f;
return function(x) { return f(g(x)); };
}
function abc(dirs) {
return !dirs.length ? id : compose(abc(dirs.slice(1)), dirs[0]=='a'?car:cdr);
}
I'm trying to use the following workaround for the hidden iframe/getComputedSytle firefox bug 548397.
if (/firefox/i.test(navigator.userAgent)){
window.oldGetComputedStyle = window.getComputedStyle;
window.getComputedStyle = function (element, pseudoElt) {
var t = window.oldGetComputedStyle(element, pseudoElt);
if (t === null) {
return {};
} else{
return t;
}
};
}
However in my case I also need getComputedSytle.getPropertyValue i.e. I get the following error:
TypeError: my_window.getComputedStyle(...).getPropertyValue is not a function
How can I add getPropertyValue to the above workaround?
You can just create an empty function:
if (/firefox/i.test(navigator.userAgent)){
window.oldGetComputedStyle = window.getComputedStyle;
window.getComputedStyle = function (element, pseudoElt) {
var t = window.oldGetComputedStyle(element, pseudoElt);
if (t === null) {
return {
getPropertyValue: function(){}
};
} else{
return t;
}
};
}
I think a better solution would be this one
function setFirefoxPolyfill() {
if (/firefox/i.test(navigator.userAgent)){
window.oldGetComputedStyle = window .getComputedStyle;
window.getComputedStyle = function (element, pseudoElt) {
var t = window.oldGetComputedStyle(element, pseudoElt);
if (t === null) {
return element.style;
} else{
return t;
}
};
}
}
in case of null response you just return element styles with all prototyped methods and fields
var a, kdApi;
a = (function() {
function a() {}
a.prototype.b = function() {
return "foo";
};
return a;
})();
kdApi = (function() {
function kdApi(className, funcName) {
if (typeof [className] !== "undefined" && ([className] != null)) {
eval("cu= new " + className + "()");
if (cu[funcName]) {
console.log("class and function exists");
} else {
console.log("class does, function doesn't");
}
} else {
console.log("both class and function doesn't.");
}
}
return kdApi;
})();
new kdApi("w", "b");
When I run this, I want to get both class and function doesn't exist message but instead I get w is not defined error. What am I doing wrong? Also, can I do it without eval?
var a, kdApi;
a = (function() {
function a() {}
a.prototype.c = 1;
a.prototype.b = function() {
return "foo";
};
return a;
})();
kdApi = (function() {
function kdApi(className, funcName) {
if (className != null && className in window) {
if (funcName != null && funcName in window[className].prototype &&
typeof window[className].prototype[funcName] == "function") {
document.write("class and function exists");
} else {
document.write("class does, function doesn't");
}
} else {
document.write("both class and function doesn't.");
}
}
return kdApi;
})();
function testCF(clazz, func) {
document.write("test for " + clazz + "." + func + "(): ");
new kdApi(clazz, func);
document.write("<br/>");
}
testCF("a", "b");
testCF("a", "c");
testCF("k", "b");
testCF("k", "c");
testCF(null, "c");
testCF("a", null);
Live demo: http://jsbin.com/ufubi5/5
Tested under Chrome 10.0.642.2 dev
The standard way of seeing it a function exists in JavaScript is to test if it is in the current scope. Hence the idiom:
if (funcName) {
funcName();
}
I believe there is something similar to see if it is a constructor function, but I'm not sure.