lastElementChild for selecting the last li in ul? - javascript

I'm trying to select the last item in
<ul id="list_1">
<li>Apple</li>
<li>Orange</li>
<li>Grape</li>
<li>Banana</li>
<li>Mango</li>
</ul>
so I made
var ul = document.getElementById("list_1");
var mango = ul.lastElementChild;
So far, the selection seems to be working. But I'm not sure if I used lastElementChild correctly. Would
var mango = ul.getElementsByTagName("li")[4];
be the proper one to use?

That use of lastElementChild is fine, it will always refer to the last element that's a direct child of the list.
ul.getElementsByTagName("li")[4] will always give you the fifth, which may not be the last (although it is in this case).
Beware, though, that if you need to support IE8, IE8 doesn't support lastElementChild. (IE9 and up do.) To include IE8, you can get the last element reliably like this:
var ul = document.getElementById("list_1");
var mango = ul.children[ul.children.length - 1];
Unlike childNodes, children only contains child elements and not other kinds of children (text nodes and such), and it's supported on IE8.

Related

How to get Value / Text of a List item Javascript

how can i get the Value / Text of a <li> item ?
I found on the internet much ways to get the value for a dropdown list.
But not for a <li> item.
This is what I have tried so far:
var listt = document.getElementById('content1');
var selectedvalue = [listt.selectedIndex].text;
You can use the innerText property for most browsers, but the textContent property for Firefox:
<ul>
<li id="myLi">Hello, world</li>
</ul>
var li = document.getElementById("myLi")
console.log(li.textContent || li.innerText);
Here is a fiddle to demonstrate.
If you are using jQuery (you say you are, but I see no evidence) it would be as simple as using the .text() function:
$("#myLi").text();
If your <li> contains HTML markup too, you may want that. In this case you need to use the innerHTML property:
document.getElementById("myLi").innerHTML;
Again, jQuery has it's own equivalent .html() which caters for all sorts of different browsers:
$("#myLi").html();
Assuming myLi is a reference to the <li> element you want to get the text of, it's as simple as:
myLi.innerText
Note that <li> elements don't have values, because they're not inputs. They have content which can be a string of text or HTML defining other page elements. If your <li> element contained other elements, and you wanted the HTML of those as a string, you could instead do:
myLi.innerHTML
What's the difference? Let's assume your HTML looked like this:
<li><span>Some text</span></li>
Then
console.log(myLi.innerHTML); // outputs: <span>Some text</span>
console.log(myLi.innerText); // outputs: Some text
I would just use innerHTML if your list item has an ID or class name and assuming there is no other html in your list item.
<ul>
<li class="list-item">Item1</li>
<li class="list-item">Item2</li>
<li class="list-item">Item3</li>
</ul>
<script>
var list = document.getElementsByClassName('list-item');
var listArray=[];
for (var i=0;i<list.length;i++){
listArray.push(list[i].innerHTML);
console.log(listArray[i]);
}
</script>
//output
Item1
Item2
Item3
You could also try using the textContent property perhaps or innerHTML for that matter if you wanna get plain text.
var li_item=document.getElementById('content1');
console.log(li_item.textContent)

How does one determine the number of a list item in an ordered list using JavaScript?

Given an ordered HTML list, is there any way, given the list element, of determining it's number in JavaScript, besides looking at its location in the list?
For example, suppose I have a list
<ol start="4" type="i">
<li>First</li>
<li>Second</li>
</ol>
which is rendered as
iv. First
v. Second
What is the best way using JavaScript (including jQuery) that, given on of the LI, to find out it's number?
The naive way is to look at the item's index, add the start value, and translate the type. But I am wondering if there's a better way.
an example is to add an index property to the list item:
lets say your list has an id='ordered'
var ol = document.getElementById('ordered');
// select the list items
var lists = ol.getElementsByTagName('li');
// now loop through the items and set a custom property 'index'
var l = lists.length; // total items
for (var i=1;i<=l;i++){
list[i].index = i;
}
now your list item will have an index property that you can access through javascript to determine its position.
<ol id='ordered'>
<li index='1'>First</li>
<li index='2'>Second</li>
</ol>
Looking at http://www.w3.org/TR/html-markup/li.html I'd say using the value member.
note: this is in HTML5. in HTML4.01 both ol.start and li.value were deprecated. This means that this solution will probably work reliably only on browsers with HTML5 support.
The MDC documentation for the <li> element mentions the value attribute, which is supposed to do just that. It was deprecated in HTML 4 but has been reintroduced in HTML 5. If your browser supports it, you should be able to write:
$("li").prop("value"); // jQuery 1.6 and higher
$("li").attr("value"); // jQuery 1.5 and lower
I was, however, unable to use that attribute in Firefox 3.6 (it always returns -1). I created a fiddle if you want to test your browser's support for that feature.
Nice questions :)
I would say, better to inject data into each li elements, you could put some HTML attributes inside the li but I am afraid when you do HTML validation, it will reject it.
So this is the code,
var lis = $("ol li").each(function(i, el)
{
$(this).data("index", i);
});
and when you render your lovely number, do this:
$(this).data("index");
:)

Javascript Changing the selected Menu items class

Assume that I have such menu
<ul id="leftMenu">
<li class="selected">Foo1</li>
<li>Foo2</li>
<li>Foo3</li>
<li>Foo4</li>
<li>Foo5</li>
<li>Foo6</li>
</ul>
Now via javascript, I want to change the highlighted one thus remove the "selected" from the current one and add to the next one
What I need is, first remove the class from the currently selected one, than add to the next.
How can this be achieved?
EDIT: I use this for an embedded system WITHOUT mouse or jquery but remote control and plain javascript so up and down are my only options, no hover allowed :S
Using javascript for this would be an overkill in this day and age.
Since you tagged this css, may I suggest the following CSS-only method, also known as the :hover pseudo-class:
ul#leftMenu li:hover {
color: red;
}
If it were me, and I knew the menus weren't monstrously huge, I'd remove the class from all the <li> elements and then add it to the one I wanted.
var lis = document.getElementById('leftMenu').getElementsByTagName('li');
for (var i = 0; i < lis.length; ++i)
lis[i].className = lis[i].className.replace(/\bselected\b/g, '');
Now, as to how to put the class back, well that depends on how you've found your new favorite <li>. If it's in an event handler, then the event object will refer to it as the "target". You'd thus just append "selected" to the class name.

get the text in a list item and modify it with javascript

I have a bunch of HTML list items and what i want is to be able to read the text of a list item and then be able to give the user the ability to modify it. the structure of each list item is the same:
<li id='1' class='attachment'>
<a href='link.html'>TEXT VALUE I WANT TO READ AND MODIFY</a>
<a href='link2.html'><img src'img1.jpg'></a>
<a href='link3.html'><img src'img2.jpg'></a>
</li>
at the moment i am able to get the list item using
li = document.getElementById(id);
but if i get it to print out something like
li.childNodes[?]
li.childNodes[?].data
li.childNodes[?].nodeValue etc...
i am never able to get it to print "TEXT VALUE I WANT TO READ AND MODIFY", it always gives null, undefined or [object Text] or something similar. any help would be greatly appreciated.
You need to get the textContent or innerText properties:
var li = document.getElementById(id);
var t = "textContent" in li.childNodes[0] ? "textContent" : "innerText";
alert(li.childNodes[0][t]);
innerText is implemented by IE and textContent is implemented by standards compliant browsers.
Alternatively, if you're certain that the element's first child will be a text node, you can use
alert(li.childNodes[0].childNodes[0].nodeValue);
Based on your comment below, we can make a safe assumption that white-space is interfering with the childNodes property in your example. This is normal - childNodes returns both elements and text nodes that are direct descendants of the given element. The alternative is to use children in newer browsers:
// 1st example using `children` instead
var li = document.getElementById(id);
var t = "textContent" in li ? "textContent" : "innerText";
alert(li.children[0][t]);
// 2nd example using `children` instead
alert(li.children[0].childNodes[0].nodeValue);
children isn't supported pre Firefox 3.5 and in other older browsers. You could use li.getElementsByTagName("a") for the example that you've posted - but bear in mind that it will return all <a> element descendants, not just immediate children.
What about this:
var li = document.getElementById(1);
var a = li.getElementsByTagName('a');
alert(a[0].innerHTML);
And before anyone can suggest to just use jQuery, here's the equivalent:
$('li#someid a').html();
In my opinion, if you're doing fine without jQuery, don't use it.

how to select 2nd <LI> element using javascript?

Using JavaScript, how can I dynamically change one of the list-items below from this:
<ul class="tabbernav">
<li class="tabberactive"><a title="All">All</a></li>
<li class=""><a title="One">One</a></li>
<li class=""><a title="Two">Two</a></li>
<li class=""><a title="Three">Three</a></li>
</ul>
to
<ul class="tabbernav">
<li class="tabberactive"><a title="All">All</a></li>
<li class=""><a title="One">One</a></li>
<li class=""><a title="Two">-----------NEW LIST ITEM CHANGED---------</a></li>
<li class=""><a title="Three">Three</a></li>
</ul>
I guess you could use getElementsByTagName inside of the ul to get all your list items inside an array. Then you can just edit the third element in your array, with index number 2.
var lItems = document.getElementsByTagName("ul").getElementsByTagName("li");
lItems[2].innerHTML = "<a title='Two'>----NEW LIST ITEM CHANGED-----</a>";
That will ofcourse get all ul elements on the page, and might lead to some strange results if you have more than two uls in your document. But you get the idea, right? Just ask some more if you don't understand what I'm trying to say.
Okay, the above code doesn't really work properly. I've modified my code a bit, but that also included a change in your HTML, as i presume you'll only have one ul "tabbernav", thus I changed it from class="tabbernav" to id="tabbernav". This is the code to do what you want.
var ul = document.getElementById("tabbernav");
var liArray = ul.getElementsByTagName("li");
for (var i = 0; i < liArray.length; i++) {
if(liArray[i].childNodes[0].title == "Two") {
liArray[i].innerHTML = "Your desired output";
}
}
Hope that helps you some more :)
I also suggest using jQuery, which makes selections like this trivial. In your case, you can use the :eq psuedo-selector to get the second line element:
$('.tabbernav li:eq(1)')
This selects the DOM element which is the second li (indexes start at 0) in an element with the class tabbernav. It returns a jQuery object which you can chain other methods to. Changing the inner HTML is done with .html('Your html here').
This is how you select the third Li element of your Ul list in pure JavaScript.
document.querySelectorAll("li")[2].innerHTML = "vasile";
Replace "Vasile" with your desired text.
var list = document.getElementsByTagName("li");
list[2].innerHTML = "<a title='Two'>------NEW LIST ITEM CHANGED----</a>";
this will work perfect
I know that this question is old but since it's still open, see how I modified the first answer. I feel someone else might need it.
>var lItems = document.getElementsByTagName("ul")[0];
>>var nth = lItems.getElementsByTagName("li")[2];
>>>nth.innerHTML = "<a title='Two'>----NEW LIST ITEM CHANGED-----> </a>";
So that basically solves it up by specifying the position of the lItems in particular to grab and in this case [0]. The code will not work properly if that position is missing because getElementsByTagName(NAME) returns a collection of html elements bearing that NAME specified. So that if you don't specify which among them all, the code fails.
If you like code reuse, see a function you can use for that. You just need to specify the parent element and its position and the childNode position and you get the same thing.
>var nthChild = function(parent, pos, childPos){
>>parent = document.getElementsByTagName(parent)[pos];
>>>return parent.children[childPos];
>>>>};
//used thus:
>nthChild("ul", 0, 2).innerHTML = "<a title='Two'>----NEW LIST ITEM CHANGED-----> </a>
";
How do you identify which <li> is the one you want to modify?
If you're doing it by index you could do something like this I think:
var list = document.getElementById("listid");
list.childNodes[2].innerHtml = "<a title='Two'>-----------NEW LIST ITEM CHANGED---------</a>";
Look into using a Javascript library such as JQuery. That will make your life a lot easier. Then you can do something like this:
$('li a[title=Two]').text('Changed Text Goes Here');
You'll need to check my syntax (not sure about the text() function), but it's easy enough to look up in JQuery's api docs.

Categories