Category Archives: Javascript

How-to for Javascript

HTML5 new Worker

I love it, the HTML5 new worker is going to really help smoothing out the behavior of websites, and open new vistas. Now, we can control multiple JavaScript tasks simultaneously on the client computer.

Until now, we were confined to AJAX to allow the off-load of some of the work. AJAX allows the page displayed on the client computer to communicate with the server to off-load some work. AJAX allows the client computer to access the server database and server files. AJAX can do computation and send information to the client computer. AJAX is good, but, workers open up a new opportunity.

HTML5 Workers open the opportunity to control and use multiple JavaScript tasks on the client computer. This lowers the traffic between client and server and gives the client a new manner to eliminate interface (display) blocking that happens when a long task has to crank and complete before the display can continue communicating with the user.

To use a new Worker you:

  1. Create a separate JavaScript file that encapsulates the JavaScript task.
  2. Activate the JavaScript worker thread functionality.
  3. Start using the thread.

Here is a sample:

JavaScript Support Activity

Create a JavaScript file that encapsulates the needed task. As a sample create a file (worker.js) that has the following code:


  // JavaScript Document worker.js
  /* 
     use importScripts to include alternate  files needed JavaScript.
     No extra code will be needed for this sample. 
    importScripts("foo.js") ; 
  */
  /* For sample, let you know the thread has been spawned and 
      can be used. */
  postMessage("I'm waiting to do some work ...") ; 

  /* define the support action this thread provides */
  onmessage = function(evt) { 
      /* To pass data, you receive evt.data from the caller */
      var data = [] ;
      for (var i = 0 ; i < 150 ; i++) {
          data[i] =  [] ;
          for (j= 0 ; j < 150 ; j++) {
              data[i][j] = Math.random() ;
          } 
      }
      /* return the information to the caller */
      postMessage(data) ; 
  
      /* free up memory */
      data = null ;         
    
      /* close the thread if it is not doing any more */   
      self.close() ;        
  }

Spawning and Using the Worker

When the new worker is defined in a separate file, you can use it in your main page script by defining the normal response handling, error response handling and calling the worker. The following is how the worker handling is defined, spawned and used.


  var webworkers_support = !!window.Worker ;
  if (webworkers_support == true) {

      /* Workers are supported */ 
      if (typeof(worker) == "undefined")
          /* Spawn the worker */
          var worker = new Worker("worker.js") ; 
	  
	  worker.onmessage = function(evt) { 
              /* define what to do with results of the worker. */
              alert(evt.data) ;
	  } ;
	  
	  worker.onerror = function(err) {
              /* define what to do with errors in the worker */
	      document.write(
                 err.message + "<br/>" + 
                 err.filename + "<br/>" + 
                 err.lineno ) ;
              throw err ;
	  }
          /* Use/call the worker to do something */
	  worker.postMessage("msg") ;
 
	  /* If the main programs wants to control the termination 
             of the worker, you can use terminate ... 
          
              worker.terminate() ;	
          */

  } else {
      /* if running on a browser that does not support workers
         you will have to do something else ... sorry */ 
      document.write("<br/>Sorry! No web worker Support ...")
   }

Handling return errors

When an alternate thread has an error, the erroring thread will return an error code to the calling thread. The calling thread will have a function(err) defined to handle the error. The returning function can expect the following information returned:


   err.message, err.filename, err.lineno 

Information Passing

It should be mentioned, workers can't read any of the variables in the main site code. All data that the worker needs to be passed to that thread through the postMessage() calling the worker. Passing a simple variable works nicely in the simple case. In the complex case of multiple variables to be passed, consider using JSON data.

Passing Multiple Variables

To pass multiple variables, using JSON is good. To pass multiple variables, you might do the following:


   /* Define the passed variables using JSON */
   postMessage({ day: 2, month: 3, year: 1960 }) ;

   /* Given the function(evt) in the receiving thread, the parameters 
      can easily accessed as: */  
   evt.data.day, evt.data.month, evt.data.year

 

 

Create a Google Map With Marker(s)

You may be building a website that has plugins or modules to deal with google maps, but, you may be working on a site that does not have modules or plugins available. In that event, you can use the following code to create a function that allow you to enter either longitude/latitude or address for mapping.

The following code clip will allow you to display a map with markers and associated pop-up bubble. You can add as many markers as you would like, with an equal number of pop-up information bubbles. You can place the markers by specifying an address, or a longitude and latitude.


<style type="text/css">
  .entry-content { max-width:none ; }
   #bubble { height: 50px ; -moz-border-radius: 10px; 
      -webkit-border-radius: 10px; -khtml-border-radius: 10px; 
      border-radius: 10px;  }
</style>
<script type="text/javascript" 
    src="http://maps.googleapis.com/maps/api/js?sensor=false"> </script>
<script type="text/javascript">
  function map_initialize() {
      geocoder = new google.maps.Geocoder();
      var latlng = new google.maps.LatLng(-34.397, 150.644);
      var myOptions = {
          zoom: 12,
          center: latlng,
          mapTypeId: google.maps.MapTypeId.SATELLITE
      }
      d_map = new google.maps.Map(document.getElementById("map-me"), 
              myOptions);
      mapIt(999, 999, "Crescent City, CA", 
          "http://www.advancedwebhelp.com/blog/wp-content/uploads/2013/11/marker.png",
          "label to see on hover of marker", 
          "<'div id='bubble'>Say something in the pop-up bubble</div>", 
          "http://www.mydomain.com/link") ; 
  }
  function mapIt(lat, lng, address, image, label, bubble, alink) {
      if (lat != 999) {
          var myLatLong = new google.maps.LatLng(lat,lng) ;
          d_map.setCenter(myLatLong);
          var link = alink ;
          var contentString = '<div class="marker_content">'+ 
              '<a href="' + link + '">'  +  bubble +   
              '</a></div>';
          var infowindow = new google.maps.InfoWindow({
              content: contentString
          });
          var marker = new google.maps.Marker({
              map: d_map,
              icon: image,
              title: label,
              position: myLatLong
          });
          google.maps.event.addListener(marker, 'click', function() {
             infowindow.open(d_map,marker);
          });
      } else {
          geocoder.geocode( { 'address': address}, function(results, status) {
              if (status == google.maps.GeocoderStatus.OK) {
              d_map.setCenter(results[0].geometry.location);
                  var link = alink ;
                  var contentString = '<div class="marker_content">' + 
                     '<a href="' + link + '">' + bubble + '</a></div><p>';
                  var infowindow = new google.maps.InfoWindow({
                      content: contentString
                  });
              var marker = new google.maps.Marker({
                      map: d_map,
                      icon: image,
                      title: label,
                      position: results[0].geometry.location
                  });
              google.maps.event.addListener(marker, 'click', function() {
                      infowindow.open(d_map,marker);
                 });
              } else { alert("Geocode was not successful 
                      for the following reason: " + status); }
          });
      }
  }
  jQuery(function() {
      map_initialize() ;        
 }) ;
</script>

Sample

If you see this, JavaScript not supported.

I should mention several things about the above code:

  1. In the declaration of the div for map-me, you can change the width and height of the map.
  2. In the declaration of var myLatLng in map_initialize(), you can change the longitude and latitude that will be used for the center of the map
  3. In the declaration of myOptions in map_initialize(), you can change the type of map, and zoom to meet your needs
  4. You may make multiple calls to mapIt() to insert markers on the map.
  5. If you do not use the latitude and longitude in mapIt, use values 999,999.
  6. In mapIt, you include the flag for the marker, so, you can make every marker can look different.
  7. In mapIt, you can pass the content used in the bubble for the marker … it can include HTML.