Hi I just can't figure this one out.
I need to use the window["evaluate string into js object"] because I am converting a web Application into a ChromeOS Chrome app and they do not let you use eval() to do their content security policy.
My problem is that for basic varibles it is fine, example:
var a = "foo";
var b = window["a"];
This will put "foo" into b no problem. But as soon as I have an object (both global or local) it doesn't work, so if 'a' was an object the code would like something like this:
a.test = "foo";
var b = window["a.test"];
That will not work.
Is there a reason for this? I can't seem to find much info on window[] in general so wondering if anyway has any insight or at least can point me in the right direction to look.
Thanks
window[] doesn't work on namespaced functions, so if you try to evaluate window['a.test'] it would fail. A proper alternative is to use window['a']['test']. In case you're indefinite of number namespaced objects you're going to use, you can create a simple function that would split the string from . and create a window object for each part. Example :
var str = 'namespace.service.function';
var parts = str.split(".");
for (var i = 0, len = parts.length, obj = window; i < len; ++i) {
obj = obj[parts[i]];
}
console.log(obj);
Related
I use a lot of the following expressions in my code:
document.
.getElementsBy...
.querySelector...
I need to save characters without using any libraries. That can be done by
var d = document;
Then, instead of document. I can write d. now.
I am wondering if there is a simple way to do the same thing for methods
.getElementsBy... and .querySelector....
Since these have a variable term, I cannot put the entire thing into a
variable, like var q = .querySelector(".class"), because the .class
changes almost every time.
You can create functions to avoid adding properties to the document object as shortcut if you don't want to.
function gEBI(d,id)
{
return d.getElementById(id);
}
function qS(d,s)
{
return d.querySelector(s);
}
var d = document;
var ele1 = gEBI(d,"yourID");
var ele2 = qS(d,".class");
You can make your own shortcut functions-references manually.
document.gEBI = document.getElementById;
document.gEBI(id);
But it's not a good practice to make such shortcuts.
This is the Google RankTracker found here
<script>
if (document.referrer.match(/google\.com/gi) && document.referrer.match(/cd/gi)) {
var myString = document.referrer;
var r = myString.match(/cd=(.*?)&/);
var rank = parseInt(r[1]);
var kw = myString.match(/q=(.*?)&/);
if (kw[1].length > 0) {
var keyWord = decodeURI(kw[1]);
} else {
keyWord = "(not provided)";
}
var p = document.location.pathname;
ga('send', 'event', 'RankTracker', keyWord, p, rank, {'nonInteraction': 1});
dataLayer.push({'eventCategory':'RankTracker','eventAction':keyWord,'eventLabel':p,'eventValue':rank 'event':'RankTracker'});
}
</script>
I'm trying to get this working with Google Tag Manager, (the dataLayer.push({... section at the bottom), but I'm not sure the variables are working (although they work with the Universal Analytics ga('send'...) portion
Should calling the variables as I have done work in this case?
My main concern is the lack of single quotes around the values
BTW, if anyone is wondering I have set up macros in GTM for eventCategory, etc., and my rule for firing is that event is equal to RankTracker
Should calling the variables as I have done work in this case?
My main concern is the lack of single quotes around the values
Assuming you mean the keyword, p, and rank values used on the right-hand side of the : in a property initializer, those are used correctly and do not need quotes.
Here's a simpler example:
var foo = "testing";
var obj = {prop: foo};
console.log(obj.prop); // "testing"
I don't know much about Google RankTracker, but I do know you need a comma between those these two key/value pairs.
'eventValue':rank 'event':'RankTracker'
should be
'eventValue':rank, 'event':'RankTracker'
Maybe that's what's causing unexpected results.
We can create an array in a couple of ways:
var myArray = new Array();
Or:
var myArray = [];
The second way is safer to use than the new Array() syntax, because the Array constructor can be overwritten and potentially replaced with malicious code.
I have seen above lines in many JavaScript books but I don't understand how an Array constructor can be overwritten and replaced with malicious code? I'm looking for an example of how someone can do it, so that I can understand the reality of the issue.
Somewhere in the code above:
Array.prototype.forEach = function (e){
console.log("something wrong there");
return(e);
};
Somewhere in the code below:
var i = [1,2,3,4,5];
i.forEach(function(e){
console.log(e);
});
Output:
>"something wrong there"
As you can see, there is no difference how to initialize array variable. var i = []; just shorter notation.
If you write on your JS console :
[1,2,3]
(just like that) - you can do nothing with it.
Well that's not accurate with old browsers.
You could overload the array ctor by :
Array = new function (){... }
and so , when you got your friend list via Json ( not jsonp) : -
someone could use an XSS/XSF attack and steal your friends list.
The thing ere is the fact that : if you write [1,2,3] - there is actually a ctor working here.
So if you got to a website which does array response - he could still your list.
I need to pass a jQuery object in to a workaround for an eval. The issue is that i need access to a jQuery object that is out side the eval area but i can't see to pass it in. here is what i have.
var jObj = $(selector);
var myCode = "var jObj="+jObj+"; var i="+i+"; "+shape.mouseover.onEnd.replace("\u0027","'");
var myFucn = new Function(myCode);
myFucn();
the oject I'm getting the string out of is
shape.mouseover.onEnd.replace("\u0027","'");
is working and what I'm passing in that string is
open_info(jObj,i)
Which is what i have to fire. The deal is that the code is run thru YUI compressor so the jObj var becomes something else so i need to pass that in. Right now i get an error where it thinks it should have and ending ] which is not right. I is working it seems, just not the jObj var.
EDIT
there are many way to get where i need to be that are close but not quite like
How to pass parameters in eval in an object form?
shape.mouseover.onEnd = "open_info(jObj,i)";
/*
* this is coming in and must be as it is, don't say it's wrong please
* it's not able to be done anyother way!
*/
//lets process the string and pull in the vars
/* BEOFRE YUI COMPRESSOR CHANGES THINGS and works!!!
var jObj = $(selector);
var i = 1;
var myCode = shape.style.events.mouseover.onEnd.replace("\u0027","'");
var myFucn = new Function(myCode);
myFucn();
*/
// AFTER note it can be random as i change code so it fails cause
// var jObj is now var r and var i is now var e
var r = $(selector);
var e = 1;
var p= shape.style.events.mouseover.onEnd.replace("\u0027","'");
var f= new Function(p);
f();
Now it works before the compression.. After is not due to the change. Hope tha tclears it up some
I might be going down the wrong tracks and be confused here..
But isnt this what your trying to do?
Send myFucn the correct object and what ever i is
myFucn($(selector),10);
function myFucn(jObj,i)
{
shape.mouseover.onEnd.replace("\u0027","'");
}
I still don't understand why this question got 2 down votes, but well it's solved and works great. The trick is to do the same manipulation of the dom state. It's really simple once it is placed out.
//so this is what the object is parsed out to from the json string
//since you can't just pass a function stright that way any how
shape.mouseover.onEnd = "open_info(jObj,i)";
//this is what will take that string and process it
//note jObj is what is in the orgain code but it changes to
// var r or something else that is shorter after going thru YUI compressor
// Which is why we can't just use open_info(jObj,i) and it work..
// ie: it's not an issue with scoope but an issues with var names being shortened
(function(){
//this is the trick on passing them so YUI doesn't get them
//use a string and YUI skips it so we directly create the
//needed oject in the window namespace
window['jObj']=jObj; window['i']=i;
var p= shape.mouseover.onEnd;
var f= new Function(p);
f();
})();
That is it.. I put it in a click or hover event so it's kin to an onClick.
/* EXMAPLE OUTPUT AFTER YUI COMPRESSION
//Note after the YUI compressor get ahold of that
//processing code above it'll look like
*/
function(){window.jObj=n,window.i=t;var u=i.mouseover.onEnd,r=new Function(u);r()}();
So the way that works is, I needed to fix the issue of the var jObj being renamed. So I simply made a sting for the name and let the compressed the var name fill the name of the object I need for the processed code string. Don’t know why I didn’t see it before and I would have saved my rep value :-\ .. oh well. May be a way to shorten this but I'm leaving it for now.
Edit
I recant the edit it was working. :) Very well.. Left wondering what any other ways there would be to make it do the same thing.
I'm trying to set properties of some elements through a for loop, but am confused about the implementation.
Here is the code:
var fiArray = new Array('name','address','address2','phone','fax','misc1','misc2');
function disableFields(){
for(i=0,x=fiArray.length; i < x; i++){
var disEl = "$('formID')."+fiArray[i];
disEl.disabled=true;
}
}
I've tried every permutation of changing the disEl var, not using a var, concatenating different parts of the disEl string; nothing seems to work.
I know I'm missing something simple and fundamental here...
p.s. using prototype
var disEl = $('formID')[fiArray[i]];