9 Replies - 9912 Views - Last Post: 19 November 2010 - 01:09 AM

#1 macosxnerd101  Icon User is offline

  • Self-Trained Economist
  • member icon




Reputation: 10803
  • View blog
  • Posts: 40,257
  • Joined: 27-December 08

Week #35- JavaScript

Post icon  Posted 03 November 2010 - 08:25 AM

This week's challenge is Javascript. Thanks to Munawwar for creating this challenge!

Javascript
The w3schools introduction to Javascript is as follows:

Quote

Javascript is THE scripting language of the Web.
Javascript is used in millions of Web pages to add functionality, validate forms, detect browsers, and much more.

Javascript is easy to learn and a great language for people who are new to programming.

Tools
The minimum tools you require to write Javascript, is a text editor (such as Notepad, Notepad++ or Programmer's notepad) and a browser.
OR you can pick an IDE :
Aptana Studio - my personal favorite for Javascript
Netbeans

Before you continue, find the Javascript error console on your browser.
Internet Explorer 8: Tools->Developer Tools-> 'scripts' tab
FireFox: Tools->Error Console. I recommend firefox users to get Firebug too.
Chrome: Wrench Icon->Tools->Javascript console
Opera: Menu->Page->Developer Tools->Error console
Safari: ?? Can't find it!

Learning
1) Javascript Tutorial and references at w3schools
2) Javascript guide, reference and a lot more at Mozilla Developer Center for Javascript
3) Another Javascript reference at javascriptkit.com. And also useful snippets here
4) Object-Oriented Javascript Part 1 and Part 2.
5) Video lecture on Javascript from Harvard.
6) PromoteJS.com

Javascript, many a times, is used along with other technologies like AJAX, JSON and server side technologies like PHP,ASP,JSP or Python.

Resources and Libraries
Making Javascript components can bring hours of fun, but when it comes to professional Javascript development, it is difficult to get anything done without using frameworks.Which brings us to the interesting part of Javascript.

1) YUI Library - YUI 2 and YUI 3. : Professional Javascript framework from Yahoo! Corp.
JQuery
MooTools
Dojo ToolKit
scriptaculous
DHTMLX
You mat look at a list of popular Javascript frameworks at wikipedia.

2) Use Java to generate Javascript with Google Web ToolKit (GWT) or Rhino.

3) Google Maps API

Other Resources
1) JSLint - Javascript syntax checker and validator.

2) Code compressors/minifiers:
YUI Compressor (Here's an online YUI compressor)
Dojo Compressor.

3) Found a set of videos here

4) As you use a lot of Javascript components, you will realize web page loading times might increase considerably - either due to extra download time or slow scripts that require lots of processing.
To achieve faster page loading, read the following (You will find few conflicting opinions :)):
http://betterexplain...ript-load-time/
http://thinkvitamin....avascript-fast/
http://developer.yah...h_performanc_8/
http://developer.yah...ance/rules.html

Future of Javascript
Read the HTML5 presentation at html5rocks.com.Note that you will need a HTML5 compatible browser.

This post has been edited by macosxnerd101: 03 November 2010 - 12:40 PM
Reason for edit:: Added PromoteJS Link thanks to BrianArn!


Is This A Good Question/Topic? 0
  • +

Replies To: Week #35- JavaScript

#2 brianarn  Icon User is offline

  • New D.I.C Head

Reputation: 11
  • View blog
  • Posts: 27
  • Joined: 02-October 09

Re: Week #35- JavaScript

Posted 03 November 2010 - 08:41 AM

For what it's worth, many in the JS community (myself included) feel that W3schools is an awful resource for JS documentation. Sure, some of the basics are there, but it's rather dated and hasn't been updated in a long time. Check out PromoteJS.com to get a banner to put on your site, to help improve the search rankings of the Mozilla Developer Center docs, which are widely regarded as the most authoritative and updated documents on Javascript. :)

This post has been edited by brianarn: 03 November 2010 - 08:42 AM

Was This Post Helpful? 3
  • +
  • -

#3 skyhawk133  Icon User is offline

  • Head DIC Head
  • member icon

Reputation: 1877
  • View blog
  • Posts: 20,284
  • Joined: 17-March 01

Re: Week #35- JavaScript

Posted 03 November 2010 - 08:45 AM

Good info Brian. Thanks!
Was This Post Helpful? 0
  • +
  • -

#4 brianarn  Icon User is offline

  • New D.I.C Head

Reputation: 11
  • View blog
  • Posts: 27
  • Joined: 02-October 09

Re: Week #35- JavaScript

Posted 03 November 2010 - 09:05 AM

If you wish to use the Safari Web Inspector, the access process is a bit more involved, but that's just because Safari kind of... hides all Developer tools at first.

Open up the Safari Preferences (cmd+, on a Mac, not sure on PC). Select the Advanced tab at the top. The bottom option under there is a checkbox that says "Show Develop menu in menu bar". Make sure that's checked.

Once you have that checked, you have an entirely new menu, which offers up the Web Inspector (which is the same toolset that Chrome uses, as they're both based on WebKit), and also offers a few features that Chrome doesn't (such as User Agent spoofing or disabling of caches/images/styles/JS/etc).

This post has been edited by brianarn: 03 November 2010 - 09:06 AM

Was This Post Helpful? 2
  • +
  • -

#5 Brewer  Icon User is offline

  • Awesome
  • member icon

Reputation: 179
  • View blog
  • Posts: 1,044
  • Joined: 14-June 10

Re: Week #35- JavaScript

Posted 03 November 2010 - 09:07 AM

After seeing the post in the Advisor's forum, I am interested in making something for this week. I just don't know what to make!
Was This Post Helpful? 0
  • +
  • -

#6 Munawwar  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 162
  • View blog
  • Posts: 457
  • Joined: 20-January 10

Re: Week #35- JavaScript

Posted 03 November 2010 - 11:40 AM

View Postbrianarn, on 03 November 2010 - 07:05 PM, said:

Open up the Safari Preferences (cmd+, on a Mac, not sure on PC). Select the Advanced tab at the top. The bottom option under there is a checkbox that says "Show Develop menu in menu bar". Make sure that's checked.

Thanks for the information. Hopefully, macosxnerd101 will update the post.
Was This Post Helpful? 0
  • +
  • -

#7 Munawwar  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 162
  • View blog
  • Posts: 457
  • Joined: 20-January 10

Re: Week #35- JavaScript

Posted 03 November 2010 - 12:30 PM

Recently, I was writing a motion animation script that mimics JQuery and Flash. It uses CSS properties like JQuery, but adds an extra argument to use various motion easing functions - like Flash's motion tweening. Here's the code :beta1: :
<html>
	<head>
		<script type="text/javascript">
			function returnNumber(str) {
				if(typeof str=='number')
					return str;
				return parseFloat(str.match(/[0-9]*\056?[0-9]*/i)[0]);
			}
			
			function animate(_arguments,_cssProp) { //cssProp should only have in pixel values
				if(typeof animate.queue=='undefined')
					animate.queue=[];
				animate.queue.push([_arguments,_cssProp]);
				if(animate.queue.length==1)
					new animateClass(animate.queue[0][0],animate.queue[0][1]);
				
				function animateClass(arguments,cssProp) {
					var self=this;
					
					self.cssProp=cssProp;
					self.element=arguments['element']; //Mandatory
					self.totalTime=arguments['totalTime']?arguments['totalTime']:800; //Time in ms
					self.fps=arguments['fps']?arguments['fps']:50; //Frames per second
					self.effect=arguments['effect']?arguments['effect']:animate.easeInOut.sinusoidal; //Frames per second
					
					self.frameDuration=Math.round(1000/self.fps);
					self.frames=(self.totalTime*self.fps)/1000; //Default 100
					self.timeElapsed=0;
					
					self.initValue=new Array(),self.deltaValue=new Array();
					var prop;
					for(prop in self.cssProp)
						if(typeof self.element.style[prop]!=='undefined') {
							self.initValue[prop]=returnNumber(self.element.style[prop]);
							self.deltaValue[prop]=(self.cssProp[prop]-self.initValue[prop]); //Difference between final and initial value
						}
					
					self.callback = function() {
						self.timeElapsed+=self.frameDuration;
						if(self.timeElapsed<=self.totalTime) {
							var prop;
							for(prop in self.deltaValue) {
								self.element.style[prop]=self.effect(self,prop);
								if(prop=='opacity' && self.element.filters && self.element.filters.alpha) //IE opacity fix
									self.element.filters.alpha.opacity=self.element.style[prop]*100;
							}
							setTimeout(self.callback,''+self.frameDuration);
						}
						else {
							//for(prop in self.deltaValue)
								//self.element.style[prop]=self.cssProp[prop];
							animate.queue.shift();
							if(animate.queue.length>0)
								new animateClass(animate.queue[0][0],animate.queue[0][1]);
						}
					}
					//First call
					setTimeout(self.callback,'0');
				}
			}
			//Animation algorithms
			//Linear motion
			animate.uniform = function(self,prop) {
				return self.initValue[prop]+((self.deltaValue[prop]*self.timeElapsed)/self.totalTime);
			}
			
			animate.easeInOut=new Object();
			animate.easeInOut.sinusoidal = function(self,prop) {
				var degree=180; //Constant
				/*(value in degrees) x PI/180 */
				/*1 + cos value to make value positive.But value will be between 0 to 2. So divide by 2 to get value from 0 to 1 */
				return self.initValue[prop]+(self.deltaValue[prop]*(1+Math.cos(((180+((self.timeElapsed*degree)/self.totalTime))*Math.PI)/180)) / 2);
			}
			animate.easeInOut.quadratic = function(self,prop) {
				var t=self.timeElapsed/(self.totalTime/2);
				if (t < 1) return self.initValue[prop]+((self.deltaValue[prop]*t*t)/2);
				t--;
				return self.initValue[prop]+((-self.deltaValue[prop]*((t*(t-2)) - 1))/2);
			}
			animate.easeInOut.cubic = function(self,prop) {
				var t=self.timeElapsed/(self.totalTime/2);
				if (t < 1) return self.initValue[prop]+((self.deltaValue[prop]*t*t*t)/2);
				t-=2;
				return self.initValue[prop]+((self.deltaValue[prop]*(t*t*t + 2))/2);
			}
			
			animate.easeOut=new Object();
			animate.easeOut.sinusoidal = function(self,prop) {
				var degree=90; //Constant
				return self.initValue[prop]+(self.deltaValue[prop]*Math.sin((((self.timeElapsed*degree)/self.totalTime)*Math.PI)/180));
			}
			animate.easeOut.quadratic = function(self,prop) { //t square
				var t=self.timeElapsed/self.totalTime;
				return self.initValue[prop]+(-self.deltaValue[prop] * t*(t-2));
			}
			animate.easeOut.cubic = function(self,prop) { //t cube
				var t=(self.timeElapsed/self.totalTime)-1;
				return self.initValue[prop]+(self.deltaValue[prop]*(t*t*t + 1));
			}
			
			animate.easeIn=new Object();
			animate.easeIn.sinusoidal = function(self,prop) {
				var degree=90; //Constant
				return self.initValue[prop]+(self.deltaValue[prop]*(1+Math.cos(((180+((self.timeElapsed*degree)/self.totalTime))*Math.PI)/180)));
			}
			animate.easeIn.quadratic = function(self,prop) { //t square
				var t=self.timeElapsed/self.totalTime;
				return self.initValue[prop]+(self.deltaValue[prop]*t*t);
			}
			animate.easeIn.cubic = function(self,prop) {
				var t=self.timeElapsed/self.totalTime;
				return self.initValue[prop]+(self.deltaValue[prop]*t*t*t);
			}
		</script>
	</head>
	<body>
		<div id="debug" style="float:right; color:#000;"></div>
		<span id="test" style="position:absolute; left:0px; top:20px; width:100px; height:100px; background-color:#98BF21; opacity: 1; filter:alpha(opacity=100)"></span>
		<script type="text/javascript">
			animate({element: document.getElementById('test'), effect: animate.easeInOut.sinusoidal},{height: 300, opacity: 0.5});
			animate({element: document.getElementById('test')},{height: 100, width: 100, opacity: 1.0});
			animate({element: document.getElementById('test')},{width: 300, opacity: 0.5});
			animate({element: document.getElementById('test')},{width: 100, opacity: 1.0});
			
			animate({element: document.getElementById('test'), effect: animate.easeInOut.quadratic},{height: 300, opacity: 0.5});
			animate({element: document.getElementById('test'), effect: animate.easeInOut.quadratic},{height: 100, width: 100, opacity: 1.0});
			animate({element: document.getElementById('test'), effect: animate.easeInOut.quadratic},{width: 300, opacity: 0.5});
			animate({element: document.getElementById('test'), effect: animate.easeInOut.quadratic},{width: 100, opacity: 1.0});
			
			animate({element: document.getElementById('test'), effect: animate.easeInOut.cubic},{height: 300, opacity: 0.5});
			animate({element: document.getElementById('test'), effect: animate.easeInOut.cubic},{height: 100, width: 100, opacity: 1.0});
			animate({element: document.getElementById('test'), effect: animate.easeInOut.cubic},{width: 300, opacity: 0.5});
			animate({element: document.getElementById('test'), effect: animate.easeInOut.cubic},{width: 100, opacity: 1.0});
		</script>
		
	</body>
</html>


Was This Post Helpful? 1
  • +
  • -

#8 BetaWar  Icon User is offline

  • #include "soul.h"
  • member icon

Reputation: 1199
  • View blog
  • Posts: 7,304
  • Joined: 07-September 06

Re: Week #35- JavaScript

Posted 03 November 2010 - 06:27 PM

<!edited>

This is a modified version of a simple JS only calendar I developed a while back for a project:
<!DOCTYPE HTML>
<html>
	<head>
  	<script>
			DOM = {
				after: function(sibling, child){
					DOM.parent(sibling).insertBefore(child, DOM.next(sibling));
				},
				append: function(parent, child){
					parent.appendChild(child);
				},
				at: function(parent, index){
					var current = DOM.first(parent);
					if(index >= parent.childNodes.length){
						return DOM.last(parent);
					}
					var i = 0;
					while(i < index){
						current = DOM.next(current);
						if(String(current.appendData).substr(0, 9) !==  "function"){
							i++;
						}
					}
					return current;
				},
				before: function(sibling, child){
					DOM.parent(sibling).insertBefore(child, sibling);
				},
				clone: function(object){
					if(object){
						return object.cloneNode(true);
					}
					return null;
				},
				create: function(tagString){
					return document.createElement(tagString);
				},
				first: function(parent){
					var current = parent.firstChild;
					while(String(current.appendData).substr(0, 9) ===  "function"){
						current = DOM.next(current);
					}
					return current;
				},
				last: function(parent){
					var current = parent.lastChild;
					while(String(current.appendData).substr(0, 9) ===  "function"){
						current = DOM.previous(current);
					}
					return current;
				},
				next: function(sibling){
					return sibling.nextSibling;
				},
				parent: function(child){
					return child.parentNode;
				},
				prepend: function(parent, child){
					parent.insertBefore(child, DOM.first(parent));
				},
				previous: function(sibling){
					return sibling.previousSibling;
				},
				remove: function(object){
					DOM.parent(object).removeChild(object);
				},
				text: function(str){
					return document.createTextNode(str);
				}
			};
			var months = [{"name": "January", "days": 31}, {"name": "February", "days": 28}, {"name": "March", "days": 31}, {"name": "April", "days": 30}, {"name": "May", "days": 31}, {"name": "June", "days": 30}, {"name": "July", "days": 31}, {"name": "August", "days": 31}, {"name": "September", "days": 30}, {"name": "October", "days": 31}, {"name": "November", "days": 30}, {"name": "December", "days": 31}];
			var daysOfWeek = ["Su", "M", "T", "W", "Th", "F", "Sa"];
			function renderMonth(date){
				var holder = DOM.create("div");
				holder.className = "calendar";
				var tmp;
				var today = new Date();
				date = date || {"year": today.getFullYear(), "month": today.getMonth()};
				var cDate = new Date(date.year, date.month, 1);
				var year = cDate.getFullYear();
				var dow = cDate.getDay();
				var day = cDate.getDate();
				var month = cDate.getMonth();
				var daysThisMonth = months[month].days;
				var daysLastMonth = months[month==0?11:month-1].days;
				tmp = DOM.create("span");
				tmp.id="monthNameAndYear";
				tmp.className = "center block";
				DOM.append(tmp, DOM.text(months[month].name + " " + year));
				DOM.append(holder, tmp);
				var i;
				var rows = 1;
				for(i = 0; i < daysOfWeek.length; i++){
					tmp = DOM.create("span");
					tmp.className = "dayOfWeek";
					DOM.append(tmp, DOM.text(daysOfWeek[i]));
					DOM.append(holder, tmp);
				}
				DOM.append(holder, DOM.create("br"));
				for(i = 0; i < dow; i++){
					tmp = DOM.create("span");
					tmp.className = "day notThisMonth calendarDate";
					tmp.title = months[month==0?11:month-1].name + " " + (daysLastMonth-dow+i+1) + ", " + (month==0?year-1:year);
					DOM.append(tmp, DOM.text(daysLastMonth-dow+i+1));
					DOM.append(holder, tmp);
				}
				for(i = 1; i <= daysThisMonth; i++, dow++){
					if(dow > 6){
						dow = 0;
						rows++;
						DOM.append(holder, DOM.create("br"));
					}
					tmp = DOM.create("span");
					tmp.className = "day calendarDate";
					if(year == today.getFullYear() && month == today.getMonth() && i == today.getDate()){
						tmp.className += " today";
					}
					tmp.title = months[month].name + " " + i + ", " + year;
					DOM.append(tmp, DOM.text(i));
					DOM.append(holder, tmp);
				}
				for(i = 1; rows < 6 || dow < 7; i++, dow++){
					if(dow > 6){
						dow = 0;
						rows++;
						DOM.append(holder, DOM.create("br"));
					}
					tmp = DOM.create("span");
					tmp.className = "day notThisMonth calendarDate";
					tmp.title = months[month==11?0:month+1].name + " " + i + ", " + (month==11?year+1:year);
					DOM.append(tmp, DOM.text(i));
					DOM.append(holder, tmp);
				}
				return holder;
			}
			var cm = new Date().getMonth();
			var cy = new Date().getFullYear();
			function newMonth(direction){
				direction = direction || "+";
				if(direction == "+"){
					cm++;
					if(cm >= 12){
						cy++;
						cm = 0;
					}
				}
				else if(direction == "-"){
					cm--;
					if(cm < 0){
						cy--;
						cm = 11;
					}
				}
				else{
					var d = new Date();
					cy = d.getFullYear();
					cm = d.getMonth();
				}
				var calendar = document.getElementById("calendar");
				DOM.remove(DOM.first(calendar));
				DOM.append(calendar, renderMonth({"year": cy, "month": cm}));
			}
		</script>
    <style>
			.day{
				display: inline-block;
				text-align: center;
				width: 30px;
			}
			.notThisMonth{
				color: #cdcdcd;
			}
			.dayOfWeek{
				font-weight: bold;
				text-align: center;
				width: 30px;
				display: inline-block;
				border-bottom: 1px solid #000000;
			}
			.today{
				background: #ccffcc;
				border-radius: 30px;
			}
			.center{
				text-align: center;
			}
			.block{
				display: block;
			}
			.calendar{
				width: 210px;
			}
		</style>
  </head>
  <body onload="newMonth('now')">
  	<div id="calendar">Test</div>
    <div width="210px">
	    <input class="center" type="button" onclick="newMonth('-')" value="Previous"/>
  	  <input class="center" type="button" onclick="newMonth('now')" value="Today"/>
    	<input class="center" type="button" onclick="newMonth('+')" value="Next"/>
    </div>
  </body>
</html>


Works in IE9, Chrome, FF 3.6, Safari, and Opera.
Was This Post Helpful? 4
  • +
  • -

#9 Munawwar  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 162
  • View blog
  • Posts: 457
  • Joined: 20-January 10

Re: Week #35- JavaScript

Posted 04 November 2010 - 12:50 AM

BetaWar, I like the way you abstracted the DOM functions into a 'DOM' namespace.

Here's another script. I occasionally use a 'debug console' for displaying logs/debug messages without cluttering the screen.
<html>
	<head>
  	<script type="text/javascript">
		function debug_msgs()
		{
			this.line=0;
			this.clear=function() {
				var div=document.getElementById('debug');
				div.innerHTML='';
				this.line=0;
			}
			this.print=function(string) {
			var div=document.getElementById('debug');
				div.innerHTML+=string;
			}
			this.println=function(string) {
				var div=document.getElementById('debug');
				div.innerHTML+=string+'<br>';
				this.line++;
			}
		}
		var debug=new debug_msgs();
	</script>
	<style>
	.debug-box {
		position: fixed;
		right: 10px;
		top: 20px;
		height: 64px;
		width: 64px;
		border: 2px solid #d0d0d0;
		background-color: #f0f0f0;
	}
	.debug-box .debug-header {
		display: block;
		padding: 7px;
		background-color: #000;
		background-repeat:no-repeat;
		color: #202020;
		width: 50px;
		height: 50px;
	}
	.debug-box #debug {
		display: none;
	}
	div.debug-box:hover .debug-header {
		display: none;
	}
	div.debug-box:hover {
		height: 350px;
		width: 640px;
	}
	div.debug-box:hover #debug {
		display: block;
		background-color: #202020;
		color: #e0e0e0;
		overflow: auto;
		margin: 3px;
		padding: 3px;
		height: 338px;
	}
	</style>
	</head>
	<body style="margin:20px;">
		Debug Console:<br />
		Hover mouse over the black box on the right.
		<div class="debug-box">
			<div class="debug-header"></div>
			<div id="debug"></div>
		</div>
		
		<script type="text/javascript">
			debug.println('Hello world!');
			debug.println('Debug message!');
			debug.println('Debug message!');
		</script>
	</body>
</html>


Was This Post Helpful? 0
  • +
  • -

#10 mocker  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 50
  • View blog
  • Posts: 466
  • Joined: 14-October 07

Re: Week #35- JavaScript

Posted 19 November 2010 - 01:09 AM

I took a stab at using Canvas with Javascript, and ported a maze generation algorithm over from python:

Posted Image
Test example


code is a bit long, but I made a Blog Post describing the maze generation parts. You can also click on the image above and view source to see it in action.

I'll add some of the helper functions I used here since they are nice and short:

arrayCount(haystack,needle) - counts how many times *needle* occurs within the array *haystack*. Python has a built in function to do this but I didn't see one for Javascript
//fake pythons array.count function - find hte number of occurences in array
function arrayCount(haystack,needle){
	var count = 0;
	for(var i=0;i<haystack.length;i++){ if(haystack[i] == needle){ count += 1; } }
	return count;

}



This is just a very useful function I found, not written by me. It randomly shuffles the elements in a given array
//shuffle function taken from http://snippets.dzone.com/posts/show/849
//written by Jonas Raoni Soares Silva
shuffle = function(o){ //v1.0
	for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
	return o;
};



convColor(cStr) takes a hex color string, ie "FFFFFF" and converts it to an array containing RGB as 1-255 integers, ie (255,255,255);
function convColor(cStr){
//convert string of rgb hex to 255,255,255 format
 if(cStr.length != 6){ return new Array(0,0,0); } //has  ccp
 var rgb = new Array(0,0,0);
 rgb[0] = parseInt(cStr.substring(0,2) , 16);
 rgb[1] = parseInt(cStr.substring(2,4) , 16);
 rgb[2] = parseInt(cStr.substring(4,6) , 16);
 return rgb;
}


Was This Post Helpful? 1
  • +
  • -

Page 1 of 1