I have a two-dimensional array (affiliates) where each array item consists of an image URL and a link URL. randArray is simply a generated list of random numbers (non-repeating) that matches the length of affiliates.
I've gotten to the point where I can successfully generate an HTML string for randomized image/url combinations.
(The above might be more information than needed but I wanted to provide a little background.)
What I'm trying to do is group every three iterations together and wrap in <p> tags. I've tried doing a nested loop inside the current one but could only get to where it was wrapping three of the same line in a <p> tag, whereas I need them to be three successive lines. I feel like this should be pretty easy, but I'm stumped. Any help would be much appreciated.
for(var y=0; y < randArray.length; y++) {
var image = affiliates[randArray[y]][0];
var url = affiliates[randArray[y]][1];
var fullString = '<img src="' + image + '">';
console.log(fullString);
}
WIthin your loop, y % 3 == 0 will be true on the first iteration and every third after it, so output your <p> when y % 3 == 0 and your </p> when y % 3 == 2 and after your loop if length % 3 != 0.
But a nested loop is probably easier to do and maintain:
var x, image, url;
var fullString = "";
var y = 0;
while (y < randArray.length) {
fullString += '<p>';
for (x = 0; x < 3 && y < randArray.length; ++x, ++y) {
image = affiliates[randArray[y]][0];
url = affiliates[randArray[y]][1];
fullString += '<img src="' + image + '">';
}
fullString += '</p>';
}
for(var y=0; y < randArray.length; y++) {
var image = affiliates[randArray[y]][0];
var url = affiliates[randArray[y]][1];
var fullString = '';
if(y%3 == 2){
fullString += '<p>';
}
fullString = '<img src="' + image + '">';
if(y%3 == 2){
fullString += '</p>';
}
console.log(fullString);
}
I am not sure if I understand, but...
var t = [];
for(var i=0;i<affiliates.length;i++) t.push(i);
while(t.length>2){
var str = '';
for(var i=0;i<3;i++){
str += '<a href="';
var r = Math.floor(Math.random()*t.length);
str += affiliates[t[r]][1] + '"><img src="';
str += affiliates[t[r]][0] + '"></a>';
t.splice(r,1);
}
str = '<p>'+str+'</p>';
console.log(str);
}
I would do something like this, but it's not optimized code, sorry :/
var counter = 1; //external counter for module (%3)
var open = false;
var tagOpen = '<p>';
var tagClose = '</p>';
var fullstring = '';
var buffer = ''
for(var y=0; y < randArray.length; y++) {
var image = affiliates[randArray[y]][0];
var url = affiliates[randArray[y]][1];
//groups entries
buffer += '<img src="' + image + '">';
if(counter % 3 == 0){
fullstring = tagOpen + buffer + tagClose; //concat strings
console.log(fullString);
open = false; //set open to false
} else {
open = true;
}
counter++;
}
//if at the end of the loop there's still an open tag, close it
if(open){
fullstring += tagClose;
}
Related
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]);
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>
I recently started learning html/javascript and I want a temporary object to be filled with one of the objects from an array based on the current page number.
loadnextpage();
function loadnextpage() {
var curpage = allcontent[pagenumber];
pagenumber++;
changeDiv('title', '<span>' + curpage.pageNumber + '</span>' + curpage.title);
}
But when I try to run the code it keeps giving me an error message that curpage is undefined, after that it keeps running and thus the last line of code gives an error, when I ask for curpage.pageNumber. After that it stops running the code.
image clipping of my code with error message
What am I doing wrong?
edit:
here is the entire code:
var pagenumber = 0;
var receipt = [];
var price = 0;
var text = '{"page": [{"pageNumber": "1","title": "kies je formaat","optionName": "size","option": [{"text": "klein","value": "small","extraPrice": "100"},{"text": "middel","value": "medium","extraPrice": "200"},{"text": "groot","value": "large","extraPrice": "300"}]},{"pageNumber": "2","title": "kies je kleur","optionName": "colour","option": [{"text": "rood","value": "red","extraPrice": "10"},{"text": "groen","value": "green","extraPrice": "20"},{"text": "blauw","value": "blue","extraPrice": "30"}]}]}';
var allcontent = [];
allcontent = JSON.parse(text);
var imgpath = 'img/';
loadnextpage();
function loadnextpage(){
var curpage = allcontent[pagenumber];
pagenumber++;
changeDiv('title', '<span>' + curpage.pageNumber + '</span>' +
curpage.title);
var radiobuttons = '';
var radiobuttonid = [];
for(var i = 0; i < curpage.option.length; i++) {
var curradio = curpage.option[i];
radiobuttons += '<label><div class="selection-wrap">';
radiobuttons += curradio.text;
radiobuttons += ' <input type="radio" name="';
radiobuttons += curpage.optoinName;
radiobuttons += '" value="';
radiobuttons += curradio.value;
radiobuttons += '" id="';
radiobuttons += curpage.optoinName;
radiobuttons += '_';
radiobuttons += curradio.value;
radiobuttons += '"></div></label></br>';
radiobuttonid.push(curpage.optoinName + '_' + curradio.value)
}
changeDiv('choices', radiobuttons);
for(var i = 0; i < radiobuttonid.length; i++){
document.getElementById(radiobuttonid[i]).onclick = function(){
receipt[pagenumber-1] = curpage.option[i];
for(var i = 0; i < receipt.length; i++){
price += receipt[i].extraPrice;
}
changeImg('previewimg', imgpath + curpage.option[i].value +
'/preview.jpg');
changeDiv('previewprice', '<h1>€' + price + ',-</h1>');
};
}
};
function changeDiv(id, content) {
document.getElementById(id).innerHTML = content;
};
function changeImg(id, img){
document.getElementById(id).src = img;
};
This is a coin flipping randomizer. I need to print out 10 rows and 20 columns. This is where I am stuck. My code seems to randomize correctly every time I click my button, it displays 20 columns but I cannot seem to get it to print a second row. It may be something simple that I am just not catching. Anything will be appreciated.
Javascript Code
function toss()
{
var heads = "x ";
var tails = "o ";
var rows = 0;
while(rows < 10)
{
var arr = new Array(20);
for(var i = 0; i < arr.length; i++)
{
var val = Math.floor( Math.random() * 2 );
if(val === 1)
{
arr[i] = " x";
}
else
{
arr[i] = " y";
}
document.getElementById("results").innerHTML = arr + "<br />";
}
delete arr;
rows++
}
}
HTML:
<html>
<head>
<title>Coin Flip</title>
<script src="Toss.js" type="text/Javascript"></script>
<style>
#results
{
display: block;
}
</style>
</head>
<body>
Push Button to Flip -> <input type="button" onclick="toss()" value=" Flip ">
<span id="results"></span>
</body>
</html>
The problem is you are replacing the entire results output each time you create a row with the new row. You need to append instead of replace. So change this:
document.getElementById("results").innerHTML = arr + "<br />";
To:
document.getElementById("results").innerHTML += arr + "<br />";
You also need to move the append of the result out of the inner for loop! If you leave the append within the for loop, you will see this behavior: http://jsfiddle.net/t1s93Lqz/3/
JSFiddle: http://jsfiddle.net/t1s93Lqz/2/
You are resetting the html inside the element each iteration through the loop
document.getElementById("results").innerHTML = arr + "<br />";
And while you could concatenate innerHTML each iteration to fix this:
document.getElementById("results").innerHTML += arr + "<br />";
This will cause the whole html for that element to be re-rendered. It would be better to either build the html string first and then set the element's innerHTML property or use DOM methods like appendChild/insertAdjacentHTML.
Build string first
var html = "";
while(rows < 10)
{
var arr = new Array(20);
for(var i = 0; i < arr.length; i++) {
var val = Math.floor( Math.random() * 2 );
if(val === 1) {
arr[i] = " x";
} else {
arr[i] = " y";
}
}
//moved the concatenation out of the loop
//otherwise you will get a line each as the array is set
html += arr + "<br />";
rows++
}
document.getElementById("results").innerHTML = html;
Using insertAdjacentHTML
var element = document.getElementById("results");
while(rows < 10)
{
var arr = new Array(20);
for(var i = 0; i < arr.length; i++) {
var val = Math.floor( Math.random() * 2 );
if(val === 1) {
arr[i] = " x";
} else {
arr[i] = " y";
}
}
element.insertAdjacentHTML('beforeend',arr+"<br />");
rows++
}
Demo
var rows = 0;
var element = document.getElementById("results");
while(rows < 10)
{
var arr = new Array(20);
for(var i = 0; i < arr.length; i++) {
var val = Math.floor( Math.random() * 2 );
if(val === 1) {
arr[i] = " x";
} else {
arr[i] = " y";
}
}
element.insertAdjacentHTML('beforeend',arr+"<br />");
rows++
}
<div id="results"></div>
Also note your delete statement won't do anything as delete works on object properties, if you console.log( delete arr ) you will see it will print false
You are only printing the last row. Replace
document.getElementById("results").innerHTML = arr + "<br />";
with
document.getElementById("results").innerHTML += arr + "<br />";
I have a bit of code that requires printing underscores but to the line above it, how would i do this? I'm not sure how to print the underscore to the previous line, not much experience with javascript. thanks!
var landscape = function() {
var result = "";
var flat = function(size) {
for (var count = 0; count < size; count++)
result += "_";
};
var hill = function(size) {
result += " /";
for (var count = 0; count < size; count++)
result += ""+
"_";
result += " \\";
};
//BUILD SCRIPT
flat(3)
hill(4);
flat(6);
hill(1);
flat(1);
//END SCRIPT
return result;
it makes this ___ /____ \______ /_ \_`enter code here`enter code here`
and i want this
_____ ___
___/ \__/ \____/\_
You can keep track of the two lines separately and then concatenate them just before returning the result.
JS:
function landscape() {
var resultTop = '';
var resultBottom = '';
function hill(size) {
resultTop += ' ';
resultBottom += '/';
for (var i = 0; i < size; i++) {
resultTop += '_';
resultBottom += ' ';
}
resultTop += ' ';
resultBottom += '\\';
}
function flat(size) {
for (var i = 0; i < size; i++) {
resultTop += ' ';
resultBottom += '_';
}
}
flat(3);
hill(4);
flat(6);
hill(1);
flat(1);
var result = resultTop + '<br/>' + resultBottom;
return result;
}
Here's a fiddle.
One workaround is to print a unicode character that draws a line on top. Turns out there is such a character: the Upper One-eighth Block
It's "\u2594" in unicode escape or ▔ as HTML entity or you can simply copy/paste the literal character from the example below:
____/▔▔▔▔\____/▔▔\___