SitePoint Sponsor

User Tag List

Results 1 to 11 of 11
  1. #1
    SitePoint Member
    Join Date
    Sep 2004
    Location
    London
    Posts
    15
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Working with URL strings

    This newbie needs some advice I have written the script below to find the first folder name in the window url and use that to determine what section of the site a page is in. Using this, I then write a class to the body tag that can be used to style all pages in that section of the site. Now, I'm pretty new to JavaScript so was hoping that someone could look at my script and give me some pointers on how I could have written it better.

    Thanks
    Mike

    Code JavaScript:
    /* ***************************************
    CHANGE BODY CLASS BASED ON SECTION OF SITE USER IS IN
    *************************************** */
    // Get the page's url
    var url = window.location.href;
    // Split the url into its directory structure and file name
    var sectionName = url.split("/");
    // If there are more than 3 forward slashes then there is a folder name ie...
    	// No folder: [url]http://www.foo.com/file.aspx[/url] (Only 3 forward slashes)	
    	// Has a folder: [url]http://foo.com/folder/file.aspx[/url] (4 forward slashes)
    if (sectionName.length > 3) {
     
    	// About
    	if (sectionName[5] == "about") {
    		var bodyClass = document.getElementsByTagName("body")[0].setAttribute("class", "about");
    	}
     
    	// Education
    	if (sectionName[5] == "education") {
    		var bodyClass = document.getElementsByTagName("body")[0].setAttribute("class", "education");
    	}
     
    	// Help
    	if (sectionName[5] == "help") {
    		var bodyClass = document.getElementsByTagName("body")[0].setAttribute("class", "help");
    	}
     
    	// Licensing
    	if (sectionName[5] == "licensing") {
    		var bodyClass = document.getElementsByTagName("body")[0].setAttribute("class", "licensing");
    	}
     
    	// My Account
    	if (sectionName[5] == "myaccount") {
    		var bodyClass = document.getElementsByTagName("body")[0].setAttribute("class", "account");
    	}
     
    	// Products
    	if (sectionName[5] == "products") {
    		var bodyClass = document.getElementsByTagName("body")[0].setAttribute("class", "products");
    	}
     
    	// Store
    	if (sectionName[5] == "store") {
    		var bodyClass = document.getElementsByTagName("body")[0].setAttribute("class", "store");
    	}
     
    }

  2. #2
    SitePoint Guru
    Join Date
    Apr 2006
    Posts
    802
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Your task will be simpler if you query the location.pathname instead of the href.

    var folder=location.pathname.match(/^\/([\w\-]+)\//i);
    if(folder) folder=folder[1];
    else folder= 'web root';

    Also, IE has a problem with setAttribute for 'class'- you may need to set the className property, which works (in html) x-browser.

    And this is minor, but I'd just write one assignment based on the result of folder.
    You only have one possible folder (myaccount) that needs translating.

    if(folder=='myaccount') folder='account';
    if(/^(about|education|help|licensing|account|products|store)$/.test(folder)){
    document.body.className=folder;
    }

  3. #3
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    There is a lot of duplication as you're well aware, so let's do something about that.

    Normally you could store the valid folder names in an array, but the myaccount section has a differently named class, so we'll use an array of objects instead that let us specify the folder and class names.

    Then we can loop through them. There doesn't appear to be any benefit to assigning the bodyClass variable either. Some browsers can have trouble with the class element too, so className is used instead.

    Oh yes, the body can be accessed as just document.body as well.

    Code Javascript:
    var folder = [
        {name: 'about', class: 'about'},
        {name: 'education', class: 'education'},
        {name: 'help', class: 'help'},
        {name: 'licensing', class: 'licensing'},
        {name: 'myaccount', class: 'account'},
        {name: 'products', class: 'products'},
        {name: 'store', class: 'store'}
    ];
     
    var folderName = location.pathname.match(/^\/([\w\-]+)\//i);
    folderName = (folderName) ? folderName[1] : 'web root';
     
    for (var i = 0; i < folder.length; i++) {
        if (folderName === folder[i].name) {
            document.body.className = folder[i].class;
        }
    }
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  4. #4
    SitePoint Wizard
    Join Date
    Nov 2004
    Location
    Nelson BC
    Posts
    2,310
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Paul:
    You could make one object with the property names being the folders instead of an array of objects, it would be a lot easier to get the class as well:

    Code:
    var folderToClass = {
        'about': 'about',
        'education': 'education',
        'help': 'help',
        'licensing': 'licensing',
        'myaccount': 'account',
        'products': 'products',
        'store': 'store'
    };
    // to be extra safe :)
    if (folderToClass[folderName] ) {
      document.body.className = folderToClass[folderName];
    } else {
      // assign some default class
    }
    Last edited by jimfraser; Feb 12, 2008 at 12:30. Reason: to be extra safe

  5. #5
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    Great stuff Jim, and thanks mrhoo for the regex. I still have more work to better understand those.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  6. #6
    SitePoint Member
    Join Date
    Sep 2004
    Location
    London
    Posts
    15
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi everyone. Thank you for your help with this script. I'm going to pick them apart to better understand how they work.

  7. #7
    SitePoint Addict
    Join Date
    Dec 2007
    Posts
    207
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Code javascript:
    var loc = location.pathname.split("/");
    var folder = loc.length >= 3 ? loc[1] : null;
    var folders = [
    	'about',
    	'education',
    	'help',
    	'licensing',
    	'account',
    	'products',
    	'store'
    ];
    if (folder) {
    	if (folders.indexOf(folder) >= 0)
    		document.body.className = folder;
    	//else
    		//
    }
    //else
    	//

    indexOf could have side-effects.

  8. #8
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    What would you suggest instead of indexOf. Perhaps "if (folders[folder])" instead?
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  9. #9
    SitePoint Addict
    Join Date
    Dec 2007
    Posts
    207
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by pmw57 View Post
    What would you suggest instead of indexOf. Perhaps "if (folders[folder])" instead?
    No, because this is a numerical array, the keys are numbers.

    The problem with indexOf is that if folder = 'abou' than when it executes "folders.indexOf(folder)" it will return 0+ (i.e. it will find it).

    If we had the equivalent of php's in_array than we would be get to go.

  10. #10
    SitePoint Wizard
    Join Date
    Nov 2004
    Location
    Nelson BC
    Posts
    2,310
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm pretty sure that Array.indexOf(thing) returns the array index of the element with value=thing, its not the same as String.indexOf. Some browsers dont support it though, but you can build it.

    Code:
    if (!Array.indexOf) {
      Array.prototype.indexOf = function(testValue) {
        for (var i=0; i < this.length; i++) {
          if (this[i] == testValue) {
            return i;
          }
        }
        return -1;
      }
    }

  11. #11
    SitePoint Addict
    Join Date
    Dec 2007
    Posts
    207
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by jimfraser View Post
    I'm pretty sure that Array.indexOf(thing) returns the array index of the element with value=thing, its not the same as String.indexOf. Some browsers dont support it though, but you can build it.

    Code:
    if (!Array.indexOf) {
      Array.prototype.indexOf = function(testValue) {
        for (var i=0; i < this.length; i++) {
          if (this[i] == testValue) {
            return i;
          }
        }
        return -1;
      }
    }
    Yeah, that is pretty much what an in_array function would look like; if ported to javascript.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •