I have my code below:
<ul id="profileList" class="nav nav-list">
<li>修改个人签名档</li>
<li>修改个人居住地</li>
<li>修改个人学校专业</li>
</ul>
Also here's the JS code:
<script type="text/javascript">
$(document).ready(function() {
// store url for current page as global variable
current_page = document.location.href
// apply selected states depending on current page
if (current_page.index(/signature/)) {
$("ul#profileList li:eq(0)").addClass('active');
} else if (current_page.match(/location/)) {
$("ul#profileList li:eq(1)").addClass('active');
} else if (current_page.match(/education/)) {
$("ul#profileList li:eq(2)").addClass('active');
} else { // don't mark any nav links as selected
$("ul#profileList li").removeClass('active');
};
});
</script>
When I click the second and third li item, they work well. But when I click the first item,
the item is not becoming active. What's the wrong and why?
In
if (current_page.index(/signature/)) {
Change to
if (current_page.match(/signature/)) {
As far as I know, String.prototype.index doesn't exist. Perhaps you wanted to use the indexOf method.
if (current_page.indexOf('signature') !== -1) {}
Also, do not use the String.prototype.match function when you just want to know if there's a match or not, use the RegExp.prototype.test function.
if (/education/.test('education')) { /*matches*/ }
However in your case, you could use the match method and instead of discarding the match, use it at your advantage:
var sections = ['signature', 'location', 'education'],
match = document.location.href.match(new RegExp(sections.join('|'), 'i')),
selectorSuffix = match? ':eq(' + sections.indexOf(match[0].toLowerCase()) + ')' : '';
$('ul#profileList li' + selectorSuffix)[(match? 'add' : 'remove') + 'Class']('active');
Related
I'm working on an events page in a WordPress site that uses a set of filters to query posts; the markup for the filters is as follows:
<div class="event-filter">
All Events
Conferences
Webinars
Learning
Past Events
</div>
I'm using jQuery to add an active class to whichever filter is currently in use, the simple code for which is as follows:
$('.event-filter a').each(function() {
if (this.href == window.location.href) {
$(this).addClass("active");
}
});
This works perfectly fine except in the case that the resulting posts are paginated, as the url changes to reflect the current page, i.e. /events/page/2/?event-type=conference. How can I modify my JS to add the active class to the current filter if the URL contains the respective event-type term but also accounts for "All Events", and thus appends the class to "All Events" when the other filters are not in use? A couple notes: the "Past Events" option just links to an archive page that is a separate template from the main, filterable "Events" page; also, these filters are not using Ajax, they're just altering the WordPress query by URL parameter. Thanks for any insight here!
By the looks of it you will have to do a two part check, I would try something like:
$('.event-filter a').each(function() {
var currentHref = window.location.href.split('?'); // ['https://myexamplesite.com/events/page/2', 'event-type=conference']
var thisHref = this.href.split('?'); // ['https://myexamplesite.com/events', 'event-type=conference']
var currentHrefHasQuery = currentHref.length > 1 ? true : false; // true
var thisHrefHasQuery = thisHref.length > 1 ? true : false; //true
if (currentHrefHasQuery != thisHrefHasQuery) {
return; // they don't match
}
if (currentHrefHasQuery && currentHref[1] == thisHref[1]) { // if they have a query and the query is the same, it's a match!
$(this).addClass("active");
} else if (!currentHrefHasQuery && currentHref[0].indexOf(thisHref[0]) > -1) { //check to see if the current href contains this' href
$(this).addClass("active");
}
});
This could definitely be simplified, but hopefully this is fairly easy to read.
Fiddle: https://jsfiddle.net/m0hf3sfL/
Using a list for navigation, I am looking for a clean way to apply the 'selected' class to a list item if the page URL (minus anything after the path) matches the href of the list item (minus anything after the path).
Example:
<li>dresses</li>
Apply class "selected" to the list item when the page URL includes the /p/clothing/dresses/N-10635 part of the href.
So far, I achieved partial results using:
$('.leftNav li a').each(function(){
if(window.location.href == this.href){
$(this).parents('li').addClass('selected');
}
});
<ul class="leftNav">
<li>dresses</li>
<li>capris</li>
</ul>
This, however, only applied the 'selected' class when the URL matched the href exactly - meaning it had to include the link-tracking variable as in the href (ie: ?ab=leftNav:dresses). Thinking of ways to match the "base" URL's and href's, I tried adding a data attribute to the list items to match the path only:
$('.leftNav li').each(function(){
if(window.location.href == (this).data('left-nav-href')){
$(this).addClass('selected');
}
});
<ul class="leftNav">
<li data-left-nav-href="/p/clothing/dresses/N-10635">dresses</li>
<li data-left-nav-href="/p/clothing/bottoms/capris/N-10764">capris</li>
</ul>
I attempted this with variations of window.location including: window.location.href, window.location.href.pathname, window.location.href.indexOf, window.location.href.startsWith. With this not working, I searched for a way to match the path of the URL and href regardless of additional parameters or variables, but all I can find are ways to match URL's and href's specifically with strings or parameters. All instances I could find of matching only part of a URL or href use "split" RegEx which introduces another level of complexity that I don't think my use requires. Am I missing a simpler solution?
you can use indexOf()
$(document).ready(function () {
$('.leftNav li a').each(function(){
var ThisHref = ($(this).attr('href').split('?'))[0];
if(window.location.href.indexOf(ThisHref) > -1) {
$(this).closest('li').addClass('selected');
}
});
});
Example
var url = "http://www.website.com/index/p/clothing/bottoms/capris/N-10764?ab=leftNav:capris";
$(document).ready(function () {
$('.leftNav li a').each(function(){
var ThisHref = ($(this).attr('href').split('?'))[0];
//alert(ThisHref);
if(url.indexOf(ThisHref) > -1) {
$(this).closest('li').addClass('selected');
}
});
});
.selected{
background : red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="leftNav">
<li>dresses</li>
<li>capris</li>
</ul>
Explanation:
$(document).ready(function () { // run the code after document is ready
$('.leftNav li a').each(function(){ // loop through <a> on <li>
// $(this).attr('href') will return href as string .. in your case will return something like '/p/clothing/dresses/N-10635?ab=leftNav:dresses'
// using .split('?') to separating this href string by '?'
// [0] get the first string after split (in this case it will be '/p/clothing/dresses/N-10635')
// combine all of those steps on just one line
var ThisHref = ($(this).attr('href').split('?'))[0];
// get the 'window.location.href' which is return your url ..something like 'http://www.website.com/index/p/clothing/bottoms/capris/N-10764?ab=leftNav:capris'
// try to find (first string after split) into (url/window.location.href)
if(window.location.href.indexOf(ThisHref) > -1) { // if the url contains the first string after split addClass
$(this).closest('li').addClass('selected');
}
});
});
you can read about .split() here
Note: in Vinas answer he use this.href which will return href as
string .. in your case will return something like
'/p/clothing/dresses/N-10635?ab=leftNav:dresses' and he use
location.pathname
and the code of indexOf() he try to find the location.pathname
into the href
Additional: in your case both my answer and Vinas answer will work . that's not depending on code its depending on your case and what you're trying to do .. something like .hide(0) , .slideUp(0) , fadeOut(0) all of those hide the element with same effect .. So the code always determine by the case you working with .. May be my code or even Vinas's code won't work on another case
I guess if you keep your html like
<li>dresses</li>
but change the comparisson to:
$('.leftNav li a').each(function(){
if (this.href.indexOf(location.pathname) > -1) {
$(this).parents('li').addClass('selected');
}
});
you'll get what you need!
The "if" above will check if the given path is contained in item's href property.
So, if your URL is "http://www.yourhost.com/p/clothing/dresses/N-10635?param=value", it's path (/p/clothing/dresses/N-10635) should be found, and the output for the given example would be:
<li class="selected">dresses</li>
I hope this helped! =)
Assuming there isn't any '?' character in the actual path you could use something like this for both the location and the href:
function getBaseURL(url) {
return url.split('?')[0];
}
Let's go straight to the point.
The following code must run on IE8, unfortunately.
It is supposed to find match the URL of the current page with the href attribute of the <a> tags present in the nav. Then swap the class of that tag from not-selected to selected or defaults to do it to the first <a> tag.
HTML
<ul id="nav">
<li><a class="not-selected" href="index.php"><span>Index Page</span></a></li>
<li>
<a class="not-selected" href="page1.php"><span>Page 1</span></a>
</li>
<li>
<a class="not-selected" href="page2.php"><span>Page 2</span></a>
</li>
</ul>
JavaScript (jQuery)
var url = $(document).attr('URL');
var isIndexPage = true;
var menu = $('#nav').children('li');
var anchors = menu.find('a');
anchors.each(function(index) {
// Is the href the same as the page?
if ($(this).href != null && anchor.href == url)
{
$(this).first().addClass('selected');
if ($(this).className.match(/\bnot\-selected\b/))
$(this).first().removeClass('not-selected');
indexPage = false;
}
else
{
// remove class="selected" if it has that class
if ($(this).className.match(/\bselected\b/))
{
$(this).first().removeClass('selected');
}
// Add class="trigger"
$(this).first().addClass('not-selected');
}
});
if (isIndexPage)
{
menu[0].childNodes[0].setAttribute('class', 'selected');
}
On the script, I get an error on the line that calls the match() function on the className attribute (which should be a string).
Why is that?
How can I fix it with jQuery or JavaScript that works on IE8?
Thank you in advance.
There is no className property of the jQuery object, you would use the hasClass method to check if the element has a class:
if ($(this).hasClass('not-selected'))
However, you don't need that check at all. You can just remove the class, and if it's not there in the first place the call will just do nothing. You can just do it like this:
$(this).addClass('selected').removeClass('not-selected');
Similarly in the else block, you don't need to check, just remove and add:
$(this).removeClass('selected').addClass('not-selected');
Actually, you don't even need the if, you can do it using toggleClass and a boolean value. This would be your entire loop:
anchors.each(function() {
var sel = $(this).href != null && $(this).href == url;
$(this).toggleClass('selected', sel).toggleClass('not-selected', !sel);
});
Also, you are using the undefined variable anchor where you should use $(this). Change this line:
if ($(this).href != null && anchor.href == url)
to:
if ($(this).href != null && $(this).href == url)
className is a native property of HTML elements, whereas you're trying to call it as a property on a jQuery object. Do either:
$(this)[0].className
or
$(this).attr('class')
Sidenote: you're are not first checking whether the element has a class or not - you're assuming it has. The second (jQuery) approach will error if the element has no class attribute, as it returns null if none is found (as opposed to the native className property which, in the absence of a corresponding class attribute, defaults to an empty string.)
you can replace the lines
if ($(this).className.match(/\bselected\b/))
with this
if ($(this).hasClass('selected'));
It's much simpler. The same for class 'not-selected'.
I think you should use plain JS for the URL and jQuery for the rest example:
JavaScript
var path = window.location.pathname;
$.each($('#nav li a'), function(index, anchor) {
if(path.indexOf($(anchor).attr('href')) != -1) {
$('#nav li a').removeClass('selected');
$(anchor).addClass('selected').removeClass('not-selected');
}
});
Here is an example: http://jsfiddle.net/2rSqL/
First thanks to the people have helped me answering most of my questions. I am new at mootools and really need some help with specific things like chaining functions, effects, etc.
I would like to fade in an entire column on a table, but the thing is I populate the table and its rows on page load, and hide that columns I dont want to show(statically are 5 columns). but I have the functionality to remove an entire column and then has to appears a new one at the end. The hidden column has a class with display none.
I am ussing moootools to remove selected column and I want with mootools to appears first on show column with an effect, like fade in.
Here are my functions:
$$('.RemoveColumn').each(function (el) {
el.addEvent('click', function (e)
{
DeleteCurrentColumn(el.get('id'));
ShowNextColumn();
})
})
function DeleteCurrentColumn(id) {
var identifier = '.columnclass' + id;
$$(identifier).each(function (el) {
el.dispose();
})
}
function ShowNextColumn() {
var firstNoDisplay = $$('.noDisplay')[0]; // Select first item with nodisplay class
var MyId = firstNoDisplay.get('id');
if ((firstNoDisplay != null) && (MyId)) {
var identifier = '.columnclass-' + MyId;
$$(identifier).each(function (el) {
if (el.hasClass('noDisplay'))
el.removeClass('noDisplay');
})
}
}
I think I have to set the opacity of all the elements of the columns at 0 and the fade in...but cant figure it out how :(
Thanks in advance!
You can use this:
function ShowNextColumn() {
var firstNoDisplay = document.getElement('.nodisplay'); // Select first item with nodisplay class
var MyId = firstNoDisplay.get('data-id');
if ((firstNoDisplay != null) && (MyId)) {
var identifier = '.columnclass' + MyId;
$$(identifier).each(function (el) {
if (el.hasClass('nodisplay')) el.fade('in');
})
}
}
Demo
What I changed:
use .fade('in') for fading io and use opacity: 0; instead of display: none;
use document.getElement('.nodisplay'); instead of $$('.noDisplay')[0]; and note the class should be all smallcase
removed the - in the classname here: '.columnclass-' + MyId;
finally i did this by following javascript..
function extractPageName(hrefString)
{
var arr = hrefString.split('/');
return (arr.length<2) ? hrefString : arr[arr.length-2].toLowerCase() + arr[arr.length-1].toLowerCase();
}
function setActiveMenu(arr, crtPage)
{
for (var i=0; i<arr.length; i++)
{
if(extractPageName(arr[i].href) == crtPage)
{
if (arr[i].parentNode.tagName != "DIV")
{
arr[i].className = "selected";
arr[i].parentNode.className = "selected";
}
}
}
}
function setPage()
{
hrefString = document.location.href ? document.location.href : document.location;
if (document.getElementById("but_a")!=null)
setActiveMenu(document.getElementById("but_a").getElementsByTagName("a"), extractPageName(hrefString));
}
if i click the ul without clicking the link.. its working.. when i click the link. it works until the page loads. after the page load, the ul back groud going default class not "selected" class..am new to tis.. am struggling so hard.. need help..??
I've added a jdFiddle with an example here:
http://jsfiddle.net/Suren/u4szQ/1/
$(document).ready(function() {
$("a.button").click(function () {
$(this).toggleClass("selected");
});
});
You've got too much javascript there.
After your posted fiddle. Here is a working fiddle.
Note you have a great deal of malformed HTML. You can't place divs in between list items. You can't have multiple objects on a page with the same ID (use a class instead).
After clicking on anchor the page is going to navigate to the url set on anchor's href attribute so whatever javascript operation you do is going to be lost after the page is loaded.
If you want to highlight the selected link the you can probably send the link id or some identifier along with the url and then check for it on page load and set the appropriate link selected.
By the way toggleClass adds or removes one or more classes from each element in the set of matched elements, depending on either the class's presence or the value of the switch argument.