Selecting a particular DOM element using JavaScript - javascript

I have the following code in my HTML:
<li class="strange">1</li>
<li class="strange">2</li>
<li class="strange">3</li>
<li class="strange">4</li>
I want to choose the exact <li> which contains number '3' as a Text.
Is there any method to choose the exact element?
Can we choose by using some OO-JS methods?

try using jQuery selector :contains
Description: Select all elements that contain the specified text.
$('li:contains("3")')
DEMO
Match exact text
As per #Raoulito mention in his comment here updated answer which match exact text using jQuery filter().
Description: Reduce the set of matched elements to those that match
the selector or pass the function's test.
$(document).ready(function(){
$("li").filter(function() {
return $(this).text() === "3";
}).css("color", "red");
});
DEMO

Try with jQuery contains
$('li:contains("3")');
Demo

Using JavaScript you can do like:
var list = document.getElementsByClassName("strange");
for (i = 0; i < list.length; i++) {
if(list[i].innerHTML ==3)
{
list[i].style.color = "blue";
list[i].style.backgroundColor = "red";
}
}
Check Fiddle.

If you want to use just javascript you can do something like that:
HTML
<ul id="ul">
<li class="strange">1</li>
<li class="strange">2</li>
<li class="strange">3</li>
<li class="strange">4</li>
</ul>
Javascript
var nums = document.getElementById("ul"); // get the ul element
var listItem = nums.getElementsByClassName("strange"); //fetch all elements inside the ul that have a class of strange
var element;
// loop through the list elements
for (var i=0; i < listItem.length; i++) {
// check whether list's inner html is equal to 3
if (parseInt( listItem[i].innerHTML) == 3) {
// set the value of element equal to the list element
element = listItem[i];
break;
}
}
console.log(element); // logs out the element that has the required value, you can use element.innerHTML to check

This only select the element which has exactly '3' as text:
$('li.strange').each(function() {
if ( $(this).text() == '3' ) {
$(this).css('color','red');
}
});
http://jsfiddle.net/dremztou/1/
$('li.strange:contains("3")').addClass('selected'); would select all the elements containing 3, including 13, 23, 33, etc.

Related

How to use javascript to replace this html?

I want to use javascript here, not jquery. How do I replace this html text?
How do I replace the 1 with a 5? I tried this but it didn't work.
document.getElementsByClassName('hello').innerHtml=5
<li class='hello'>
<a tabindex="0" aria-label="Page 1 is your current page" aria-current="page">1</a>
</li>
document.querySelector( '.hello a' ).innerHTML = 5;
document.getElementsByClassName() will give you a live HTMLCollection containing your <li> element. You need to use document.querySelector() to select the <a>.
The above solution will only work, if there is only one <a> matching that selector. Otherwise you would have to use document.querySelectorAll() and change for all elements or pick the right one.
Use,
document.querySelector(".hello a").innerHTML = 5;
The problem is that you are selecting the <li> element and not the <a> inside it.
Since you don't want to use jQuery, here is a JS function to consider:
function updateAnchorText(className, anchorText)
{
// NOTE: you could make 'anchorText' an integer value that is incremented during each update and set using .ToString()
var liElems = null;
var aElems = null;
var liElem = null;
var aElem = null;
var i,j;
try
{
liElems=document.getElementsByClassName(className);
if(liElems!=null)
{
for(i=0;i<liElems.length;i++)
{
liElem = liElems[i];
aElems=liElem.getElementsByTagName("a");
if(aElems!=null)
{
for(j=0;j<aElems.length;j++)
{
aElem = aElems[j];
aElem.innerHTML=anchorText;
}
}
}
}
}
catch(e)
{
alert("Error: " + e.Message);
}
finally
{
}
return;
}
Call it using updateAnchorText("hello", "5");

how to find upper (top layer )li in jquery?

I am trying to find all top li from html .I have this mark up
<ul class="chapters">
<li>
tc_1
</li>
<li>
tc_2<ul>
<li>tc_1_1</li>
<li>tc_1_2</li>
<li>tc_1_3</li>
</ul>
</li>
<li>
tc_3
</li>
</ul>
Expected Answer: tc_1 ,tc_2,tc_3
I tried like that actually I inspect and write my code on console .
I tried like that $('li') and I get null
Then I put a class attribute "chapters" on ul then try like this
$(".chapters") again and I got null.
how to achieve this ?
You could iterate through the childNodes of the topmost li elements and filter their first textNode:
var textArray = $(".chapters > li").map(function() {
var nodes = this.childNodes, len = nodes.length;
for ( var i = 0; i < len; i++ ) {
if ( nodes[i].nodeType === 3 && $.trim(nodes[i].nodeValue).length ) {
return $.trim(nodes[i].nodeValue);
}
}
}).get();
console.log(textArray.join());
Here is a demo.
$('.chapters > li').each(function(){
alert($(this) .clone()
.children()
.remove()
.end()
.text());
});
JSFIDDLE
for more explanation you can read http://viralpatel.net/blogs/jquery-get-text-element-without-child-element/
This locates the ul, takes its immediate children (each of the lis), then removes any subchildren, .end(), to return to the lis, and .text() to get the contents.
$("ul").clone().children().children().remove().end().text()
This returns
"tc_1
tc_2
tc_3"
because of the line breaks and whitespace in between.
$(".chapters li").text()
should work.

Javascript - get text between <li> by ID

I'm trying to write some javascript that will grab the inner text of li elements (1-16) and put them into hidden fields.
var myValue9 = document.getElementById("fileName9").value;
oForm.elements["fileName9"].value = myValue9;
<input name="fileName9" type="hidden" id="fileName9" />
<li id="wavName9"> Some Text </li>
How do I return the text in between the <li> and put into the hidden field?
Simple JavaScript:
document.getElementById("fileName9").value = document.getElementById("wavName9").innerText;
You could, in this case, also use innerHTML but that would also give you the HTML the element contains.
LI tags don't have a .value property. Using plain javascript, you could do it this way:
oForm.elements["fileName9"].value = document.getElementById("wavName9").innerHTML;
Or, to do all of them from 1 to 16, you could use this loop:
for (var i = 1; i <= 16; i++) {
oForm.elements["fileName" + i].value = document.getElementById("wavName" + i).innerHTML;
}
Or since you also tagged your post for jQuery, using jQuery you could do it like this:
$("#fileName9").val($("#wavName9").text());
Or, to do all of them from 1 to 16:
for (var i = 1; i <= 16; i++) {
$("#fileName" + i).val($("#wavName" + i).text());
}
Use jQuery to do it.
var myvar = $("#wavName9").html()
I think this will do in for all li's
$("li[id^=wavName]").each(function(){
var $this = $(this);
$this.closest("input[id^=fileName]").val($this.text())
});
Create your li's with id's following such a structure: listitem-n, where n is 1-16 and input fields following the same structure hiddeninputs-n (n = 1-16)
using jfriend00's code, add it in a loop that will traverse 16 times, incrementing a count variable that you will use to transfer the data from list items to hidden inputs
var count = 0;
for( i=0; i < 16; i++){
count ++;
$("form #hiddeninput-"+count).val($("#listitem-"+count).text());
}
Better validate the code, but there's the general idea.
You could also create the hidden fields in javascript from scratch, which would make the code abit more stable IMO as there's less chances of a hidden field missing in the form when the js is executed.
Using jQuery:
$('#fileName9').val($('#wavName9').text());
Note that you can change .text() to .html() to return the HTML structure rather than just the text.
You could automate this for multiple <li>'s like so:
$('li[id^="wavName"]').each(function () {
var number = this.id.replace('waveName', '');
$('#fileName' + number).val($(this).text());
});
This selects all <li>'s who's id starts with "wavName" and stores the text within the <li> tag in the hidden input who's id starts with "fileName" and ends with the same integer as the <li> tag.

How to determine DOM position of element in a series of elements when clicked

In this scenario, I have a series of list items each of which has a corresponding content area. When clicking a list item, a corresponding content area is manipulated (i.e., if the first list item is clicked, then the first content section would be manipulated).
<ul>
<li>List item</li>
<li>List item</li>
<li>List item</li>
</ul>
<div>
<section>Content section</section>
<section>Content section</section>
<section>Content section</section>
</div>
My old-school way of doing this was giving each list item and section an id, such as "li1", "li2", etc. and "section1", "section2", etc. I would then parse the integer off the id of the element that was clicked and manipulate the corresponding section.
Is there a way to determine this without needing extra id attributes? E.g., if I click the 3rd list item and know that is the 3rd, I can use document.querySelector('div:nth-child(3)') to manipulate the third content section. My question is how to know it was the 3rd element in a series that was clicked to begin with.
My first-thought solution was something like this:
var target = e.target;
var parent = e.target.parentNode;
for (var i in parent.childNodes) {
if (parent.childNodes[i].nodeType == 1 && parent.childNodes[i] == target) {
// found it... i+1
}
}
This seems like a rather expensive operation compared to just using IDs, especially if there were many more list items and content sections. I'm hoping there is some node attribute that will give me the correct DOM position that I haven't yet found.
Modern browser-only solutions welcomed.
So i have no ide what you are doing here but there must be a more data oriented approach to this.
Like both the li and the section is referring to the same Product or Person or something so you can find it by that reference.
otherwise you can use the previousElementSibling method to count your location like this
var position = function(el) {
var count = 1;
for(var cur = el.previousElementSibling;
cur !== null; cur = cur.previousElementSibling) {
count++;
}
return count;
};
gl
I’d use something like:
var target = e.target,
i = 0;
while(target = target.previousSibling) {
i += target.nodeType == 1;
}
alert('you clicked on '+i);
Fiddle: http://jsfiddle.net/K5Qg9/1/
You can also try using a data lib or assign stuff to the element expano onload:
var elems = document.getElementsByTagName('li'),
i=0;
for(; elems[i]; i++) {
elems[i].rel = i;
}
Then just fetch e.target.rel onclick. Fiddle: http://jsfiddle.net/UnrCt/
If you can use jQuery: $(elem).index()
Update 2016
Well I've run into this issue again nearly 5 years later only this time I used a much simpler solution using a built-in Array method:
var index = Array.prototype.indexOf.call(event.target.parent.children, event.target);

Pure javascript way to update CSS class attribute from all list items?

I'd like to use Javascript (not jquery) to access all items in a <ul> list and remove the active class from everything except my chosen menu item.
Here is the list:
<ul id='flash-menu'>
<li id="menu1" class='something active'>item 1</li>
<li id="menu2" class='somethingelse'>item 2</li>
<li id="menu3" class='somethingelse'>item 3</li>
</ul>
This is my javascript:
function updateMenu(view_name) {
var list_items = document.getElementById('flash-menu').childNodes;
for (var i=0 ; i<list_items.length ; i++){
list_items[i].className = list_items[i].className.replace('/\bactive\b/','');
}
document.getElementById(view_name).className += " active";
}
The last line of the Javascript (adding the active class) works, but I don't think I'm accessing the list items right to remove the classes from the other items. Any suggestions? - thanks!
First off, your regex is wrong:
list_items[i].className.replace(/\bactive\b/, '');
Note: No quotes on regex'es in JavaScript. A slighty altered, working version is available on JsFiddle.
Furthermore, I get a few instances of HTMLTextElements in list_items. They're breaking the loop (Fx3.6/Win7) when trying to access the non-existing className attribute. You can avoid this by either using:
var list_items = document.getElementById('flash-menu').getElementsByTagName('li');
// Selecting _all_ descendant <li> elements
or by checking for the existence of .className before read/write within the loop body (example). The latter is probably the cleanest choice since it still only affects direct children (you may have several levels of <ul>s in each <li>).
I.e.,
function updateMenu(view_name) {
var list_items = document.getElementById('flash-menu').childNodes;
for (var i=0, j=list_items.length; i<j; i++){
var elm = list_items[i];
if (elm.className) {
elm.className = elm.className.replace(/\bactive\b/, '');
}
}
document.getElementById(view_name).className += ' active';
}
You can use javascript function getElementsByTagName:
var listitems = document.getElementsByTagName("li");
this would return an array of all the lists and can be iterated for each list element and processed as required.
You can try:
In the case that you can have more than ul, first you have to get all references to them and then process each ul:
var uls = document.getElementsByTagName("ul");
for (uli=0;uli<uls.length;uli++) {
ul = uls[uli];
if (ul.nodeName == "UL" && ul.className == "classname") {
processUL(ul);
}
}
An illustration of proccessUL can be:
function processUL(ul) {
if (!ul.childNodes || ul.childNodes.length == 0) return;
// Iterate LIs
for (var itemi=0;itemi<ul.childNodes.length;itemi++) {
var item = ul.childNodes[itemi];
if (item.nodeName == "LI") {
// Iterate things in this LI
in the case that you need it put your code here
.....
}
}
}
Of course you can also use: item.className = "classname"; if you dont need to iterate between childs of LI
document.getElementById('flash-menu').childNodes will also include white space nodes.
function updateMenu(view_name) {
var list_items = document.getElementById('flash-menu').getElementsByTagName('li'), i;
for (i=0 ; i<list_items.length ; i++){
if (list_items[i].className.indexOf('active') > -1) {
list_items[i].className = list_items[i].className.replace(/\bactive\b/,'');
}
}
document.getElementById(view_name).className += " active";
}
i agree with jensgram,and you'd better code like this:
list_items[i].className.replace(/\bactive\b/g, '');
add the regex string a 'g'
g is for Global ,using ‘/g’ can replace all the same Which Match the regex ,but if you don't use '/g',you just replace the first string .
like this :
var test= "testeetest" ;
alert(test.replace(/e/,"")) ;//result
: tsteetest but using 'g' var
test= "testeetest" ;
alert(test.replace(/e/g,"")) ;//result
: tsttst
Have a look at this here: https://developer.mozilla.org/en-US/docs/Web/API/element.classList
It helped me a lot with finding class elements!
This is my solution, maybe not the best, but for my works fine.
window.addEventListener('load', iniciaEventos, false);
function iniciaEventos(e)
{
var menu = document.querySelectorAll('nav li');
for(var i = 0; i < menu.length; i++ )
{
menu[i].addEventListener('mousedown', clickMenu);
}
}
function clickMenu()
{
var menu = document.querySelectorAll('nav li');
for(var i = 0; i < menu.length; i++)
menu[i].classList.remove('active');
this.classList.add('active');
}

Categories

Resources