<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Chris LeCompte &#187; Web Development</title>
	<atom:link href="http://www.clecompte.com/category/web-development/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.clecompte.com</link>
	<description></description>
	<lastBuildDate>Mon, 26 Jul 2010 22:25:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Managing Hacked Client WordPress Sites: Prevention, Reaction and Investigation</title>
		<link>http://www.clecompte.com/managing-hacked-client-wordpress-sites/</link>
		<comments>http://www.clecompte.com/managing-hacked-client-wordpress-sites/#comments</comments>
		<pubDate>Thu, 17 Jun 2010 13:23:07 +0000</pubDate>
		<dc:creator>Chris LeCompte</dc:creator>
				<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.clecompte.com/?p=738</guid>
		<description><![CDATA[As project managers, web designers, and freelancers, we deal with a multitude of issues, especially when it comes to content management systems. For me, most of the issues arise in WordPress as it’s my choice CMS for clients. The most serious of these issues is dealing with hacked client sites where either spam has been [...]]]></description>
			<content:encoded><![CDATA[<p>As project managers, web designers, and freelancers, we deal with a multitude of issues, especially when it comes to content management systems. For me, most of the issues arise in WordPress as it’s my choice CMS for clients. The most serious of these issues is dealing with hacked client sites where either spam has been placed, or more detrimental, malware.</p>
<p>So as project managers, web designers, and freelancers, we must by default become quasi experts in security. No problem. It adds more fun to the challenge.</p>
<p>Combating security breaches should fall into two camps (which are obvious if you’re a long-time reader of this blog): proactive and reactive. Proactive is preventing the problem before it occurs while reactive is after the fact and how to perform damage control.<span id="more-738"></span></p>
<h3>How to prevent malware and spam from harming your clients’ WordPress sites</h3>
<p>First, never underestimate the damage a spam or malware link can do to your client’s website. A strategically placed barrage of spam links can reflect in search engine listings, which could take days, if not weeks, to reverse. Malware links, which are usually script or iframe calls, can cause the ire of Google and Mozilla, both of which subscribe to an internet malware watchdog group. Under this coalition, you could find a client’s site tagged in Google searches as being unsafe due to malware and inaccessible via Firefox and Chrome among other browsers, with a big red warning to greet visitors.</p>
<p>That’s not good, especially if your client relies on their site for income. Unfortunately, I’ve been on the receiving end of a malware attack, and the results aren’t pretty.</p>
<p>With that preface in mind, prevention is the obvious course. Here’s what you can do to sleep better at night:</p>
<ul>
<li>Perform basic security operations on the WordPress install. This includes changing the admin account to a subscriber access level, ensuring passwords are strong, and closing some of the loopholes in WordPress (see the plugin below to help manage this).</li>
<li>Consider installing a plugin to help manage some of those basic security loopholes. <a href="http://wordpress.org/extend/plugins/secure-wordpress/">Secure WordPress</a> is among the more popular ones.</li>
<li>Always install the latest version of WordPress since many security holes are patched in the updates.</li>
<li>Read through <a href="http://codex.wordpress.org/Hardening_WordPress">WordPress’s preventative guide</a>.</li>
<li>Stay informed of the latest security methods and concerns. For example, Noupe has a <a href="http://www.noupe.com/how-tos/wordpress-security-tips-and-hacks.html">good article (and comments) on some preventions</a>.</li>
<li>Routinely check the client’s website rankings in search engines to identify any possible spam links.</li>
<li>Maintain backups of the WordPress database. In the event of an attack, you may have to perform a restoration. WP-DBManager is one of the <a href="http://wordpress.org/extend/plugins/wp-dbmanager/">best plugins for automated database backups</a>.</li>
<li>Install a gatekeeper plugin to prevent robots from delivering link spam. <a href="http://wordpress.org/extend/plugins/bad-behavior/">Bad Behavior</a> is a good plugin to consider.</li>
<li>Finally, and most important, setup a <a href="http://www.google.com/webmasters/">Google Webmaster</a> account to tie in with the client’s site. Not only will this service provide valuable insight into search engine rankings, it will also notify you the instant a malware attack has been flagged by Google. And yes, it’s free.</li>
</ul>
<h3>The hack has happened, what to do now</h3>
<p><strong> </strong></p>
<p>A WordPress hacking incident will more than likely occur at some point in your life. It sucks and the ensuing mess is no fun to deal with. Fortunately, it’s not the end of the world, and there are some pretty solid ways of cleaning it up.</p>
<p>Remember that there&#8217;s a difference between a spam attack and a malware attack. A spam attack is the infusion of junk links in the code (or worse, in rogue plugin files, which are harder to find) so that search engine results will pick them up. This may not necessarily be flagged by Google as malware, making detection a bit fuzzy.</p>
<p>A malware attack, on the other hand, is usually a simple case of an illegal login into the site and the placement of a script or iframe tag. Google routinely scans sites for calls to malware files such as these and will subsequently raise the warning flag. Hopefully, you’ll have had Google Webmaster setup so that notification can be sent if that flag is raised, though Google makes an earnest attempt to email the site owners regardless.</p>
<p>Once the attack has occurred and you awake to the nightmare, here are some ways to deal with it:</p>
<ul>
<li>Identify the location of the malware or spam, and remove it. If it’s a more intricate spam attack, you may need to consult a guide such as <a href="http://www.pearsonified.com/2010/04/wordpress-pharma-hack.php">Pearsonified’s WordPress Pharma Hack post</a>.</li>
<li>Scan the WordPress install for any other problems. I recommend the <a href="http://wordpress.org/extend/plugins/exploit-scanner/">WordPress Exploit Scanner plugin</a> for this job.</li>
<li>If you haven’t done so already, setup <a href="http://www.google.com/webmasters/">Google Webmaster</a> immediately. After linking the site with the service, you’ll see a red bar warning you of malware on the site if that’s the problem. After you’ve removed the malware, make sure you notify Google using the malware diagnostic tool. This will instruct a robot to scan through your client’s website, and if the malware is gone, remove the warnings within 12 &#8211; 24 hours. The sooner you do this, the sooner the warnings will be removed, which is the ultimate goal.</li>
<li>Notify the client that the problem occurred and what you’ve done to resolve the situation. This is the hardest part because a Google malware warning can make a site appear like death. Nevertheless, if the client is hosting with you or under a maintenance contract, you should help them out of this situation. A confident tone and action-oriented plan will typically calm the client’s understandably stretched nerves.</li>
<li>Now that damage control has been completed and Google notified (if there was a malware attack), it’s time to toughen up the WordPress install. I highly recommend reading through the <a href="http://codex.wordpress.org/FAQ_My_site_was_hacked">hacked FAQ on WordPress’s website</a>. This guide will provide some basic and advanced methods for fixing and preventing the problems that brought about the attack.</li>
<li>Review the preventative measures outlined in the section above.</li>
<li>Of the WordPress hacked FAQ already mentioned, the most important takeaways are to change the passwords of user accounts and implement new secret keys in the wp-config file, which can be <a href="https://api.wordpress.org/secret-key/1.1/">generated here</a>. This will establish new cookies so that hackers cannot remain logged in.</li>
<li>It may also be prudent to scan your computer and the client’s using antivirus software. The malware may have either originated from one of those computers or infected one or more of them if the problem site was opened.</li>
<li>Lastly, notify the client what steps you have taken as well as a timeline for the impact on Google search results to reverse.</li>
</ul>
<h3>Perform an investigation</h3>
<p>Many people advise performing an after-the-fact investigation into what happened post-attack. This is a good move in that it can provide a unique analysis of the flaws in your client’s site, the hosting operation, database software, or some other area of potential weakness.</p>
<p>The best place to start is by executing a simple search in Google for any recent issues regarding the web host and security problems. For examples, in the attacks I recently experienced, there were a couple of articles pertaining to my provider, Rackspace:</p>
<ul>
<li>Smackdown! Blog: <a href="http://smackdown.blogsblogsblogs.com/2010/06/14/rackspace-hacked-clients-check-your-databases-wordpress-wp_optimize-backdoor-in-wp_options-table/">Rackspace clients, check your databases</a></li>
<li>Sucuri Blog: <a href="http://blog.sucuri.net/2010/06/mass-attack-of-wordpress-blogs-on-rackspace.html">Attack of WordPress blogs on Rackspace</a></li>
<li>Unmask Parasites Blog: <a href="http://blog.unmaskparasites.com/2010/06/14/attack-on-wordpress-blogs-on-rackspace/">Attack on WordPress blogs on Rackspace</a></li>
</ul>
<p>These resources can provide valuable analysis on a specific attack as well as a means to stop and remove them. In addition to these resources, you should also consider reviewing logs, if available, to see if you can pinpoint where the attack originated. This might not always be possible, but the more information you can gather, the better. It may even be prudent to contact the web hosting company to see if they&#8217;re aware of the problem, and if they&#8217;re at fault, what&#8217;s being done to rectify the situation.</p>
<hr />
<p>WordPress hacking sucks; there&#8217;s no doubt about that. Remain vigilant and help protect your clients from the dreaded malware warnings slapped down by Google and others. Otherwise, your client could lose confidence in their website as well as visitors and revenue.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.clecompte.com/managing-hacked-client-wordpress-sites/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Building a Simple jQuery Rotating Carousel</title>
		<link>http://www.clecompte.com/building-simple-jquery-rotating-carousel/</link>
		<comments>http://www.clecompte.com/building-simple-jquery-rotating-carousel/#comments</comments>
		<pubDate>Mon, 12 Oct 2009 12:38:49 +0000</pubDate>
		<dc:creator>Chris LeCompte</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[build]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[homepage]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[rotate]]></category>

		<guid isPermaLink="false">http://www.clecompte.com/?p=318</guid>
		<description><![CDATA[The homepage is the most valuable real estate of a web site. Oftentimes, it is also the most viewed page that determines whether or not a user will explore further into the site. One way to maximize the real estate of a homepage is to dynamically show and hide content. For example, one piece of [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignright size-full wp-image-331" title="carousel" src="http://www.clecompte.com/wp-content/uploads/2009/10/carousel.jpg" alt="jQuery Carousel Content Rotate" width="300" height="195" />The homepage is the most valuable real estate of a web site. Oftentimes, it is also the most viewed page that determines whether or not a user will explore further into the site.</p>
<p>One way to maximize the real estate of a homepage is to dynamically show and hide content. For example, one piece of content could feature information about a product and then automatically hide to show a new piece of content advertising some other part of the web site. Not only does this enable you to create more space where there once wasn&#8217;t, it also helps you to grab the attention of the user. Any type of animated content is almost always guaranteed to attract eyeballs.<span id="more-318"></span></p>
<p>The best way to implement something like this for your own homepage (or a subpage, it doesn&#8217;t have to be a homepage) is to implement what&#8217;s called a carousel.</p>
<p>The carousel automatically rotates through pre-defined featurettes, be they media or text, and allows the user to manipulate which content is shown via a mouse hover or click event.</p>
<h2>The Example</h2>
<p>Let&#8217;s take a look at a quick example: <a href="http://www.clecompte.com/examples/carousel/">http://www.clecompte.com/examples/carousel/</a></p>
<p>This is a bare bones carousel that can always be beefed up with design elements later on. As you can see, it&#8217;s automatically rotating through three content pieces. If you hover your mouse over any of the three content titles to the left, the animation will end. You can then continue to navigate to the other pieces of content by hovering over the other titles.</p>
<p>Why does it behave like this? It begins with the automatic animation to make sure all of the content gets play in case the user doesn&#8217;t interact with it. It ceases the animation once the user interacts with it so that it doesn&#8217;t animate as the user is trying to read the content.</p>
<h2>How it Works</h2>
<p>So how does it work? Below is the full source code of the CSS and jQuery.</p>
<h3>The CSS</h3>
<p>The CSS is pretty straightforward. The left side navigation of the three content pieces is setup using an unordered list while the content is housed using a div container. All of the content containers must be hidden as the jQuery will initialize everything.</p>
<pre>body {font-family:"Helvetica Neue", Arial, Helvetica, sans-serif;}

.feature_nav {width:200px; float:left;}
ul {list-style:none; margin:0; padding:0;}
ul li a {background:#666; color:#fff; padding:8px; border-width:1px 0 1px 1px; border-color:ccc; border-style:solid; display:block; font-size:14px; font-weight:bold; margin:0 1px 2px 0; text-decoration:none;}
ul li a.on {background:#ccc; font-size:16px; color:#333; border:none; margin-right:0;}

.feature_content {width:460px; float:left; height:160px; background:#eee; border:2px solid #ccc; padding:20px;}

#feature_one, #feature_two, #feature_three {display:none;}

h1 {color:#333; font-size:22px; border-bottom:2px solid #fff; margin-top:0;}</pre>
<h3>The jQuery</h3>
<p>Here comes the fun part. Below is the full source of the jQuery which I&#8217;ll explain in a moment.</p>
<pre>$(document).ready(function() {

  /* HOME ANIMATION */
  function contentRotate(feature) {
    if (doAnimate) {
      feature.fadeOut("fast", function (feature) {
        return function () {
          $(".feature_content div").hide();

          /* HIGHLIGHT RELEVANT CONTROL */
          if ($(this).attr("id") == "feature_one") {
            $(".feature_nav .on").removeClass("on");
            $(".home_one").addClass("on");
          }
          else if ($(this).attr("id") == "feature_two") {
            $(".feature_nav .on").removeClass("on");
            $(".home_two").addClass("on");
          }
          else if ($(this).attr("id") == "feature_three") {
            $(".feature_nav .on").removeClass("on");
            $(".home_three").addClass("on");
          }

          /* FADE IN NEXT ITEM OR GO BACK TO FIRST */
          feature.fadeIn("fast", function () {
            if ($(this).attr("id") == "feature_three") {
              setTimeout(function () {
                contentRotate($(".feature_content div:first"));
              }, 4000);
            }
            else {
              setTimeout(function () {
                contentRotate($(feature.next()));
              }, 4000);
            }
          });
        };
      }(feature));
    }
  }

  /* HOME FEATURES */
  $(".feature_nav a").hover(function() {
    var current = $(this).attr("title");
    $(".feature_nav .on").removeClass("on");
    $(this).addClass("on");
  });

  $(".feature_nav a").click(function() {
    return false;
  });

  var doAnimate = true;

  contentRotate($(".feature_content div:first"));

  $(".home_one").hover(function() {
    $("#feature_one").fadeIn();
    $("#feature_two").hide();
    $("#feature_three").hide();
    doAnimate = false;
  });
  $(".home_two").hover(function() {
    $("#feature_one").hide();
    $("#feature_two").fadeIn();
    $("#feature_three").hide();
    doAnimate = false;
  });
  $(".home_three").hover(function() {
    $("#feature_one").hide();
    $("#feature_two").hide();
    $("#feature_three").fadeIn();
    doAnimate = false;
  });

});</pre>
<p>The easiest way to explain this code is to start from the bottom. A variable called doAnimate is created to determine whether or not the animation should run. It is initially set to true so that the content will rotate when the page loads. Calling the contentRotate function, which I&#8217;ll get into shortly, initializes the content rotation.</p>
<p>The only way the animation can be stopped is if the user hovers over the left side titles. That&#8217;s what the three hover functions are doing. For example, if the user hovers their mouse over the second title, the first and third containers will be immediately hidden if they are visible, the second container will be shown, and the doAnimate variable will be set to false to end the animation.</p>
<p>Above those three functions is the contentRotate function call that I mentioned earlier. When this function is called, the first div container within the container that has class &#8220;feature_content&#8221; is passed. So, if you refresh the page, the animation will always begin with the first content feature.</p>
<p>In the actual contentRotate function itself, the function will only run if doAnimate is true, which it is by default. After that you see a function to fade out the current content container, which is done after the contentRotate function is given the next content container. The hiding of all divs inside the &#8220;feature_content&#8221; container may seem counterintuitive, but this is done to prevent any of the content containers from appearing prematurely.</p>
<p>The area in the contentRotate function with the comment about highlighting the relevant control is what determines which left side title will be highlighted. This is accomplished using a simple if statement. If the current visible content container has an id that matches its associated title, then all the other titles are deemphasized and only the associated title is highlighted.</p>
<p>The next part of the contentRotate function is where the magic happens. The current content container is faded in and an if statement is immediately run to make sure the last content container has not been reached. If the last container has been reached, the if statement will go through the function again starting with the first container. If the last container has not been reached then the function will continue with the next container in sequence. All of this is set to a 4-second timer.</p>
<p><strong>So there you have it:</strong> a simple carousel feature that is flexibly built using HTML, CSS and jQuery. This is just a prototype, so if you find problems or areas of improvement, feel free to drop a comment.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.clecompte.com/building-simple-jquery-rotating-carousel/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Building Dynamic Navigation Using JavaScript and jQuery</title>
		<link>http://www.clecompte.com/building-dynamic-navigation-using-javascript-and-jquery/</link>
		<comments>http://www.clecompte.com/building-dynamic-navigation-using-javascript-and-jquery/#comments</comments>
		<pubDate>Tue, 28 Jul 2009 12:46:31 +0000</pubDate>
		<dc:creator>Chris LeCompte</dc:creator>
				<category><![CDATA[Web Design]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[dynamic]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[navigation]]></category>
		<category><![CDATA[script]]></category>

		<guid isPermaLink="false">http://www.clecompte.com/?p=238</guid>
		<description><![CDATA[Ok, I&#8217;ll admit, I&#8217;m pretty new to JavaScript and jQuery, so as a disclaimer, my coding may not be perfect or concise. With that said, I&#8217;m going to explain how to build dynamic navigation highlighting using a little JavaScript and jQuery. The first step is to explain the problem. Most web sites that follow good [...]]]></description>
			<content:encoded><![CDATA[<p>Ok, I&#8217;ll admit, I&#8217;m pretty new to JavaScript and jQuery, so as a disclaimer, my coding may not be perfect or concise. With that said, I&#8217;m going to explain how to build dynamic navigation highlighting using a little JavaScript and jQuery. The first step is to explain the problem.</p>
<p>Most web sites that follow good usability practices will tell visitors where they are on the site. It&#8217;s kind of like that directory map in a shopping mall with the big red &#8220;YOU ARE HERE&#8221; arrow. On web sites, this is usually accomplished by highlighting or shading the navigation object that the user is currently on.</p>
<p><img class="aligncenter size-full wp-image-249" title="js-dynamic-nav-highlighting-example" src="http://www.clecompte.com/wp-content/uploads/2009/07/js-dynamic-nav-highlighting-example.png" alt="js-dynamic-nav-highlighting-example" width="494" height="54" /><span id="more-238"></span></p>
<p>If you&#8217;re running a web site on a content management system like WordPress, this is easy to handle. For example, WordPress gives you a class called &#8220;current_page_item&#8221; that is only added to the list item of the page the user is currently looking at. Pretty useful.</p>
<p>Unfortunately, if you&#8217;re not running a web site in a content management system with that level of sophistication, then you&#8217;re out of luck. The only way to really implement something like it is to manually build the navigation.</p>
<p>However, JavaScript can help automate most of that. We can use JavaScript and jQuery to dynamically determine what page the user is currently browsing and add a class to the navigation object to highlight it. In the example above, the &lt;a href&gt; tag surrounding &#8220;About&#8221; has a class of &#8220;on&#8221; applied to it.</p>
<p><strong>The code:</strong></p>
<pre id="line1">&lt;<span>script</span><span> type</span>=<span>"text/javascript"</span>&gt;
var blog = "blog";
var url = blog;
var siteurl;
var locmatch;

url = url.split(/[\s\,]+/i);
siteurl = String(location.href);
for (var x = 0; x &lt; url.length; x++) {
  locmatch = siteurl.match(url[ x ]);
}

$(document).ready(function(){
  if (locmatch == blog) {
    $("#page_nav li a[href*='blog']").addClass("on");
  }
  else {
    $("#page_nav li").find("a[href='"+window.location.pathname+"']").each(function(){
      $(this).addClass("on")
    });
  };
});
&lt;/<span>script</span>&gt;</pre>
<p>The code is broken into two parts consisting of regular JavaScript and then jQuery. The approach behind this script is simple. We want to determine what page a user is currently on and then analyze the <em>&lt;a href&gt;</em> links in the navigation to see if there&#8217;s a match. If there is, we&#8217;ll apply <em>class=&#8221;on&#8221;</em> to the matched navigation object.</p>
<p>Furthermore, say for example there is a blog on the web site in question. With a blog, each post would create a new page and that page location would no longer match the navigation object (e.g. &#8220;Blog&#8221; in the navigation would have a URL of http://www.mysite.com/blog/, but if a user is on a specific post, that URL would change to something like http://www.mysite.com/blog/this-is-a-post/. The URL then would no longer match the <em>&lt;a href&gt;</em> link of the &#8220;Blog&#8221; navigation object and thus no match would be detected.)</p>
<p><strong>Let&#8217;s walk through the code one chunk at a time.</strong></p>
<pre id="line1">var blog = "blog";
var url = blog;
var siteurl;
var locmatch;

url = url.split(/[\s\,]+/i);
siteurl = String(location.href);
for (var x = 0; x &lt; url.length; x++) {
  locmatch = siteurl.match(url[ x ]);
}</pre>
<p>This chunk of code is designed to look for the word &#8220;blog&#8221; in the URL path. The <em>blog</em> variable is defining what word to look for (in this case &#8220;blog&#8221;) and it then stores it in the <em>url</em> variable. The <em>siteurl</em> variable will contain the full path of the current page URL and the <em>locmatch</em> variable will contain a match to &#8220;blog&#8221; if there is one. The <em>url</em> variable is then split and run through a loop to detect a match of &#8220;blog.&#8221; The result is stored in the <em>locmatch</em> variable.</p>
<p><strong>The second chunk of code is the jQuery and it does most of the heavy lifting.</strong></p>
<pre id="line1">$(document).ready(function(){
  if (locmatch == blog) {
    $("#page_nav li a[href*='blog']").addClass("on");
  }
  else {
    $("#page_nav li").find("a[href='"+window.location.pathname+"']").each(function(){
      $(this).addClass("on")
    });
  };
});</pre>
<p>Once the document is ready, the first order of business is to determine whether or not the <em>locmatch</em> variable matches the blog variable we defined earlier. If it does, then we instruct the code to find all <em>&lt;a href&gt;</em> tags within the navigation area (anything that is a descendant of <em>#page_nav li</em>) that contains the word &#8220;blog&#8221; and apply a class of &#8220;on.&#8221;</p>
<p>If <em>locmatch</em> does not equal the <em>blog</em> variable, the if statement moves to the second part. First, we tell the code to look under <em>#page_nav li</em> and to find any <em>&lt;a href&gt;</em> tags that contain the current page path that the user is on (keep in mind, the code is only looking at the path of the page and not the host, so http://www.mydomain.com would be ignored&#8230; this is in case you&#8217;re using relative paths). It processes each of the <em>&lt;a href&gt;</em> tags and applies the &#8220;on&#8221; class to any matches.</p>
<p><strong>So, let&#8217;s look at the net result of our efforts. Say we have our navigation/page setup like the following:</strong></p>
<pre>&lt;ul id="page_nav"&gt;
  &lt;li&gt;&lt;a href="/about-me/"&gt;About Me&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="/services/"&gt;What I Do&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="/blog/"&gt;My Blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="/blog/archives/"&gt;Check out my blog archives, too!&lt;/a&gt;&lt;/p&gt;</pre>
<p>If a user clicks on either &#8220;About Me&#8221; or &#8220;What I Do,&#8221; a class called &#8220;on&#8221; will be applied to the <em>&lt;a href&gt;</em> tag. If the user clicks either &#8220;My Blog&#8221; or the paragraph link beneath the navigation, the &#8220;on&#8221; class will be applied to the <em>&lt;a href&gt;</em> tag surrounding &#8220;My Blog&#8221; in the navigation.</p>
<p>Is there an easier way of doing this? Probably. But like I said, I&#8217;m not an expert in JavaScript or jQuery &#8212; but I am an expert in what works and this does. Tested in Firefox, Safari, IE6 and IE7 without issue. Let me know if you have any problems.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.clecompte.com/building-dynamic-navigation-using-javascript-and-jquery/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
