What does the method clog() do? - javascript

I am trying to learn url persistence, and a friend told me to study this block of code:
$(document).ready(function(){
var objects = {};
var DEFAULT_LOCATION = "diameter";
$("#animateObjects").hide();
var urlDimension = location.hash.replace("#","");
if (urlDimension.length == 0) {
// location.hash = "#" + DEFAULT_LOCATION;
urlDimension = DEFAULT_LOCATION;
$("#"+DEFAULT_LOCATION).addClass("active");
clog("started with no dimension, defaulted to " + DEFAULT_LOCATION);
}
else {
$("#"+urlDimension).toggleClass("active");
clog("started with dimension: " + urlDimension);
}
What does the clog() method accomplish?
Full code is here.

I'd bet its a wrapper around console.log to cater for IE not being able to handle it.
something like this:
function clog(message) {
try {
console.log('message');
}
catch (ex) {}
}
Reference: http://benwong.me/javascript-console-log-and-internet-explorer/

Related

JQuery Pass Parameter as Vars in 2 functions returns undefined

I have the following code and I dont know why it is returning trackingIds[i] as undefined in the View and Click function... I want to fill an array and the code should go through each array index and checks if element is hovered or clicked. el_id and trackingIds[i] in the first function return the correct values. I would appreciate any help because I cant seem to figure this out.
jQuery(document).ready(function(){
var trackingIds = ["elementid"];
for(i=0; i<trackingIds.length; i++){
var el_id = jQuery('#'+trackingIds[i]);
console.log(el_id);
console.log(trackingIds[i]);
el_id.click(function() { Click(trackingIds[i]);});
el_id.mouseover(function() { View(trackingIds[i]);});
}
});
function Click(a) {
//do stuff...
console.log("Click was called from:"+a);
}
function View(b){
// do stuff..
console.log("View was called from:"+b)
}
You need to use let in your for-loop.
jQuery(document).ready(function() {
var trackingIds = ["elementid"];
for (let i = 0; i < trackingIds.length; i++) {
var el_id = jQuery('#' + trackingIds[i]);
//console.log(el_id);
//console.log(trackingIds[i]);
el_id.click(function() {
Click(trackingIds[i]);
});
el_id.mouseover(function() {
View(trackingIds[i]);
});
}
});
function Click(a) {
//do stuff...
console.log("Click was called from: " + a);
}
function View(b) {
// do stuff..
console.log("View was called from: " + b)
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1 id='elementid'>Click me!</h1>
Resource
let
The let statement declares a block scope local variable, optionally initializing it to a value.

Accesing function within function JavaScript

I got this piece of code below which is not DRY. What i want to do is to cut it,so everything below var = text would be used only once not twice.
My concept is,to close these two functions in bigger function (e.g. guess()) and keep trimmed correctGuess() and incorrectGuess() within it.
Now here's the question,how can I call such nested function as describe above from outside scope. I was thinking about smth like: guess().correctGuess() which is obviously wrong but I wanted to share a concept.
Additionally, when e.g. correctGuess() would be called, is rest of the commands within our main guess() function would be executed?
function correctGuess(i) {
totalScore++;
questionNumber++;
var text = "Correct!";
var updatePage = ['<div id="answerDiv">' +
'<h1>' + text + '<h1>' +
'<h2>Total Score: ' + totalScore + '</h2></div>'
];
mainContent[html](updatePage);
$('#answerDiv')[fadeIn]("slow");
$('#answerDiv').append('<button id="nextButton">Next Question</button>');
$('#nextButton').on('click', function() {
if (questionNumber == allQuestions.length && totalScore <= 4) {
results()
} else {
question(questionNumber)
}
})
};
var incorrectGuess = function(i) {
totalScore--;
questionNumber++;
var text = "Wrong!";
var updatePage = ['<div id="answerDiv">' +
'<h1>' + text + '<h1>' +
'<h2>Total Score: ' + totalScore + '</h2></div>'
];
mainContent[html](updatePage);
$('#answerDiv')[fadeIn]("slow");
$('#answerDiv').append('<button id="nextButton">Next Question</button>');
$('#nextButton').on('click', function() {
if (questionNumber == allQuestions.length && totalScore <= 4) {
results();
} else {
question(questionNumber);
}
});
};
http://www.w3schools.com/js/js_objects.asp
From your question it seems like you aren't very familiar with object notation. Read up on the above link and then try to create a js "guess" object with 2 member functions. Correct and Incorrect guess.
You need to use the this keyword.
function guess(){
/* do stuff here for guess() */
this.correct = function(){
/* Do stuff for correct */
}
this.wrong = function(){
/* Do stuff for wrong */
}
return this;
}
Because you returned this you can now access the correct() and wrong() functions using:
guess().correct();
// AND
guess().wrong();
Note that whatever code you write inside guess() and outside the two nested functions will also be called every time you call guess().correct() or guess().wrong()
If you do not want any particular code to execute every time they "guess" regardless of right or wrong then I would suggest just storing the correct() and wrong() functions in an object literal.
var guess = {
correct: function(){
// Code for "correct" here
},
wrong: function(){
// Code for "wrong" here
}
}
And then you can access them using
guess.correct();
// AND
guess.wrong();

Callback at the end of all the functions contained in one function

I find myself stuck for some days on a callback issue, and I can't find any convenient solution. Here is the problem:
I have some jQuery that looks like that
$(document).ready(function(){
masterFunction_A();
masterFunction_B();
});
function masterFunction_A() {
littleFunction_1();
littleFunction_2();
littleFunction_3();
littleFunction_4();
// etc...
}
function masterFunction_B() {
// do stuff
}
I would like to start executing masterFunction_B() when all littleFunctions() are done. When I try to set masterFunction_B() as a callback for masterFunction_A(), it seems that it is launched when masterFunction_A() has launched all the littleFunctions(), but not when littleFunctions() are over...
I tried to:
Set a timer, and launch masterFunction_B() at the end of that timer but... that's not a proper way to to it
Set callbacks in all the littleFunctions and a counter that counts until the right amount of callbacks are called, but I think there is a better and cleaner way to get what I want.
Can you help ?
Thanks a lot!
—— EDIT ——
This is the content of masterFunction_A(), actually called loadContents() :
function loadContents () {
$.getJSON('data/data.json', function(data) {
for (var i = 0 ; i < data.length ; i++) {
$(".projects_ordered_list").append("<!-- PROJECT " + i + " -->");
$(".projects_ordered_list").append("<li id='projects_ordered_list_item_" + i + "'></li>");
}
for (var i = 0 ; i < data.length ; i++) {
$("#projects_ordered_list_item_" + i).load('projects.html', function() {
var this_html_id = $(this).attr("id");
var this_id = this_html_id.substr(this_html_id.length - 1);
this__display_id = this_id;
this__display_id++;
$(this).find(".project_id").css("background", data[this_id].color);
$(this).find(".project_id_title").html(this__display_id + ".");
$(this).find(".project_name").html(data[this_id].name.en);
$(this).find(".project_date").html(" — " + data[this_id].date.en);
for (var j = 0 ; j < data[this_id].imgs.length ; j++) {
$(this).find(".bxslider").append("<li><img src='" + data[this_id].imgs[j] + "'></li>");
}
});
}
});
}
Using jQuery deferreds which are built into jQuery ajax functions, you can make it all work like this.
First, make each of your littleFunction_x() code look like this:
function littleFunction_1() {
var d = $.getJSON(...)
// other code
return d;
}
Then, you can do this:
$(document).ready(function(){
$.when(masterFunction_A()).done(masterFunction_B);
});
function masterFunction_A() {
var d = $.Deferred();
$.when(littleFunction_1(),
littleFunction_2(),
littleFunction_3(),
littleFunction_4()
).done(function() {
d.resolve();
});
return d;
}
After thinking about it a bit more, I think you can also do a slightly cleaner version like this:
$(document).ready(function(){
masterFunction_A().done(masterFunction_B);
});
function masterFunction_A() {
return $.when(littleFunction_1(),
littleFunction_2(),
littleFunction_3(),
littleFunction_4()
);
}
Take a look at the jQuery Deferred feature. I think it's exactly what you need.
first, create a Deferred for each littleFunction:
dfd1 = $.Deferred();
dfd2 = $.Deferred();
dfd3 = $.Deferred();
dfd4 = $.Deferred();
in each littleFunction, resolve the Deferred at the end:
function littleFunction1() {
...
dfd1.resolve();
}
...
when all Deferreds are resolved, start executing master_Function_B:
$.when(dfd1, dfd2, dfd3, dfd4).then(masterFunction_B);

Deep nesting functions in JavaScript

I cannot find an proper example for the love of my life on how to do this or even if this is possible. Based on my pieced together understanding from fragments of exmaples, I have come up with the following structure
var t = function()
{
this.nestedOne = function()
{
this.nest = function()
{
alert("here");
}
}
}
t.nestedOne.nest();
However this is not working (obviously). I would greatly appreciate if someone could point me in the right direction!
That is simply done with:
var t = {
nestedOne: {
nest: function() {
alert('here');
}
}
};
Your code otherwise doesn't make sense. this inside function doesn't refer to the function itself, it refers to the object context that the function is invoked in. And you are not even invoking the functions in your code.
If I say obj.func() then this inside func will be obj for that call. So assigning this.asd = true will assign true to that object's "asd" property.
If you wanted to do a nested class, it looks very different:
ClassA = (function() {
function ClassA() {
}
ClassA.prototype.method1 = function() {
};
function ClassB() {
}
ClassB.prototype.method1 = function() {
};
return ClassA;
}())
only ClassA can now make instances of ClassB. This should achieve same goals as nested classes in java.
See http://jsfiddle.net/CstUH/
function t(){
function f(){
this.nest = function()
{
alert("here");
}
}
this.nestedOne = new f();
}
var myt=new t();
myt.nestedOne.nest()
Edit 1:
You can also use
new t().nestedOne.nest()
instead of
var myt=new t();
myt.nestedOne.nest()
(http://jsfiddle.net/CstUH/1/)
Edit 2:
Or even more condensed:
function t(){
this.nestedOne = new function(){
this.nest = function(){
alert("here");
}
}
}
new t().nestedOne.nest()
http://jsfiddle.net/CstUH/2/
In JS functions are prime class objects, and you can access them directly in the code [i.e. without using reflection or so].
The code you put inside t body would be performed when actually executing t:
t();
You wrote t.nestedOne,nest(), but t has no nestedOne property - you should do like this:
var t = {
nestedOne : {
nest : function()
{
alert("here");
}
}
};
t.nestedOne.nest(); ​
I advice you to have a trip on John Resig's Learning Advanced JavaScript tutorial, it was very enlightening for me.
A simple callback handler I wrote today as an example of how I do deep nesting. I apologize if it's not the bees knees when it comes to code style, it made the concept a little clearer for me.
function test () {
this.that = this;
this.root = this;
this.jCallback = new Array(new Array()); // 2d
this.jCallbackCount = -1;
this.str = "hello";
// Callback handler...
this.command = {
that : this, // let's keep a reference to who's above us on the food chain
root : this.root, // takes us back to the main object
// add : function() { var that = this; console.log(that.that.str); },
add : function(targetFnc, newFunc) {
var that = this;
var home = that.that; // pretty much root but left in as an example of chain traversal.
var root = this.root; // useful for climbing back up the function chain
// console.log(that.that.str);
home.jCallbackCount++;
// target, addon, active
home.jCallback[home.jCallback.length] = { 'targetFunc' : targetFnc, 'newFunc' : newFunc, 'active' : true, 'id': home.jCallbackCount};
console.log('cbacklength: ' + home.jCallback.length);
console.log('added callback targetFunction:[' + targetFnc + ']');
return home.jCallbackCount; // if we want to delete this later...
},
run : function(targetFnc) {
var that = this;
var home = that.that;
console.log('running callback check for: ' + targetFnc + ' There is : ' + (home.jCallbackCount + 1) + 'in queue.');
console.log('length of callbacks is ' + home.jCallback.length);
for(i=0;i < home.jCallback.length - 1;i++)
{
console.log('checking array for a matching callback [' + targetFnc + ']...');
console.log('current item: ' + home.jCallback[i]['targetFunc'] );
if( home.jCallback[i]['targetFunc'] == targetFnc )
{
// matched!
home.jCallback[i]['newFunc']();
}
// console.log(that.that.jCallback[i].targetFunction);
}
}
};
}
test.prototype = {
say : function () {
var that = this;
console.log('inside');
// that.command('doSay');
that.command.run('doSay');
console.log(that.str);
}
} // end proto
// BEGIN TESTING **************************************************************************
// BEGIN TESTING **************************************************************************
// BEGIN TESTING **************************************************************************
var testing = new test();
testing.command.add('doSay', function () { console.log('213123123'); } );
testing.command.add('doSay', function () { console.log('12sad31'); } );
testing.command.add('doSay', function () { console.log('asdascccc'); } );
testing.say();
live:
http://jsfiddle.net/Ps5Uf/
note: to view console output, just open inspector in chrome and click on the "console" tab.

How to write this JavaScript code without eval?

How to write this JavaScript code without eval?
var typeOfString = eval("typeof " + that.modules[modName].varName);
if (typeOfString !== "undefined") {
doSomething();
}
The point is that the name of the var that I want to check for is in a string.
Maybe it is simple but I don't know how.
Edit: Thank you for the very interesting answers so far. I will follow your suggestions and integrate this into my code and do some testing and report. Could take a while.
Edit2: I had another look at the could and maybe itis better I show you a bigger picture. I am greatful for the experts to explain so beautiful, it is better with more code:
MYNAMESPACE.Loader = ( function() {
function C() {
this.modules = {};
this.required = {};
this.waitCount = 0;
this.appendUrl = '';
this.docHead = document.getElementsByTagName('head')[0];
}
function insert() {
var that = this;
//insert all script tags to the head now!
//loop over all modules:
for (var modName in this.required) {
if(this.required.hasOwnProperty(modName)){
if (this.required[modName] === 'required') {
this.required[modName] = 'loading';
this.waitCount = this.waitCount + 1;
this.insertModule(modName);
}
}
}
//now poll until everything is loaded or
//until timout
this.intervalId = 0;
var checkFunction = function() {
if (that.waitCount === 0) {
clearInterval(that.intervalId);
that.onSuccess();
return;
}
for (var modName in that.required) {
if(that.required.hasOwnProperty(modName)){
if (that.required[modName] === 'loading') {
var typeOfString = eval("typeof " + that.modules[modName].varName);
if (typeOfString !== "undefined") {
//module is loaded!
that.required[modName] = 'ok';
that.waitCount = that.waitCount - 1;
if (that.waitCount === 0) {
clearInterval(that.intervalId);
that.onSuccess();
return;
}
}
}
}
}
};
//execute the function twice a second to check if all is loaded:
this.intervalId = setInterval(checkFunction, 500);
//further execution will be in checkFunction,
//so nothing left to do here
}
C.prototype.insert = insert;
//there are more functions here...
return C;
}());
var myLoader = new MYNAMESPACE.Loader();
//some more lines here...
myLoader.insert();
Edit3:
I am planning to put this in the global namespace in variable MYNAMESPACE.loadCheck, for simplicity, so the result would be, combining from the different answers and comments:
if (MYNAMESPACE.loadCheck.modules[modName].varName in window) {
doSomething();
}
Of course I will have to update the Loader class where ever "varName" is mentioned.
in JS every variable is a property, if you have no idea whose property it is, it's a window property, so I suppose, in your case, this could work:
var typeOFString = typeof window[that.modules[modName].varName]
if (typeOFString !== "undefined") {
doSomething();
}
Since you are only testing for the existence of the item, you can use in rather than typeof.
So for global variables as per ZJR's answer, you can look for them on the window object:
if (that.modules[modName].varName in window) {
...
}
If you need to look for local variables there's no way to do that without eval. But this would be a sign of a serious misdesign further up the line.

Categories