Thursday, 7 April 2016

Document object in javascript - introduction

Here is the html code that has been used in the javascript code on this page.

<article id="article1" class="my_new_class">
    <h3>
        Demonstrating how to get an element fron an html document in javascript
    </h3>
    <p>
        This is paragraph one.
    </p>
    <p>
        This is paragraph two.
    </p>
    <p class="new_point">
        This is paragraph three.
    </p>
    <p class="new_point">
        This is paragraph four.
    </p>
</article>

Here is the javascript code that uses the html code above.

var element = document.getElementById('article1');
console.log(element);//We get the element in the document that has id=article1
var elements = document.getElementsByTagName('p');
console.log(elements);//We get an array of all the elements that has a tag of p i.e., paragraph
var element = document.getElementsByTagName('h3');
console.log(element);//We get an array of all the elements with heading set to h3
var elements = document.getElementsByClassName('new_point');
console.log(elements);//We get an array of our two paragraph elements with class=new_point

//***************************************************************************
/* 
Once we get an element from a document then we can get access to any of its attributes also. 
*/
var e = document.getElementById('article1');
console.log(e.getAttribute('class'));//my_new_class

//We can dynamically set an attribute also. 
e.setAttribute('class', 'my_old_class');
console.log(e.getAttribute('class'));//my_old_class

//We can get all the child nodes of an element.
console.log(e.childNodes); /* We get on the console
[text, h3, text, p, text, p, text, p.new_point, text, p.new_point, text]
the array has text 6 times because we have spaces before the h3, and all the paragraph elements and white space is represented as text. */

The location object in javascript

/* 
The location object lets us look at the browser's URL location. 
*/

console.log(location.href); // https://fiddle.jshell.net/_display/

console.log(location.host); //fiddle.jshell.net

console.log(location.port); //port number

console.log(location.protocol); // https:


//redirecting to another page/website but it depends on your browsing settings.
location.assign('https://www.google.com');//directs browser tot he page passed as argument.

System Dialogs in javascript - alert, confirm, and prompt

//System dialogs
//1. alert
alert('Hello jsfiddle.net');


//2. confirm - with ok and cancel button ok button for the if is true case and cancel button for the else case 
if(confirm('Do you want to leave this page?')){
 console.log('You chose to leave the page.');
}
else{
 console.log('You chose to stay on the page.');
}

//3. prompt - with an ok and a cancel button
var input = prompt('Enter Your address please!');
if(input != null && input != '')
 console.log(input);
else
{
 console.log('You did not enter any address');
}

timer in javascript

//Timer related code snippets in js
console.log(new Date().getSeconds()); //e.g., 49 seconds
/* function setTimeout() is a global object window and we do not need to prefix it with window.*/
setTimeout(function() {
  console.log(new Date().getSeconds());
 }, 1000
);/* 1000 milliseconds of delay should be observed before calling the function setTimeout after the internal function has been called. */
/* I got 
6
7
because there were 6 seconds in to the minute and then it was 7 seconds into the minute. Note that the 7 appears after an 
interval of 1 second after the 6 appears on the console. If I delete the ', 1000' then I will 
instead get
6
6
as no delay is being observed. 
*/

//*******************************************************
console.log(new Date().getSeconds());
/* Assigning the id of the timer to a variable so that we use that id later on to clear the timer and prevent it from being activated. */
var id = setTimeout(function(){
  console.log(new Date().getSeconds());
 }, 1000
);
clearTimeout(id);
/* After executing the code above we get only one number as our timer is prevented being activated by the clearTimeout() method.
*/
//*******************************************************
/* In the code snippet given below we pass a funciton to method setInterval() and that internal function will be called over and 
over again untill the if condition is true and it is then when the function clearInterval(id) will be called to stop calling the 
internal function.
*/
console.log(new Date().getSeconds());
var id = setInterval(function(){
  var seconds = new Date().getSeconds();
        console.log(seconds);
        if(seconds === 30)//shutting down the timer when there are 30 seconds into the minute
         clearInterval(id);//id exists in the outer function.
 }, 1000
);
//*******************************************************


Window object in javascript

console.log(window.screenLeft + ', ' + window.screenTop);//0,0 but depends on where the window is positioned on your screen
/* innerWidth is where your html document is showing. The brower ususall has some kind of frame and that is included in the outer width. */
console.log(window.innerWidth + ', ' + window.outerWidth);//100, 1280 
window.open('http://www.google.com', '_blank');/*Popup might be blocked so you will not get a new window but might get an indication that a poping up window has been blocked.*/

Recursive functions in javacript - an introduction

//Recursion in javascript 
//functions
/* Making a json object that uses anonymous function instead of a named funciton
which causes problem in a scenario in which we make another variable ftn2 to 
point to the same function ftn by assigning ftn2 to ftn. Then we set ftn to null
and we lose our reference to the recrusive call to ftn inside the funciton ftn. 
If we use a named function then the problem gets solved and recursion works. 
*/
var orgChart = {
    name: 'Dilshad',
    subordinates: [{
        name: 'Rafaqat',
        subordinates: [{
            name: 'Sardar',
            subordinates: []
        }, {
            name: 'Shaukat',
            subordinates: []
        }]
    }]
};
//Writing an anonymous function that uses recursion.
var ftn = function(topEmployee) {
    console.log(topEmployee.name);
    console.log('Number of subordinates of ' + topEmployee.name + ': ' + topEmployee.subordinates.length);
    /* 
      Calling itself recrusively for each employee to check it s(he) has subordinates. 
      */
    for (var i = 0; i < topEmployee.subordinates.length; i++){
     console.log(topEmployee.name + "'s subordinate # " + (i + 1) + ": ");
        //Recursive call to ftn in the line below.
        ftn(topEmployee.subordinates[i]);
    }
};
//calling the funciton ftn and passing it the json object representing the organization chart.
//**********************************
//ftn(orgChart);
//**********************************
/*
Here is the output of the function above:
Dilshad
Number of subordinates of Dilshad: 1
Dilshad's subordinate # 1: 
Rafaqat
Number of subordinates of Rafaqat: 2
Rafaqat's subordinate # 1: 
Sardar
Number of subordinates of Sardar: 0
Rafaqat's subordinate # 2: 
Shaukat
Number of subordinates of Shaukat: 0
*/
//The problem with the anonymous function above starts when we do the following two lines.
//**********************************
//var ftn2 = ftn;
//ftn = null;
//ftn2(orgChart);
//**********************************
/*
We get an error after the first top employee of the organization chart as shown as the recursive call fails because we have set ftn to null and we are still calling it in the recrusive call inside the body of the function. 

Dilshad
Number of subordinates of Dilshad: 1
Dilshad's subordinate # 1: 
Uncaught TypeError: ftn is not a function
*/
/*
 The solution is simple - use a named function instead of an anonymous funciton as shown below:
*/

//Writing a named function that uses recursion.
var ftn = function showAllEmployees(topEmployee) {
    console.log(topEmployee.name);
    console.log('Number of subordinates of ' + topEmployee.name + ': ' + topEmployee.subordinates.length);
    /* 
      Calling itself recrusively for each employee to check it s(he) has subordinates. 
      */
    for (var i = 0; i < topEmployee.subordinates.length; i++){
     console.log(topEmployee.name + "'s subordinate # " + (i + 1) + ": ");
        //Recursive call to ftn in the line below.
        showAllEmployees(topEmployee.subordinates[i]);
    }
};

/* Now the code works even if we do the following. */
var ftn2 = ftn;
ftn = null;
ftn2(orgChart);
/* But don't forget to comment the lines above which were causing errors. The lines between 
//********************************** and //**********************************
 should be commented
*/



Here is the output on the console:

Dilshad
Number of subordinates of Dilshad: 1
Dilshad's subordinate # 1: 
Rafaqat
Number of subordinates of Rafaqat: 2
Rafaqat's subordinate # 1: 
Sardar
Number of subordinates of Sardar: 0
Rafaqat's subordinate # 2: 
Shaukat
Number of subordinates of Shaukat: 0

Immediately invoked function expressions (IIFEs)

//IIFEs - Immediately invoked function expressions
//IIFEs don't pollute the global environment.
(function(){
 console.log('Executed!');
})();
//*************************************************************
/* We can move the last pair of parenthesis () before the semicolon inside the parenthesis containing hte whole function. This works the same way as the
code snippet given above. 
*/
(function(){
 console.log('Executed again!');
}());
//*************************************************************
//IIFEs don't pollute the global environment.
(function(){
 var employeeName = 'Jack';
})();
/* The linew of code below will give error as employeeName has been declared
with keyword var inside the function so it does not pollute the global 
namespace. Its scope is limited to the function only. */

/* console.log(employeeName);//Uncaught ReferenceError: employeeName is not defined
*/
//*************************************************************
/* app in the code below is an object that is empty here but in a real
app it will be populated. Most of the libraries in js has
a global variable e.g., $ in jQuery. An application has often a variable
in the global namespace called app. */
var app = {};
(function (ns) {
 ns.name = 'None';
})(app);//Passing the global variable app as an argument to the IIFE function.
console.log(app.name);//None
//*************************************************************
var app = {};
var jQuery = {};
/* The way we pass jQuery as a second argument to the IIFE guarantees that
the jQuery === $ (the dollar sign). */
(function (ns, $) {
 ns.name = 'None';
  console.log($ === jQuery);//true
})(app, jQuery);
//*************************************************************
/* To make sure that the system's undefined object is set to the undefined 
object we do as given below: */
var app = {};
var jQuery = {};
(function (ns, $, undefined) {
 ns.name = 'None';
  console.log(undefined);//undefined
})(app, jQuery);
//*************************************************************
//We can also use +, -, or ! with the keyword function instead of parentheses
+function(){
 var employeeName = 'Jack';
  console.log('Executed!');//Executed
}();
console.log(employeeName);//Uncaught ReferenceError: employeeName is not defined.
//*************************************************************