I'm attempting to add the different classes from each separate anchor to their parent <li> tags. The general HTML code looks like this:
<ul class="list">
<li>
<div>Title Text</div>
<span class="tag">Class1 Link, Class2 Link, Class3 Link</span>
</li>
<li>
<div>Title Text</div>
<span class="tag">Class4 Link, Class5 Link, Class6 Link</span>
</li>
</ul>
The closest jQuery scripting I have works to an extent, but it is merely grabbing the first anchor class it encounters and adds it to every <li> tag in the unordered list.
$(window).load(function () {
$('span.tag a').each(function(){
var tagClass = $(this).attr("class");
$('span.tag a').closest('li').addClass(tagClass);
});
Any help in getting this to work properly would be much appreciated.
You should use $(this) instead of the $('span.tag a'), the latter select all the a elements and subsequently all the parent li elements. You can also use the .addClass() callback function:
$('ul.list > li').addClass(function() {
return $('span.tag a[class]', this).map(function() {
return this.className;
}).get().join(' ');
});
http://jsfiddle.net/UXSa7/
You should use the this reference to find the correct parent for that instance, rather than selecting them all again, which causes jQuery to take the first a tags parent li, then takes the class name of that element.
$(window).load(function () {
$('span.tag a').each(function(){
var tagClass = $(this).attr("class");
$(this).closest('li').addClass(tagClass);
});
});
You can also use $(function(){ instead of $(window).load(function () { to make this run as soon as the DOM is ready, rather then when all assets are loaded.
Related
I've tried using .closest, .parents and .eq to get this div selected on page load, and can not figure out why it is not working. My HTML is:
<div class="top">
<ul>
<li>
<div></div>
<ul class="first"></ul>
<div></div>
<ul class="first active">
<li><a class="current"></a></li>
</ul>
<ul class="first"></ul>
</li>
</ul>
So on page load I want the div above 'active' to change colors, but can't get it to work. I've tried:
$(document).ready(function () {
if ($('.current').is(':visible')){
$('.current').closest('div').addClass('active');
});
You have incorrect selector to target required div. You need to first traverse to parent ul element and then to its previous sibling div. Like this:
$('.current:visible').closest('ul').prev().addClass('active');
I think you are trying to select the prev sibling.
$('.current:visible').each(function(){
$(this).closest('ul').prev('div').addClass('active');
})
This should work:
$(document).ready(function () {
if ($('.current').is(':visible')){
$('.current').parents('.active').prev('div').addClass('active');
});
The div above .first.active in the source is a sibling, not a parent, hence why closest() doesn't work for you in the method you're using.
You can use closest() to get the parent ul, then prev() to get the div you require. Try this:
if ($('.current').is(':visible')) {
$('.current').closest('ul').prev('div').addClass('active');
});
.closest will look up the DOM tree to find the closest matching "parental" element. The div you are trying to get is actually a "sibling" of the <ul> so .closest won't find it.
So you would need to go up to the <ul>, then get the element "previous" to that.
$(document).ready(function () {
if ($('.current').is(':visible')){
$('.current').closest('ul').prev('div').addClass('active');
});
I am trying to clone an li element but without the tags.
I am have tried many different ways but I can make it seem to work.
When I take a look at the html of the li element it still selects the span tags.
Below is the code I am using. Any help would be really appreciated. Thanks!
<ul class="todo_list_items" data-category_id="44">
<li class="tasks" data-task_id="30">
<!-- Don't want to select this span class -->
<span class="modify_tasks">
<a href='#' class='delete_task_name'>Delete</a>
<a href='#' class='edit_task_name'>Edit Task</a>
</span>
Test
</li>
</ul>
<script>
$(document).on("click", ".edit_task_name", function () {
var task_id = $(this).data("task_id");
var previous = $(".tasks[data-task_id=30]").not(".tasks[data-task_id=30] > span").clone();
console.log(previous.html());
});
</script>
Just clone it and then empty it:
var previous = $(".tasks[data-task_id=30]").clone().empty();
EDIT: If you only want to remove the span and not other content, then just remove the span from the clone:
var previous = $(".tasks[data-task_id=30]").clone();
previous.children("span").remove();
not() will check against elements in the set, in your case the set consists of only $(".tasks[data-task_id=30]"). not() is testing the span inside it to see if it matches its own parent, so not wont be adjusting your jQuery object for cloning there. An alternative way to achieve what you want might be code similar to this:
var $tasks = $(".tasks[data-task_id=30]"),
$modifyTasks = $tasks.children('span').detach(),
$cloneOfTasks = $tasks.clone();
$modifyTasks.prependTo($tasks);
$cloneOfTasks.appendTo($tasks.parent());
.detach() removes the span without losing events and data so you can put it back in when your done making your clone.
Alternatively this code might be easier to interpret and use:
var $tasks = $(".tasks[data-task_id=30]");
$('ul.todo_list_items').append($tasks.contents().not('span').clone().wrap('<li class="tasks" data-task_id="30">').closest('li'));
This uses .contents() to grab whats inside the task so you can run not against it. The closest('li') part is needed to ensure the li wrapped around the new element is returned for appending to the ul.
I have the following code:
<div id="nav">
<ul>
<li id="tabOne" class="first current">Page One</li>
<li id="tabTwo">Page Two</li>
<li id="tabThree"><a href="./CS3.html" target="SheetView">Page Three</li>
<li id="tabFour">Page Four</li>
<li id="tabFive">Page Five</li>
<li id="tabSix">Page Six</li>
</ul>
This loads the selected page into an iframe named "SheetView." What I need to do is use JavaScript to alter the class when an option that isn't the currently selected on is clicked. I should say that I have the current class already setup in my CSS. I just have no way to trigger it.
I thought adding an onlick event to the <UL> up there and calling onclick="Javascript:changeCurrent();" but there is the problem (four actually):
Is <ul onclick="JavaScript:changeCurrent();> where I need to have the event?
What is the resulting JavaScript to make the change happen?
How can I cause the first option to be set as current by default?
Is there a way to keep the currently selected option from being an active link?
I found a few different examples but I couldn't tailor them to work for me. Any help would be most appreciated.
Since you specified that you wanted a non-jQuery response, here's a function that will toggle appropriately:
function toggleNavSelected(el){
var list = document.getElementById('nav').children[0];
for(var i=0; i<list.children.length; i++){
var cur = list.children[i];
if(el==cur){
cur.classList.add("current");
cur.firstChild.onclick = (function(){
toggleNavSelected(this.parentElement);
return false;
});
} else {
if(cur.classList.contains("current")){
cur.classList.remove("current");
}
cur.firstChild.onclick = (function(){
toggleNavSelected(this.parentElement);
});
}
}
}
Either add an onclick handler to each LI (onclick="toggleNavSelected(this);") or execute the following after the menu has loaded:
var list = document.getElementById('nav').children[0];
for(var i=0; i<list.children.length; i++){
var el = list.children[i];
el.firstChild.onclick = (function(){
toggleNavSelected(this.parentElement);
});
}
Demo: http://jsfiddle.net/bWY7P/2/
(note: The JSFiddle script has a small difference; it adds a return false; to the onclick function so that you can play with it without the links actually following the HREF attribute. Do not use that line in your live code)
Explanation:
The function looks at each LI element within the #nav element.
If that element is the element passed to the function, then it adds the class .current.
Otherwise, it removes the class .current (if present).
The second part binds a function to the onclick event of each a element that calls the toggleNavSelected() function and passes its parent element (the li) as the argument.
1) if you want to change the currently selected class when you click an item, put the onclick into the li item
2) using jquery would be very easy here, all you have to do is import the jquery file with the <script> tag and you're ready! For example, you could do onclick="changeClass(this);" on the <li> tag and in a normal JavaScript file or in a script tag:
function changeClass(this){
$('#nav li').attr("class","");
$(this).attr("class","current");
}
Replace the 'current' with the class name you want to use
3) it should already be set as current
4) use the :visited CSS selector to change what colour followed links look like eg:
a:visited{
color: #000000;
}
First of all you should set the event handler from a separate script, not from an onclick attribute. You don't repeat your code that way and have anything in one place. The HTML is also much cleaner.
Using jQuery it would be as easy as:
var menuLinks = jQuery( '#nav a' );
menuLinks.on( 'click' function() {
menuLinks.removeClass( 'active' );
$( this ).addClass( 'active' );
} );
You could also do that in plain JS, but using some library keeps you out of the trouble of browser incompatibilities.
I have a list with links:
<li class="link-1">One</li>
<li class="link-2">Two</li>
<li class="link-3">Three</li>
..
user clicks on any link, then with jQuery I want to display the content of the link.. somthing like:
$(".link-??? a").click(function() {
alert($(".link-??? a").html());
})
something like this. I am not going to create X function (as the number of the links), so what can I do? I should replace the ??? in somtehing else..
You could do:
$('li[class^="link"] a').click(...
However this would only work if the li have only one class or if the link-X class is the first in the list.
Inside the handler you can use $(this) to refer to the a element:
alert($(this).text());
Much better would be to give the li elements a common class:
<li class="link">One</li>
<li class="link">Two</li>
<li class="link">Three</li>
$('.link a').click(... will be much more reliable.
Give each element the same class. Then in your javascript reference this within your function. Check out the link below to see a working example
http://jsfiddle.net/kprgr/2/
<li class="link">One</li>
<li class="link">Two</li>
<li class="link">Three</li>
$(".link").click(function() {
alert($(this).find("a").html());
});
Try..
$(".link-??? a").click(function() {
alert(this.innerHTML);
})
Inside the click event, this should refer to the element that was clicked.
You could also do..
alert($(this).html());
..but the first way is simpler, and faster.
I have some HTML that looks like this:
<ul class="faq">
<li class="open">
<a class="question" href="">This is my question?</a>
<p>Of course you can, it will be awesome. </p>
</li>
</ul>
Using CSS I'm setting the p tag to display:none;. I want to use jQuery to display or hide the p tag when the anchor is clicked, but I'm having some troubles with the sibling selector.
Just trying to get the selector working, I tried:
$("a.question").click(function () {
$(this + " ~ p").css("background-color", "red");
});
to test it out. Seemingly, the sibling selector can't really be used like that, and as I'm completely new to jQuery I don't know the appropriate means to make that happen.
Try using:
$(this).siblings('p').css()
$(this).next("p").css("...")
the "p" above is optional, if you just want the next non-whitespace node in the DOM.
I want to use jQuery to display or hide the 'p' tag when the anchor is clicked
Since you mentioned that you'd like to toggle the 'p' tag when the anchor is clicked, I'd do:
$("a.question").click(function (event) {
$(this).siblings('p').show(); //toggle the p tags that are siblings to the clicked element
event.preventDefault(); //stop the browser from following the link
});