How can access bunch of <li>? - javascript

I have a list of texts and I want to change their innerHTML. how can I do that by javascript if I have thousands of li tag (whose data come from database)?
<div>
<ul>
<li>a</li>
<li>as</li>
<li>asd</li>
<li>asds</li>
<li>asdsa</li>
<li>asdsad</li>
<li>asdsadz</li>
<li>asdsadzc</li>
....
.....
</ul>
</div>
-Thanks.
Update
JS code being used:
function a(){
var parent = document.getElementById("z");
var i = 0;
for(i = 0; i <= parent.children.length; i++){
if(parent.children[i].tagName == "LI"){
if(i%2!=0){
parent.children[i].innerHTML="ok";
}
}
}
}
document.onload=a(); // this didn't work. so I called the function in body tag instead of that.
<body onload="a();">

Have you tried using getElementsByTagName ? Sonds like it would help you find the elements you're trying to work with.
Edit
If you can give an Id to the UL element that holds the li's you're trying to process, you could do something like this:
var parent = document.getElementById("yourID");
var i = 0;
for(i = 0; i < parent.children.length; i++){
if(parent.children[i].tagName == "LI") {
//do what you want...
}
}
EDit 2
You have to change the last line on your script:
document.onload=a();
With this one: window.onload=a;
That'll get your function to execute on the onLoad event. Note that there might be some crossbrowser incompatibility, I would suggest researching a bit on how to execute functions on the onload event on a crossbrowser manner, or just adding this to your body tag:
<body onload="a();">

Given the - not so far fetched - precondition you wish to use jQuery, you can select them and iterate over them with "each".
$("li").each(
function() { $(this).html("changed content"); }
);
If you are not using jQuery, using a js-library that helps you out with the quircky dom is probably not a bad idea...
The general idea
Select nodes
Iterate and change html
is always the same.

Related

How to delete specified children?

<body>
<p>dfg</p>
<h1>yoyo</h1>
<h1>yoyo2</h1>
<ul>
<li>somo</li>
</ul>
</body>
For example I want to delete only h1 from body. The other children should stay
You can use a CSS selector.
You can do it using jQuery or VanillaJS. For instance, here is my code for VanillaJS.
var headers = document.querySelectorAll('h1');
headers.forEach(function(h) { h.remove(); });
This will effectively remove the headers from the DOM.
We can create our own fn to remove node by tag for usability. please review this one:
function rem(tag) {
var h = document.querySelectorAll(tag); //return NodeList not array
[].forEach.call(h,function(elm) {
elm.parentNode.removeChild(elm);
});
}
//passing tag to remove
rem('p');
<body>
<p>dfg</p>
<h1>yoyo</h1>
<h1>yoyo2</h1>
<ul>
<li>somo</li>
</ul>
</body>
You can use getElementsByTagName to get an HTMLCollection (not an array) of the h1 tags, which is live.
When an element is removed, the elements update their indexes accordingly which means that you have to remove each element from the last position to the first.
Javascript solution:
var h1Elems = document.getElementsByTagName('h1');
for(var i = h1Elems.length - 1; i >= 0; i--){
h1Elems[i].parentElement.removeChild(h1Elems[i]);
}
See this code working in this jsfiddle

Adding javascript programmatically to dynamicly generated hyperlinks with the same id

Might be a strange setup, but I have a number of hyperlinks on the page with the same id (yeah, I know, but it was not my choice and I cannot change that at this time plus those hyperlinks are generated dynamically).
Example:
<div id="Links">
<div class="myItem">Some text</div>
<div class="myItem">More text</div>
<div class="myItem">Even more text</div>
</div>
Now I need to attach javascript to those links dynamically (the hyperlinks are also dynamically generated). The easiest way I see is by getting all hyperlinks on the page and then check the hyperlink id to ensure I only take care of those that have id of "myLink" (I have many other hyperlinks on the page).
I thought of using getElementById but that would only grab the first element with the specified id.
am attaching javascript to those links using the following:
window.onload = function() {
var anchors = document.getElementsByTagName('a');
for(var i = 0; i < anchors.length; i++) {
var anchor = anchors[i];
if (anchor.id='myLink')
{
if (anchor.getAttribute("LinkID") != null)
{
anchor.onclick = function() {
MyFunction(this.getAttribute("LinkID"), false);
return false;
}
}
}
}
}
The above function works fine, but it creates another issue - affects the styling of other hyperlinks on the page. So I was wondering if there is a way to accomplish the same thing but without affecting other elements on the page?
This is more modern and corrects your equality test:
window.onload = function() {
var anchors = document.getElementsByTagName('a');
for(var i = 0; i < anchors.length; i++) {
if (anchor[i].id==='myLink' && anchor[i].getAttribute("LinkID") !== null)
{
anchor[i].addEventListener("click", function() {
MyFunction(this.getAttribute("LinkID"), false);
}
}
}
}
Even with your original code, I don't see anything that would interfere with styling in the code. Can you elaborate as what styling changes you were getting?
You can use an attribute selector and document.querySelector([id=<id>]) pretty reliably depending on your browser support situation: http://codepen.io/anon/pen/YwLdKj
Then, of course, loop through that result and make subsequent changes or event bindings.
If not, you could use jQuery (referenced in above code pen).
You might also use JavaScript event delegation and listen for all click events, check if the user is clicking a link with the correct id.
If a combination of tag == 'a', class == "myItem" and presence of a LinkID attribute is sufficient to identify nodes requiring a click handler they could be identified using multiple CSS selectors. If this is not possible however, a query selector not using id can create a list of nodes to be checked for id, as for example:
function callMyFunction()
{ MyFunction(this.getAttribute("LinkID"), false);
}
function addClickHandlers()
{ var list = document.querySelectorAll("a[LinkID]")
var i, node;
for( i = 0; i < list.length; ++i)
{ node = list[i];
if(node.id == "myLink")
{ node.onclick=callMyFunction;
}
}
}
See also running a selector query on descendant elements of given node if of interest.

Javascript efficient approach for changing inner dom elements of a list item

I have a unordered list with 12 list items inside it
<ul class="rb-grid" id="list">
<li class="view view-fifth">
<div class="mask">
<h2>Article Name</h2>
<p>Brief</p>
Read More
</div>
</li>
...
...
</ul>
Now what i want is that on page load i have to change the content of these h2 and p tags, now while i can do this by hardcoding every list item, but can anyone tell me a better way to make all changes at once by using javascript or jquery anything....
Now i found something like this in dojo , this will make clear what i want actually -
var items = registry.byId("list").getChildren();
array.forEach(items, function(item, idx) {
item.onClick = function(evt) {
};
});
I want to do some such thing to change the contents of the h2 and the p tags inside every list items
Try this: (jquery)
var lis = $('.rb-grid').children('li');
for(var i = 0; i < lis.length : i++){
$(lis).eq(i).find('p').html("change to something");
$(lis).eq(i).find('h2').html("change to something");
}
js
var x =$('.rb-grid').children('li');
x.find('p').html('change to something');
x.find('h2').html('change to something');
A non jquery way:
var ee = document.getElementById('list').getElementsByTagName('li');
for(i=0; i<ee.length; i++) {
ee[i].getElementsByTagName('h2')[0].textContent = "hello world";
ee[i].getElementsByTagName('p')[0].textContent = "article 2";
}
EDIT: It seems IE previous to IE9 does not have textContent and should use innerText instead. Thanks Mr_Green!
Here for comparison is a more idiomatic jQuery version of Mr_Green's answer:
$('.rb-grid').children('li').each( function( i, element ) {
var $element = $(element);
$element.find('p').html("change to something");
$element.find('h2').html("change to something");
});
OTOH, you may not even need the loop, depending on what you're doing. If you just want to change all the relevant nested p and h2 elements to the same value, then Tushar Gupta's answer is a simpler way to do it.

Javascript click event listener on multiple elements and get target ID

I have a javascript file that sets an EventListener of 'click' on every element with the <article> tag. I want to get the id of the article clicked when the event fires. For some reason, my code produces nothing!
My javascript:
articles = document.getElementsByTagName('article');
articles.addEventListener('click',redirect(e),false);
function redirect(e){
alert(e.target.id);
}
Why isn't this working? BTW my article setup is in a function called when the window is loaded, and i know that works for sure because that function has other stuff that work.
EDIT
So i fixed my code so it will loop and add the listener to every article element, and now i get an alert box with nothing in it. When trying to output the e.target without the ID, i get the following message for every element:
[object HTMLHeadingElement]
Any suggestions?
ANOTHER EDIT
My current javascript code:
function doFirst(){
articles = document.getElementsByTagName('article');
for (var i = 0; i < articles.length; i++) {
articles[i].addEventListener('click',redirect(articles[i]),false);
}
}
function redirect(e){
alert(e.id);
}
window.addEventListener('load',doFirst,false);
This is showing my alert boxes when the page finished loading, without considering that i haven't clicked a damn thing :O
You are not passing an article object to redirect as a parameter.
Try this (EDIT):
articles = document.getElementsByTagName('article');
for (var i = 0; i < articles.length; i++) {
articles[i].addEventListener('click',redirect,false);
}
function redirect(ev){
alert(ev.target.id);
}
Hope, it will solve the bug.
Why is nobody mentioning a single event which checks for the clicked element?
document.body.addEventListener('click', function(e) {
var target = e.target;
if (target.nodeName === 'article') {
// do whatever you like ;-)
}
e.stopPropagation()
});
it's more performant to have less events..
if you don't need to check for click events on the whole body you could attach the event to some closer parent element
You are executing the redirect function instead of passing the reference, try this:
articles = document.getElementsByTagName('article');
articles.addEventListener('click',redirect,false);
function redirect(e){
alert(e.target.id);
}
Edit:
Also, getElementsByTagName returns an array with articles, so you have to loop through them and call addEventListener on each one of them.
articles = document.getElementsByTagName('article');
for (var i = 0; i < articles.length; i++) {
articles[i].addEventListener('click',redirect,false);
}
function redirect(e){
alert(e.target.id);
}
getElementsByTagName returns a nodelist. You can then add an eventlistener to each one of those elements with a for loop.
<div id="test">
hey
</div>
<div id="test2">
yo
</div>
<script>
var nl = document.getElementsByTagName('div');
for(var i=0; i<nl.length; i++){
nl[i].addEventListener('click', function(e){
alert(e.target.id);
},false);
}
</script>
This mini javascript libary (1.3 KB) can do all these things
https://github.com/Norair1997/norjs/
nor.event(["#first"], ["touchstart", "click"], [doSomething, doSomething]);
This plugin can handle such stuff and more
Sry for bumping this old post, but I would do something like this
const myElements = document.querySelectorAll("article")
myElements.forEach(x => x.setAttribute("onclick", "alertFunction(this.id)"))
function alertFunction(theId){
alert(theId)
}
That would be if JavaScript is what you need. But today you can use JQuery instead, and that would be less code.
articles.addEventListener('click',redirect,false); // omit redirect(e) inside event listener // and then try with the alert as you did.
if does not work then try by e.id instead of e.target.id inside alert as below:
alert(this.id);
Thanks.

Javascript DOM howto?

I am a javascript noob.
I would like to select the second 'p' element of the div.box.
How do I do this?
Thanks a lot!
Tom
To get second p element of div with class box you'd do this:
var paragraph = null;
var divs = document.findElementsByTagName('div');
for (var i = 0; i < divs.length; i++) {
var div = divs[i];
if (div.class == 'box') {
var paragraphs = div.getElementsByTagName('p');
if (paragraphs.length > 1)
paragraph = paragraphs[1];
break;
}
}
The paragraph would then be in the paragraph variable (or null if it wasn't found).
However you can do this much easier with a library such as jQuery:
var paragraph = $('div.box p:eq(1)');
Without using jQuery, the basic method would be to attach an unique ID to your Dom element
<p id="second_p_elmt"> [...] </p>
and then accessing it through the getElementById() method:
<script ...>
var second_p_elmt = document.getElementById('second_p_elmt');
</script>
<script type="text/javascript">
var boxElem = document.getElementById('box'),
pElems = boxElem.getElementsByTagName('p'),
whatYouWant = pElems[1]; // [1] is the second element in the response from getElementsByTagName
</script>
You have several options. As stated above, you could use one of the excellent frameworks, like jQuery or prototype. Or you give the <p/> an ID, that you can use simply with document.getElementById().
Then, as reko_t pointed out, without the above, you must write a lengthy DOM traversing code (which is preferable, if you don't use JS frameworks elsewhere, over embedding them only for this task).
In the most recent browsers (namely, IE>=8, FF>=3.5, recent Opera and Safari > 3) you can also use this simple snippet:
var p = document.querySelectorAll("div.box p");

Categories

Resources