This is turning into a big ol’ red herring. I’m trying to use jQuery to add an ‘active’ class to a basic menu (to either the li or a tag) that’s generated from a Pulse Block. Über simple.
I’ve tried numerous jQuery examples but none of them work for me and I’m not sure why (yes, I’m calling jQuery before the link script). Does someone have a vanilla js solution I can try? Something that won’t conflict with jQuery.
Here’s the classname stuff from Prototype, with all of its prototype-ness taken out of it so it can’t conflict:
To use this you would get a reference to the element you want to modify, and then pass it to the addClassName function, like this (pure vanilla js):
var selected = document.querySelector('ul.menu li:nth-of-type(2)');
addClassName(selected, 'active');
That should get you the second li marked as .active.
Walter
PS: You have a quote mark in there that doesn’t match – I think the first one is curly, not straight “typewriter” quotes. When I pasted your example into TextMate, it freaked out and the whole rest of the document was badly-colored.
On Jan 27, 2014, at 6:36 PM, Todd wrote:
This is turning into a big ol’ red herring. I’m trying to use jQuery to add an ‘active’ class to a basic menu (to either the li or a tag) that’s generated from a Pulse Block. Über simple.
I’ve tried numerous jQuery examples but none of them work for me and I’m not sure why (yes, I’m calling jQuery before the link script). Does someone have a vanilla js solution I can try? Something that won’t conflict with jQuery.
Thanks Walter, I managed to get the below jQuery script working. One catch though: despite the example on the dev site http://bit.ly/1fs3FwI which uses relative links (.html) my menu only works with absolute urls (.php). Any idea why this is happening?
Call
$(".menu a").currentPage();
Script
/* jQuery plugin for setting the class of a particular element to
* "current" based on the current page. Useful for navigation menus
* that are part of a server side include for the whole site.
*
* By Rob Watts, http://tractionsys.com
* Version 1.3, May 10, 2011
*
* Modified by Chris Osborn, http://tractionsys.com
* Version 2.0, Dec 16, 2011
* Now constructs complete URL and compares to current location
*
* Provided under the MIT license. Feel free to use it however you like.
*
* Example:
* $("ul.nav a").currentPage();
*
* To override defaults, pass in a defaults object:
* $("ul.nav a").currentPage({
* attr: "href",
* defaultClass: "selected"
* });
*
*/
ME_cpBase = $('base').attr('href');
ME_cpPath = window.location.href;
function ME_cpCompleteURL(base, path, index, uri)
{
var array;
var i;
/* This looks stupid but it's the easiest way to make sure uri is a string */
uri = uri + '';
if (uri.indexOf(':') < 0) {
if (base == undefined)
base = path.substr(path.lastIndexOf('/') + 1);
if (uri.charAt(0) == '/') {
i = base.indexOf(':');
i = base.indexOf('/', i + 3);
uri = base.substr(0, i) + uri;
}
else
uri = base + uri;
}
if (uri.search('/\\.\\./') >= 0) {
array = uri.split('/');
if (array.length > 3) {
for (i = 4; i < array.length; i++)
if (array[i] == '..') {
array.splice(i-1, 2);
i--;
}
for (i = 3; i < array.length && array[i] == '..'; i++)
;
if (i - 3)
array.splice(3, i - 3);
uri = array.join('/');
}
}
if (uri.charAt(uri.length - 1) == '/')
uri = uri + index;
return uri;
}
jQuery.fn.currentPage = function(options) {
var currentPage = "";
var thisClass = "";
var thisHref = "";
var settings = jQuery.extend({
defaultClass: "current", // Default class to add to current link
attr: "href", // Default attribute to compare with current page URL (not usually used)
appendToFirstClass: false, // Append the defaultClass to the first class on the element.
// E.g. class="monkey" becomes class="monkey monkeycurrent"
indexFile: "index.html"
}, options);
currentPage = ME_cpCompleteURL(ME_cpBase, ME_cpPath,
settings.indexFile, window.location.href);
this.each(function() {
thisHref = ME_cpCompleteURL(ME_cpBase, ME_cpPath, settings.indexFile,
$(this).attr(settings.attr));
thisClass = "";
if (thisHref == currentPage) {
if (settings.appendToFirstClass) {
/* Conditional to support jQuery 1.6 */
if ($(this).attr("class"))
thisClass = $(this).attr("class").split(" ")[0];
thisClass = thisClass + settings.defaultClass;
}
else
thisClass = settings.defaultClass;
$(this).addClass(thisClass);
}
});
};
It looks like they’re using a naive method of splitting the URL into its component parts. I would start by refactoring that part of the script. Look at window.location in MDN – there’s all sorts of bits in that object that are useful: window.location.pathname and .hostname and .search and .hash.