Javascript: How can I join all links (array) - javascript

I have HTML like :
<div id="divid">
1
2
3
.....................
</div>
I used script below to join, but it cannot join. Check for me.
var links = document.getElementById('divid').getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
links[i] = links[i].href;
}
document.write('<div class="' + links.join(" ") + '">Class is added links</div>');
It means after joining I have HTML :
<div class="d#link1 d#link2 d#link3">Class is added links</div>

var as = document.getElementById('divid').getElementsByTagName('a');
var links = [];
for (var i = 0; i < as.length; i++) {
links[i] = as[i].href;
}
// work with links here
console.log('<div class="' + links.join(" ") + '">Class is added links</div>');
JSfiddle here.
Note that this causes trouble because the links are fully resolved, relative to the current domain. You might want to use another attribute to contain the classes.

Check for me.
Check it yourself.
document.getElementsByTagName returns a NodeList not an array, you'll need to
transform the nodelist into an array or just use a new array where you put in the hrefs...

Introduce a new variable:
var links = document.getElementById('divid').getElementsByTagName('a'),
hrefs = [];
for (var i = 0; i < links.length; i++) {
hrefs[i] = links[i].href;
}
document.write('<div class="' + hrefs.join(" ") + '">Class is added links</div>');

You'll need to create a separate array to hold the links.
Something like:
var links = document.getElementsByTagName('a');
var linkarr = new Array();
for (var i = 0; i < links.length; i++) {
linkarr[i] = links[i].href;
}
document.write('<div class="' + linkarr.join(" ") + '">Class is added links</div>');

Try this with jquery:
var links = $('#divid').children('a');
var linkArr = '';
for (var i = 0; i < links.length; i++) {
linksArr += links[i].attr('href') + ' ';
}
document.write('<div class="' + linksArr + '">Class is added links</div>');

Related

How to iterate a JavaScript code for two objects

I would like to apply same piece of code to two objects in JavaScript.
When calling getElementsByClass ,there appears 2 objects in my website.So I would like to apply the same code for both of them.Currently I'm applying it to only one Object (text[0]) and I would like to implement it also to text[1] .
var text=document.getElementsByClassName("th");
var text =text[0];
var newDom = '';
var animationDelay = 6;
for(let i = 0; i < text.innerText.length; i++)
{
newDom += '<span class="char">' + (text.innerText[i] == ' ' ? ' ' : text.innerText[i])+ '</span>';
}
text.innerHTML = newDom;
var length = text.children.length;
for(let i = 0; i < length; i++)
{
text.children[i].style['animation-delay'] = animationDelay * i + 'ms';
}
}
I think you want to do the same thing with using item[0] and item[1] together.
You can create a function. Or call this function by iterating your items too.
var text=document.getElementsByClassName("th");
function myFunc(text) {
var newDom = '';
var animationDelay = 6;
for(let i = 0; i < text.innerText.length; i++)
{
newDom += '<span class="char">' + (text.innerText[i] == ' ' ? ' ' : text.innerText[i])+ '</span>';
}
text.innerHTML = newDom;
var length = text.children.length;
for(let i = 0; i < length; i++)
{
text.children[i].style['animation-delay'] = animationDelay * i + 'ms';
}
}
}
myFunc(text[0]); // call functions with your items.
myFunc(text[1]);

Identify the first and last two posts

I am using the script below to show the latest 5 posts on my Blogger blog. How can I wrap the first and last 2 posts in different div containers? Currently all the 5 posts are inside a wrapper container stored in the item variable:
<script type='text/javascript'>
function mycallback(json) {
for (var i = 0; i < json.feed.entry.length; i++) {
for (var j = 0; j < json.feed.entry[i].link.length; j++) {
if (json.feed.entry[i].link[j].rel == 'alternate') {
var postUrl = json.feed.entry[i].link[j].href;
break;
}
}
var postTitle = json.feed.entry[i].title.$t;
var postAuthor = json.feed.entry[i].author[0].name.$t;
var postSummary = json.feed.entry[i].summary.$t;
var entryShort = postSummary.substring(0,400);
var entryEnd = entryShort.lastIndexOf(" ");
var postContent = entryShort.substring(0, entryEnd) + '...';
var postImage = json.feed.entry[i].media$thumbnail.url.replace('s72-c/','s1600/');
var item = '<div class="wrapper"><img src="' + postImage + '"/><h3><a href=' + postUrl + '>' + postTitle + '</h3></a><span>'+ postAuthor + '</span><p>' + postContent + '</p></div>';
document.write(item);
}
}
</script>
<script src="/feeds/posts/summary?orderby=published&max-results=5&alt=json-in-script&callback=mycallback"></script>
More generic solution would not check for last and previous to last elements checking for 3 or 4 but should be based on total length of your posts (it can be 3 it can be 10000).
Checks below should be place in your loop.
if(i === 0 || i === 1)
Always use === operator as it is typesafe.
Also group your checks in a way that is easy to understand (check for first and second in one if and for last and previous to last in another if:
if(i === json.feed.entry.length || i === json.feed.entry.length - 1) - this check is based on length of your entries, not some fixed value like 3 or 4.
This way if your displayed entries value will change in future (to ex. 10), you don't need to adjust your code here. All code you write should strive to work without such adjustments when code it uses changes.
Check desired elements through loop
// to check first or fourth element
if (i == 0 || i == 3)
// to check second or fifth element
if (i == 1 || i == 4)
Wrap them by adding HTML tages
<script type='text/javascript'>
function mycallback(json) {
for (var i = 0; i < json.feed.entry.length; i++) {
for (var j = 0; j < json.feed.entry[i].link.length; j++) {
if (json.feed.entry[i].link[j].rel == 'alternate') {
var postUrl = json.feed.entry[i].link[j].href;
break;
}
}
var postTitle = json.feed.entry[i].title.$t;
var postAuthor = json.feed.entry[i].author[0].name.$t;
var postSummary = json.feed.entry[i].summary.$t;
var entryShort = postSummary.substring(0,400);
var entryEnd = entryShort.lastIndexOf(" ");
var postContent = entryShort.substring(0, entryEnd) + '...';
var postImage = json.feed.entry[i].media$thumbnail.url.replace('s72-c/','s1600/');
var item = '<div class="wrapper"><img src="' + postImage + '"/><h3><a href=' + postUrl + '>' + postTitle + '</h3></a><span>'+ postAuthor + '</span><p>' + postContent + '</p></div>';
if (i == 0 || i == 3) document.write('<div>');
document.write(item);
if (i == 1 || i == 4) document.write('</div>');
}
}
</script>
<script src="/feeds/posts/summary?orderby=published&max-results=5&alt=json-in-script&callback=mycallback"></script>

Access and munipulate the DOM using a for loop

for a challenge, I am calling an the twitch TV API to get info and update my HTML.
Using a for loop, I succeeded to setAttributes for my divs and appendChilds. but when I want to update those childs, it is updating only the childs of the last div.
I need your help to update all my appended childs. Below is my code:
// variables declarations to update the DOM
var users = usersJson.data;
var i;
var usersIds = [];
var channels = document.getElementById("all").children;
console.log(channels);
// pushing channels ids into an array for a later
for (i = 0; i < users.length; i++) {
usersIds.push(users[i].id);
}
var channelImg = document.createElement("img");
var channelTitle = document.createElement("h3");
for (var i = 0; i < channels.length; i++) {
channels[i].setAttribute("id", users[i].id);
channels[i].setAttribute("class", "channelInfo" + (i + 1) + " " + "channel" + (i + 1));
channels[i].appendChild(channelTitle);
channels[i].appendChild(channelImg).setAttribute("id", "img-holder" + (i + 1));
channelTitle.innerHTML = users[i].display_name;
channelImg.setAttribute("src", users[i].profile_image_url);
}
https://jsfiddle.net/xpcz1r5k/1/
The creation of the elements needs to go in the for loop:
for (var i = 0; i < channels.length; i++) {
var channelImg = document.createElement("img");
var channelTitle = document.createElement("h3");
channels[i].setAttribute("id", users[i].id);
channels[i].setAttribute("class", "channelInfo" + (i + 1) + " " + "channel" + (i + 1));
channels[i].appendChild(channelTitle);
channels[i].appendChild(channelImg).setAttribute("id", "img-holder" + (i + 1));
channelTitle.innerHTML = users[i].display_name;
channelImg.setAttribute("src", users[i].profile_image_url);
}
When the creation is on the outside of the loop, appendChild only moves the element to the next parent. appendChild doesn't clone/duplicate the DOM elements. So you end up constantly updating the same DOM element and the last one ends up winning.

JavaScript: Cannot read property 'value' of null from textbox

function create(param) {
var i, target = document.getElementById('results');
target.innerHTML = '';
for(i = 1; i <= param; i += 1) {
target.innerHTML +='<br>'
for(var j=1;j<=param;j+=1)
target.innerHTML += '<input type="text" id="a'+i+''+j+'" placeholder="a'+i+''+j+'">';
}
}
function saveData(param) {
var a = []
for(var i = 1;i<param;i+=1) {
a[i] = [];
for(var j = 1;j<param;j+=1)
a[i][j] = document.getElementById('"a'+i+''+j+'"').value;
}
var target = document.getElementById('ShowResults');
for(var i = 1;i<param;i+=1){
a[i] = [];
target.innerHTML +='<br>'
for(var j = 1;j<param;j+=1)
target.innerHTML +=a[i][j];
}
}
<button onclick="create(5)" style="widht:300px;height:30px;">Create table</button>
<div id="results"> </div>
<button id="takeResults" onclick="saveData(5)"style="widht:300px;height:30px;">Save data</button>
<div id="ShowResults"> </div>
Ok so i made a table whit js and gave every textbox id of "a'+i+''+j+'" but it seems that when i want to save the data it show's me the following error: Cannot read property 'value' of null
Can you guys tell me what i did wrong?
Here's the solution with some code improvements
As i said in the comment, you had a mistake in the code you getElementById('"a' + i + '' + j + '"') should be getElementById('a' + i + '' + j)
and there's a lot of unnecessary loops
function create(param) {
var target = document.getElementById('results');
target.innerHTML = '';
for (var i = 0; i < param; i++) {
target.innerHTML += '<br>'
for (var j = 0; j < param; j++)
target.innerHTML += '<input type="text" id="a' + i + '' + j + '" placeholder="a' + i + '' + j + '">';
}
}
function saveData(param) {
var target = document.getElementById('ShowResults');
target.innerHTML = '';
var a = []
for (var i = 0; i < param; i++) {
a[i] = [];
for (var j = 0; j < param; j++) {
target.innerHTML += document.getElementById('a' + i + '' + j).value;
}
target.innerHTML += '<br>'
}
}
<button onclick="create(5)" style="widht:300px;height:30px;">Create table</button>
<div id="results"> </div>
<button id="takeResults" onclick="saveData(5)" style="widht:300px;height:30px;">Save data</button>
<div id="ShowResults"> </div>
Change this...
a[i][j] = document.getElementById('"a'+i+''+j+'"').value;
to this...
a[i][j] = document.getElementById('a' + i + j).value;
You have two lots of quotes around the id when you create it, but you don't need to add them both when you're using getElementById. Just build the string and it will work.
There were some other issues with your code, mainly where you didn't have opening braces but you had closing braces. Copy/paste this and it should fix your issues...
function create(param) {
var i, target = document.getElementById('results');
target.innerHTML = '';
for(i = 1; i <= param; i += 1) {
target.innerHTML +='<br>'
for(var j=1;j<=param;j+=1) {
target.innerHTML += '<input type="text" id="a'+i+''+j+'" placeholder="a'+i+''+j+'">';
}
}
function saveData(param) {
var a = []
for(var i = 1;i<param;i+=1) {
a[i] = [];
for(var j = 1;j<param;j+=1) {
a[i][j] = document.getElementById('a' + i + j).value;
}
var target = document.getElementById('ShowResults');
for(var i = 1;i<param;i+=1) {
a[i] = [];
target.innerHTML +='<br>'
for(var j = 1;j<param;j+=1) {
target.innerHTML +=a[i][j];
}
}
}
}
Incidentally, using multiple layers of arrays can cause issues, mainly due to being unfriendly for the reader (or you in the future). I'd highly recommend using an array of objects instead, and naming things more appropriately than a, i & j.

How to implement this Javascript to Blogger?

Please help, I can't implement this javascript to my Blogger...
(function() {
var pre = document.getElementsByTagName('pre'),
pl = pre.length;
for (var i = 0; i < pl; i++) {
pre[i].innerHTML = '<span class="line-number"></span>' + pre[i].innerHTML + '<span class="cl"></span>';
var num = pre[i].innerHTML.split(/\n/).length;
for (var j = 0; j < num; j++) {
var line_num = pre[i].getElementsByTagName('span')[0];
line_num.innerHTML += '<span>' + (j + 1) + '</span>';
}
}
})();
You can see this Javascript work fine here : http://jsfiddle.net/tovic/AbpRD/1/
If you are seeing that following type of error when you try to add this JavaScript snippet in your theme code -
Error parsing XML: The content of elements must consist of well-formed character data or markup.
Then to resolve this error, use any of the following methods -
1. Wrap the code within a CDATA directive in the script tag. The code will look like -
<script>
//<![CDATA[
(function() {
var pre = document.getElementsByTagName('pre'),
pl = pre.length;
for (var i = 0; i < pl; i++) {
pre[i].innerHTML = '<span class="line-number"></span>' + pre[i].innerHTML + '<span class="cl"></span>';
var num = pre[i].innerHTML.split(/\n/).length;
for (var j = 0; j < num; j++) {
var line_num = pre[i].getElementsByTagName('span')[0];
line_num.innerHTML += '<span>' + (j + 1) + '</span>';
}
}
})();
//]]>
</script>
The only downside of this approach being that Blogger XML parser will ignore any data layout tags (like for example <data:blog.homepageUrl/>) within the CDATA directive. Rather than replacing them with their actual values, it will not interpret them and show them as is.
2. Escape the following characters in your code -
" is replaced with "
& is replaced with &
< is replaced with <
> is replaced with >
After escaping, the code should look like -
<script>
(function() {
var pre = document.getElementsByTagName('pre'),
pl = pre.length;
for (var i = 0; i & lt; pl; i++) {
pre[i].innerHTML = '<span class="line-number"></span>' + pre[i].innerHTML + '<span class="cl"></span>';
var num = pre[i].innerHTML.split(/\n/).length;
for (var j = 0; j & lt; num; j++) {
var line_num = pre[i].getElementsByTagName('span')[0];
line_num.innerHTML += '<span>' + (j + 1) + '</span>';
}
}
})();
</script>
The data layout tags will remain functional when following this method. Remember to not escape <> surrounding the data layout tag (aka <data:blog.homepageUrl/> will work but not <data:blog.homepageUrl/>)
3. If no data layout tags have to be included in the JavaScript. Then you can add it in an HTML/JavaScript gadget via the Layout tab instead of directly including it in the theme code.

Categories

Resources