Difficulty in understanding javascript coding - javascript

i'm facing difficulty in understanding what this following code does. could anyone here please help me out in understanding this piece of code?
var PnPResponsiveApp = PnPResponsiveApp || {};
PnPResponsiveApp.responsivizeSettings = function () {
// return if no longer on Settings page
if (window.location.href.indexOf('/settings.aspx') < 0) return;
// find the Settings root element, or wait if not available yet
var settingsRoot = $(".ms-siteSettings-root");
if (!settingsRoot.length) {
setTimeout(PnPResponsiveApp.responsivizeSettings, 100);
return;
}
}

var PnPResponsiveApp = PnPResponsiveApp || {};
The above line ensures that the PnPResponsiveApp variable gets its old value if it already exists, otherwise it's set to a new object.
PnPResponsiveApp.responsivizeSettings = function () {
Here, a new function is created.
// return if no longer on Settings page
if (window.location.href.indexOf('/settings.aspx') < 0) return;
If the URL of the current page isn't the settings page, then the function exits immediately.
// find the Settings root element, or wait if not available yet
var settingsRoot = $(".ms-siteSettings-root");
This gets all elements with a class of .ms-siteSettings-root.
if (!settingsRoot.length) {
setTimeout(PnPResponsiveApp.responsivizeSettings, 100);
return;
}
If any elements were found (if the length of the node list is not zero), then call the PnPResponsiveApp.responsivizeSettings function in 100 milliseconds.

Very easy code basically, I'll explain what's going on:
var PnPResponsiveApp = PnPResponsiveApp || {};
This is very common way to see if the variable is already defined and if not, avoid throwing error and equal it to an empty object, It's used in many frameworks and library, very safe way to check if the var is there already... look at here for more info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators
PnPResponsiveApp.responsivizeSettings = function () {};
This is basically a simple function but attached to the object PnPResponsiveApp - if just responsivizeSettings = function () {}; it's attached to window Object
if (window.location.href.indexOf('/settings.aspx') < 0) return;
this is Checking if the Link in the linkbar has settings.aspx - indexOf return -1 if it doesn't contain the string, so if it's not settings.aspx it returns -1 that's smaller than 0 and then the whole function return ... the second return basically return undefined
var settingsRoot = $(".ms-siteSettings-root");
This is basically look for all element with class of ms-siteSettings-root and equal them to variable settingsRoot, it could be a single DOM or multiple...
if (!settingsRoot.length) {
and this basically check if any DOM element has ms-siteSettings-root class, length return a Number, so if it's not there, it returns 0, if there is return 1,2,3 etc... and 0 is equal to False in JavaScript and bigger than 0 is equal to True, so this way we can check if it's there...
setTimeout(PnPResponsiveApp.responsivizeSettings, 100);
so if the settingsRoot is there, we execute this function block and with setTimeout we wait 100ms... setTimeout always works in this manner, setTimeout(function(), time); and the same return happens at the end...
Hope it's informative enough...

Related

How can I return a value from function with multiple nested functions in Javascript?

The problem: I want to call a value from a nested method outside of its parent method. In other words, I want the output from "console.log(someObjects[i].valueChecker);" to be either "true" or "false." However, it is just returning the function itself.
What I've done so far: So I have been scouring the web/stack overflow for a solution, but either I haven't found a solution, or I just can't make sense of it. I think it has something to do with "closures," and most of the solutions to problems I've seen have been to return from the submethod, and then return the submethod from the parent method. However, every time I've tried this, I've just encountered numerous errors-- either another submethod suddenly doesn't exist, or the code runs, but the output is still a function. I wonder if having multiple methods affects the issue.
Context: I'm making a platformer game, and there are multiple types of the same enemy. I want to check for collision between the player and weapon and thusly need some values from the enemy function (I don't want to use the word "class," but I'm not sure about the appropriate terminology). I'm much more familiar with Java though, so it is frustrating me to not be able to create a separate class and just have a method to give me values back.
//assume all the other html/main stuff is already set up
var temp = {
create: c4,
update: u4
}
MyObject = function(value) {
this.value = value; //passed in value
var magicNumber = 4; //local value initialized/declared
this.valueChecker = function() {
//return boolean
return this.value == this.magicNumber;
}
this.otherValueChecker = function() {
//return boolean
return (this.value + 1) == this.magicNumber;
}
}
//just make the space bar tied to a boolean
var someKeyPress;
function c4() {
someKeyPress = game.input.keyboard.addKey(Phaser.Keyboard.A);
}
var someObjects = [];
//... later on in the program, presuming key already coded
function u4() {
//add a new MyObject to array someObjects
if (someKeyPress.isDown) {
//check with various random numbers between 3 to 5
someObjects.push(new MyObject(game.rnd.integerInRange(3, 5)));
}
//run through MyObject(s) added to someObjects, and see if any match number
for (var i = 0; i < someObjects.length; i++) {
console.log(someObjects[i].valueChecker);
}
}
/* current output
ƒ () {
//return boolean
return this.value == this.magicNumber;
}
*/
Try
console.log(someObjects[i].valueChecker())
Because I see the value checker as a function
this.valueChecker = function()

Avoiding multiple load of javascript file

I add this snippet to each javascript file used in my asp.net web api application to avoid multiple load :
Fullcalendar.js
blog = {};
blog.comments = blog.comments || {};
blog.comments.debugMode = false;
blog.isFirstLoad = function (namesp, jsFile) {
var isFirst = namesp.jsFile.firstLoad === undefined;
namesp.jsFile.firstLoad = false;
return isFirst;
};
$(document).ready(function () {
if (!blog.isFirstLoad(blog.comments, "fullcalendar.js")) {
return;
}
});
Sometimes I get a weird exception
Uncaught TypeError: Cannot read property 'firstLoad' of undefined
I need to know :
Why this happens?
How can I fix it?
A couple of problems there.
First, you shouldn't be loading the file more than once in the first place, so it shouldn't be necessary to go through this business of trying to figure out whether you've loaded it.
But if you want to do that:
The first practical issue is that you're always doing this:
blog = {};
...which means if there's already a blog global, you're wiping out its value and replacing it with an empty object. If you want to use an existing global's value or create a new one, do this:
var blog = blog || {};
That seems odd, but since repeated var declarations are fine (and don't change the variable), that will use an existing one's value, or if there isn't one (or its value is falsey) it will create a new one and initialize it with {}.
Then, the line
namesp.jsFile.firstLoad = false;
...looks for a property called jsFile on namesp and assumes it's not null or undefined. It doesn't look for a property using the jsFile argument's value.
To do that, use brackets notation:
namesp[jsFile].firstLoad = false;
Even then, though, you're assuming it's not null or undefined, but it may well be. You probably just wanted:
namesp[jsFile] = false;
Or possibly:
namesp[jsFile] = namesp[jsFile] ||{};
namesp[jsFile].firstLoad = false;
That said, it seems really odd to use blog.comments to track whether JavaScript files have been loaded. If the file may have already been loaded, just this will do it:
var fullCalendarLoaded;
if (fullCalendarLoaded) {
// It's already loaded
} else {
// It isn't, but it is now
fullCalendarLoaded = true;
// ...do your init...
}
Or if you have several of these and want to use a single global for it:
var loadedScripts = loadedScripts || {};
if (loadedScripts.fullCalendar) {
// Already loaded
} else {
// Not loaded yet
loadedScripts.fullCalendar = true;
// ...do init...
}
Or if using the filename is important:
var loadedScripts = loadedScripts || {};
function firstLoad(filename) {
if (loadedScripts[filename[) {
return false;
}
// Not loaded yet, remember we've loaded it now
loadedScripts[filename] = true;
return true;
}
Then:
if (firstLoad("fullcalendar.js")) {
// First load, do init...
}
It's fairly straightforward:
On your initial run, you define
blog = {};
blog.comments = blog.comments || {};
blog.comments.debugMode = false;
In theory, this means that on some loads, blog is:
var blog = {
comments: {
debugMode: false
}
}
You then pass blog.comments into your function isFirstLoad as the namesp parameter. In that function, you do the evaluation:
namesp.jsFile.firstLoad === undefined;
Well, you never defined the jsFile property of blog.comments. This means it is undefined. Trying to access the property firstLoad of an undefined variable will give you your error
Uncaught TypeError: Cannot read property 'firstLoad' of undefined

How do you iterate over the list of bodies from Box2D in emscripten?

I'm using the emscripten port of Box2D from here: https://github.com/kripken/box2d.js
It's working great, but I'm have some trouble interacting with emscripten.
Specifically I'm perform model-display sync in a loop like this:
function step() {
world.Step(1/60);
var body = this.world.GetBodyList();
while(body != null) {
readGeometry(body, body.data);
body = body.GetNext();
}
}
...but that doesn't seem to work. Although the C++ code returns NULL at the end of the linked list of body objects, body.GetNext() (return type in cpp is b2Body *) is never the native javascript null.
I've also tried:
body != Box2D.NULL
However, that is also never true. I'm guessing that emscripten is returning a wrapped pointer, and I have to do some specific operation on it to test for 'nullness'.
Inspecting the returned object I can see that the 'pointer' value in it for the null values is zero, and I can make it work with:
function step() {
world.Step(1/60);
var body = this.world.GetBodyList();
while(body.a != 0) { // <--------------- This hack
readGeometry(body, body.data);
body = body.GetNext();
}
}
So, it's clearly possible to test for NULL-ness, but I can't find any documentation on how to do it.
Try this
function step() {
world.Step(1/60);
var body = this.world.GetBodyList();
while(Box2D.getPointer(body)) { // <-- will equal 0 for a Box2D.NULL object
readGeometry(body, body.data);
body = body.GetNext();
}
}
I know this question is really old but I recently came across this problem and found the solution on github.
The accepted answer didn't work, but this did :
var next = World.m_bodyList;
var current;
while (next != null) {
current = next; next = next.m_next;
if(current.m_userData){
var current_body = {};
current_body.x = current.m_xf.position.x;
current_body.y = current.m_xf.position.y
}
}

Self-created fadeIn() function not working correctly

I am trying to create the fadeIn() function using Javascript. I am having trouble, when I click the fadeIn button, it does not perform a fadeIn animation, instead I have to click it several times to fadeIn. Would anyone know how I can fix this issue?
jsFiddle
// Created a jQuery like reference
function $(selector) {
if (!(this instanceof $)) return new $(selector); // if new object is not defined, return new object
this.selector = selector; // setting selector attribute
this.node = document.querySelector(this.selector); // finds single element from the DOM
};
var fInFrom = 0, fOutFrom = 10;
$.prototype.fadeIn = function() {
var target = this.node,
newSetting = fInFrom / 10;
// Set Default styles for opacity
target.style.display = 'block';
target.style.opacity = newSetting;
// fadeInFrom will increment by 1
fInFrom++;
var loopTimer = setTimeout('this.fadeIn', 50);
if (fInFrom === 10) {
target.style.opacity = 1;
clearTimeout(loopTimer);
fInFrom = 0;
return false;
}
return this;
}
$('#fadeIn').node.addEventListener('click', function() {
$('#box').fadeIn();
});
This line is your problem:
setTimeout('this.fadeIn', 50)
That will set a timeout to evaluate the expression this.fadeIn in the global scope in approximately 50 milliseconds from the current time. There's two problems with that:
It's in the global scope; this is window, not an instance of $, so this.fadeIn is undefined.
Even if it were resolved correctly, you're only evaluating this.fadeIn; you're not calling it. You would need to use this.fadeIn() for it to do anything. (If you do that with the current code, this will reveal your first problem.)
To solve this, pass not a string but a function that does what you want it to do. You might naïvely do this:
setTimeout(function() {
this.fadeIn();
}, 50);
Unfortunately, while we now have lexical scoping for variables, this in JavaScript is dynamic; we have to work around that. Since we do have lexical scoping for variables, we can utilize that: [try it]
var me = this; // store the current value of this in a variable
var loopTimer = setTimeout(function() {
me.fadeIn();
}, 50);
After that's solved, you might want to look into:
Not using global variables to hold the fade state. Even after that fix, running two fade animations at once on different elements won't work as expected. (Try it.)
Only setting the timeout if you need to; right now, you always set it and then clear it if you don't need it. You might want to only set it if you need it in the first place.

implementing namespace function javascript

I'm implementing Stoyan Stefanov's javascript namespace function as I have been reading his very informative JavaScript Patterns book; in my web application but not sure if I'm using it the proper way
here is the funciton implementation i'm using on my web app on this page http://dalydd.com/projects/module_example/
var COOP = COOP || {};
COOP.namespace = function (ns_string) {
var parts = ns_string.split('.'),
parent = COOP,
i;
// strip redundant leading global
if (parts[0] === "COOP") {
parts = parts.slice(1);
}
for (i = 0; i < parts.length; i += 1) {
// create a property if it doesn't exist
if (typeof parent[parts[i]] === "undefined") {
parent[parts[i]] = {};
}
parent = parent[parts[i]];
}
return parent;
};
COOP.namespace('sliderContainer')
COOP.sliderContainer = function () {
return slider = ($('#slider').length > 0) ? $('#slider') : $('#element_temp');
} // we need this at the beginning as others are dependent on it and call it initially
my goal is to check every new property of COOP to see if it exists before it's implemented --- so if I create a property of COOP called COOP.sliderContainer - I want to make sure COOP.sliderContainer does not exist already. when I use the namespace function it returns an object but COOP.sliderContainer is a function. I feel like I have to do an extra layer of abstraction in order to name this namespace function work properly like
var sliderContainer = COOP.namespace('sliderContainer');
sliderContainer.sliderContainer = function () {
return slider = ($('#slider').length > 0) ? $('#slider') : $('#element_temp');
}
this seems silly and redundant to me - is there a better way to do this?
any info is appreciated as always - the page has a direct link to the js file on it
namespace function is useful when create sub namespaces inside COOP, it will help to avoid multiple checkings. For example you want to create COOP.module.module1, you have to make 2 checks to see if module and module 1 are not defined or not.
However, in this case, sliderContainer is just a property of COOP. There's no need to use namespace. You just simply check it yourself:
if(COOP.sliderContainer === undefined){
// define it
}
EDIT
You can have a function handle that for you:
COOP.createProperty = function(name, prop){
if(COOP[name] === undefined){
COOP[name] = prop;
}
}
then
COOP.createProperty("sliderContainer", function(){
// do whatever you want
});

Categories

Resources