Create a pyramid structure diagram on a page from the user input - javascript

I want to create a pyramid like structure on a page from the user input, and the structure should appear like this,
I tried to loop in JS to display the structure but can't change the css property in JS loop according to user input. Here is the code on this page :
var objContainer = document.getElementById("container"),
intLevels = 10,
strBlocksHTML = '';
for (var i = 0; i < intLevels; i++) {
strBlocksHTML += '<div class="buildingBlock"></div>';
strBlocksHTML += '<div></div>'; // Line break after each row
}
objContainer.innerHTML = strBlocksHTML;
.buildingBlock {
display: inline-block;
width: 20px;
height: 20px;
margin: 2px 5px;
background-color: #eee;
border: 2px solid #ccc;
}
#container {
text-align: center;
}
<div id="container"></div>
The output is displayed as a tower and also want to remove the spacing between each <div> element. How can I change this by using jquery or by some other method ? The above image is the desired output that I want.

By changing the first strBlocksHTML row to
strBlocksHTML += '<div class="buildingBlock" style="width: ' + Number(20 + 40 * i) + 'px"></div>';
it works.

you need to do some thing like this
for( var i=0; i<intLevels; i++ ){
var wd = 20 * i;
strBlocksHTML += '<div class="buildingBlock" style="width:'+wd+'px"></div>';
strBlocksHTML += '<div></div>'; // Line break after each row
}
var objContainer = document.getElementById("container"),
intLevels = 10,
strBlocksHTML = '';
for (var i = 0; i < intLevels; i++) {
var wd = 20 * i;
strBlocksHTML += '<div class="buildingBlock" style="width:' + wd + 'px;"></div>';
strBlocksHTML += '<div></div>'; // Line break after each row
}
objContainer.innerHTML = strBlocksHTML;
.buildingBlock {
display: inline-block;
width: 20px;
height: 20px;
margin: 2px 5px;
background-color: #eee;
border: 2px solid #ccc;
margin-top: -20px;
}
#container {
text-align: center;
}
<div id="container"></div>
you can allign these closer by using css

You could simple set the width via the style attribute on each created div, and calculate it dynamically – I’ve change your loop to run backwards, something like this:
for(var i=intLevels; i>0; --i) {
strBlocksHTML += '<div class="buildingBlock" style="width:'+(250-i*20)+'px"></div>';
}
Change the values (250px width from which i*20 gets subtracted) as you see fit, resp. calculate them dynamically based on the number of pyramid levels wanted.
And also you do not need the empty divs for line breaks – just keep your divs as display:block, and set the margin to auto to center them.
var objContainer = document.getElementById("container"),
intLevels = 10,
strBlocksHTML = '';
for (var i = intLevels; i > 0; --i) {
strBlocksHTML += '<div class="buildingBlock" style="width:' + (250 - i * 20) + 'px"></div>';
}
objContainer.innerHTML = strBlocksHTML;
.buildingBlock {
height: 20px;
margin: auto;
background-color: #eee;
border: 2px solid #ccc;
}
#container {
text-align: center;
}
<div id="container"></div>

var objContainer = document.getElementById("container"),
intLevels = 10,
strBlocksHTML = '';
for (var i = 0; i < intLevels; i++) {
strBlocksHTML += '<div class="buildingBlock" style="width:' + (10 * i) + 'px"></div>';
//strBlocksHTML += '<div></div>'; // Line break after each row
}
objContainer.innerHTML = strBlocksHTML;
.buildingBlock {
display: block;
width: 20px;
height: 20px;
margin: 0 auto;
background-color: #eee;
border: 2px solid #ccc;
}
#container {
text-align: center;
}
<div id="container"></div>

Related

Why I have NaN on Node.js?

I'm making a bulletin board now. Above is the template code for it, where page function has NaN. What is the reason for this error, and how should I fix it?
The code below is written in node.js.
module.exports = {
HTML:function(title, board, control, page){
return `
<!DOCTYPE html>
<html>
<head>
<title>${title}</title>
<meta charset="utf-8">
<style type="text/css">
ul.board, ol.board {
list-style: none;
margin: 0px;
padding: 5px;
}
form {
display: inline;
}
table.type09 {
border-collapse: separate;
text-align: left;
line-height: 2;
}
table.type09 thead th {
padding: 10px;
font-weight: bold;
vertical-align: top;
color: #369;
border-bottom: 3px solid #003699;
}
table.type09 tbody th {
width: 150px;
padding: 10px;
font-weight: bold;
vertical-align: top;
border-bottom: 1px solid #ccc;
background: #f3f6f7;
}
table.type09 td {
width: 350px;
padding: 10px;
vertical-align: top;
border-bottom: 1px solid #ccc;
}
</style>
</head>
<body>
<div id="board">
<table class="type09">
<thead>
<tr>
<th>제목</th>
<th>작성자</th>
<th>날짜</th>
<th>조회수</th>
</tr>
</thead>
<tbody>
${board}
</tbody>
</table>
${control}
</div>
${page}
</body>
</html>`;
},board: function (lifeboards) {
var board = ``;
for (i = 0; i < lifeboards.length; i++) {
var article = lifeboards[i];
var titleBold = article.titleBold;
board += `<tr>`;
if(titleBold == "1") {
board += `<td> <b><공지>${article.title}</b> </td>`;
board += `<td>${article.writer}</td>`;
board += `<td>${article.day}</td>`;
board += `<td>${article.see}</td>`;
board += `</tr>`;
}
}
for (i = 0; i < lifeboards.length; i++) {
var article = lifeboards[i];
var titleBold = article.titleBold;
board += `<tr>`;
if(titleBold == "1") {
board += `<td> ${i+1}. <b>${article.title}</b> </td>`;
} else if(titleBold == "0") {
board += `<td>${i+1}. ${article.title}</td>`;
}
board += `<td>${article.writer}</td>`;
board += `<td>${article.day}</td>`;
board += `<td>${article.see}</td>`;
board += `</tr>`;
}
return board;
},page:function (lifeboards) {
var page = ``;
page =+ `<tr>`;
page =+ `<td colspan="5">`;
for(j = 0; j < lifeboards.length/5; j++) {
page =+ `[${j+1}]`;
}
page =+ `</td>`;
page =+ `</tr>`;
return page;
}
}
The picture below shows how it works.
I don't know how much more detail Stackoverflow wants, but this is all my code and there's nothing more to explain.
Please use this one , you need to add concat ( + ) operator first then =. e.g. +=
page: function (lifeboards) {
var page = ``;
page += `<tr>`;
page += `<td colspan="5">`;
for (j = 0; j < lifeboards.length / 5; j++) {
page += `[${j + 1}]`;
}
page += `</td>`;
page += `</tr>`;
return page;
}
Hope this will solve the issue.

Jquery Fade Cycle through paragraphs and display one item at a time

I cannot get it to just display one at a time. It has to do a full cycle before it displays just one paragraph. Pulling my hair out.
$(function(){
setInterval(function(){$('.forumFeed > :first-child').fadeOut(3000).next('p').delay(3000).fadeIn(1000).end().appendTo('.forumFeed');}, 5000);
});
https://codepen.io/capseaslug/pen/yqyBXB
Hide all but the first paragraph tag by default. Inside the setInterval hide the one that is showing and display the next one (controlled by an index variable).
To make the items fade in/out nicely you can fade in the next element after the visible one is finished hiding.
Added some variables at the top to play with the aesthetics / number of items looped through.
SO didn't have moment.js so I hard coded some string. Codepen for a working version.
var numberOfItems = 10;
var flipSpeed = 2000;
var fadeOutSpeed = 500;
var fadeInSpeed = 200;
(function(c){
var uniquename = 'rssfeed' // id of target div
var query = 'select * from rss(0,' + numberOfItems + ') where url = "https://forums.mankindreborn.com/f/-/index.rss"'; // RSS Target, 0,5 signifies number of entries to show
var numretries = 1; // increase this number (number of retries) if you're still having problems
//////// No Need To Edit Beyond Here Unless You Want To /////////
var counter = typeof c === 'number'? c : numretries;
var thisf = arguments.callee;
var head = document.getElementsByTagName('head')[0];
var s = document.createElement('script');
window["callback_" + uniquename + (--counter)] = function(r){
head.removeChild(s);
if(r && r.query && r.query.count === 0 && counter > 0){
return thisf(counter);
}
//r now contains the result of the YQL Query as a JSON
var feedmarkup = '';
var feed = r.query.results.item // get feed as array of entries
for (var i=0; i<feed.length; i++) {
feedmarkup += '<p><span class="firstrowwrap"><a href="' + feed[i].link + '">';
feedmarkup += feed[i].title + '</a> <span class="comments"> Replies: ';
feedmarkup += feed[i].comments + ' </span></span><span class="secondRow"> <i class="fas fa-feather-alt"></i> ' ;
feedmarkup += feed[i].creator + ' <span class="posttime"> Last Post: ';
//pubishdate since
publishDate = feed[i].pubDate;
var inDate = publishDate;
var publisheddate = new Date(inDate);
feedmarkup += 'moment.js is missing ' + '</span></span></p>';
//endpublishdate since
}
document.getElementById(uniquename).innerHTML = feedmarkup;
};
var baseurl = "https://query.yahooapis.com/v1/public/yql?q=";
s.src = baseurl + encodeURIComponent(query) + "&format=json&callback=callback_" + uniquename + counter;
head.append(s);
})();
$(function(){
var index = 0;
setInterval(function() {
$('#rssfeed>p:visible').fadeOut(fadeOutSpeed, ()=> {
$('#rssfeed>p').eq(index).fadeIn(fadeInSpeed);
});
index++;
if(index === $('#rssfeed>p').length){
index = 0;
}
}, flipSpeed);
});
#main-container {
padding:4em;
background: #333;
font-family: 'exo'
}
#rssfeed p:not(:first-child) {
display: none;
}
a{
font-weight:
500;
color: #68ddda;
}
a:hover{
color: #4ca7a4;
}
.firstrowwrap{
display: flex;
justify-content: space-between;
}
.secondRow{
display: block;
padding-top: 4px;
margin-bottom: -5px;
}
#rssfeed p{
background-color: #212121;
padding: 10px;
width: 400px;
margin-bottom: 2px;
color: #464646;
}
.comments{
height: 18px;
position: relative;
z-index: 1;
padding-left: 8px;
margin-left: 4px;
font-size: 12px;
}
.comments:after{
content: "";
position: absolute;
width: 100%;
height: 100%;
left: 0px;
top: 0px;
background-color: #969696;
border-radius: 2px;
z-index: -1;
margin-left: 4px;
}
.posttime{
float: right;
font-size: 13px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container-fluid" id="main-container">
<div class="row">
<div class="col-md-12">
<div class="forumFeed" id="rssfeed"></div>
</div>
</div>
</div>

Reflow/repaint issues? Optimize app that is way too slow

Alright so I have run into what I believe is an optimization issue. I have written a short app that grabs data from two fields, rips them apart character by character and matches them to each other, highlighting discrepancies. The issue seems to be that because the function loops through and not only prints each character one at a time, but changes color in a new span one at a time, there is a severe amount of bottlenecking for large data entries. One sentence of even five work just fine, but when you get up to a full page of text, things bog down and in some cases crash. I have tried to look up some fixes for repaints/reflows, but I haven't run into this issue before and don't know much about it. ANy tips welcome.
Code is here:
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Data Comparison</title>
</head>
<body>
<p><strong>Insert text into fields one and two and press 'Compare'. Matching data is green non-matching is red. </strong></p>
<div class="userField">
<h1>Input Field 1</h1>
<textarea id="textAreaOne" rows="30" cols="65"></textarea>
</div>
<div class="userField">
<h1>Input Field 2</h1>
<textarea id="textAreaTwo" rows="30" cols="65"></textarea>
</div>
<div id="submission">
<button onclick="compare(textAreaOne);">Compare</button>
</div>
<div id="divOne">
<h1 id="titleOne">Output Field 1</h1>
<p id="outputOne"></p>
</div>
<div id ="divTwo">
<h1 id="titleTwo">Output Field 2</h1>
<p id="outputTwo"></p>
</div>
</body>
</html>
CSS:
body {
width: 100%;
margin: 0;
padding: 0;
font-family: Verdana, Geneva, sans-serif;
font-size: 15px;
}
.userField {
display: inline-block;
width: 44%;
margin: 15px;
padding: 15px;
background-color: lightgrey;
border-radius: 13px;
box-shadow: 3px 3px 3px slategrey;
}
#submission {
text-align: center;
}
#divOne {
display: inline-block;
margin: 15px;
padding: 15px;
width: 44%;
word-wrap: break-word;
background-color: lightgrey;
}
#divTwo {
display: inline-block;
background-color: lightgrey;
width: 44%;
word-wrap: break-word;
margin: 15px;
padding: 15px;
}
#titleOne {
background-color: white;
width: 240px;
border-radius: 30px;
padding: 6px;
}
#titleTwo {
background-color: white;
width: 240px;
border-radius: 30px;
padding: 6px;
}
JS:
const fieldOne = document.querySelector("#textAreaOne");
const fieldTwo = document.querySelector("#textAreaTwo");
function compare(){
document.querySelector("#outputOne").innerHTML = "";
document.querySelector("#outputTwo").innerHTML = "";
document.querySelector("#divOne").style.visibility = "hidden";
document.querySelector("#divTwo").style.display = "hidden";
let dataOne = [];
let arrOne = fieldOne.value;
let temp = arrOne.split("");
dataOne.push(temp);
let dataTwo = [];
let arrTwo = fieldTwo.value;
let tempTwo = arrTwo.split("");
dataTwo.push(tempTwo);
if (fieldOne.value.length <= fieldTwo.value.length){
for (var i = 0; i<fieldOne.value.length; i++){
if (dataOne[0][i] === dataTwo[0][i]){
document.querySelector("#outputOne").innerHTML += "<span style='color:green'>" + dataOne[0][i] + "</span>";
document.querySelector("#outputTwo").innerHTML += "<span style='color:green'>" + dataTwo[0][i] + "</span>";
} else {
document.querySelector("#outputOne").innerHTML += "<span style='color:red'>" + dataOne[0][i] + "</span>";
document.querySelector("#outputTwo").innerHTML += "<span style='color:red'>" + dataTwo[0][i] + "</span>";
}
}
if (fieldOne.value.length < fieldTwo.value.length){document.querySelector("#outputTwo").innerHTML += "<span>...</span>";}
}
else {
for (var i = 0; i<fieldTwo.value.length; i++){
if (dataOne[0][i] === dataTwo[0][i]){
document.querySelector("#outputOne").innerHTML += "<span style='color:green'>" + dataOne[0][i] + "</span>";
document.querySelector("#outputTwo").innerHTML += "<span style='color:green'>" + dataTwo[0][i] + "</span>";
} else {
document.querySelector("#outputOne").innerHTML += "<span style='color:red'>" + dataOne[0][i] + "</span>";
document.querySelector("#outputTwo").innerHTML += "<span style='color:red'>" + dataTwo[0][i] + "</span>";
}
}
if (fieldTwo.value.length < fieldOne.value.length){ document.querySelector("#outputOne").innerHTML += "<span>...</span>";}
}
document.querySelector("#divOne").style.visibility = "visible";
document.querySelector("#divTwo").style.visibility = "visible";
}
https://codepen.io/Axfinger/pen/QxvbqM?editors=0010
Thanks
The main reason your code is slow it's because you keep modify innerHtml for every letter.
This approach is way faster even with several paragraph:
[...]
let outOne = '';
let outTwo = '';
if (fieldOne.value.length <= fieldTwo.value.length){
for (var i = 0; i<fieldOne.value.length; i++){
if (dataOne[0][i] === dataTwo[0][i]){
outOne += dataOne[0][i];
outTwo += dataTwo[0][i];
} else {
outOne += "<span style='color:red'>" + dataOne[0][i] + "</span>";
outTwo += "<span style='color:red'>" + dataTwo[0][i] + "</span>";
}
}
if (fieldOne.value.length < fieldTwo.value.length){outTwo += "...";}
}
[...]
outputOne.innerHTML = outOne;
outputTwo.innerHTML = outTwo;
Note that I omitted parts of the code for clearness.
That said if you still need more speed:
Lookup for fitting as much data as possible into the red spans. That is the whole consecutive subsequence of different letters.
Execute the function in a webworker (Will take similar time but at least won't freeze the browser).

Javascript increment up within a loop

for (i = 0; i < arrayData.length; i++) {
$(".swipe-wrap").append("<div class=\"final\">Hello!</div>");
console.log('hello');
}
This is what I currently have. My arrayData is an array that changes each load.
How can I get it so my class final each for loop will have an counter like such : <div class="final_1">Hello!</div> , <div class="final_2">Hello!</div>..
for (i = 0; i < arrayData.length; i++) {
$(".swipe-wrap").append("<div class=\"final_"+i+"\">Hello!</div>");
console.log('hello');
}
You should not perform DOM manipulation inside loops. Always perform bulk operation.
Try this:
var html = ""
for (i = 0; i < arrayData.length; i++) {
html += '<div class="final_'+i+'">Hello!</div>';
console.log('hello');
}
$(".swipe-wrap").append(html);
You can also use Array.forEach.
var html = ""
var arrayData = ["test1", "test2", "test3", "test4", "test5"];
console.log(arrayData);
arrayData.forEach(function(item, index) {
html += '<div class="tile final_' + index + '">Hello ' +item+ '!</div>';
console.log('hello');
});
$(".swipe-wrap").append(html);
.swipe-wrap {
background: #eee;
padding: 10px;
border: 1px solid gray;
}
.tile {
width: auto;
padding: 10px;
margin: 10px;
background: #fff;
border: 1px solid #ddd;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="swipe-wrap"></div>

javascript background image change using array

I am not exprienced javascript programmer so I try to play with javascript. I am trying to make a slideshow by clicking on a button. Function I am trying to make a function with array that holds the names of all the images and changing the background-image according to the index of the array. I did only this part of function yet and I cant get what is wrong.
function change(lol){
var img = ["veni1.jpg", "veni2.jpg", "veni3"];
var middle = document.getElementById("vvvmiddle");
var index = img.indexOf(middle.style.backgroundImage);
if(change === "right"){
var current = index + 1;
middle.style.backgroundImage = img[current];
}
}
middle {
width:1262px;
height:550px;
background-color: white;
margin-left: -7px;
}
#vvvmiddle {
width:700;
height:400;
background-image:url('veni1.jpg');
margin: 20px 0px 0px 310px;
float:left;
}
#sipka {
width:40;
height:40;
border-radius: 100px;
background-color: #DCDCDC;
float:right;
margin: 450px 410px 0px 0px;
}
#sipkatext {
font-family: Impact;
color: white;
font-size: 30px;
padding-left: 10px;
padding-top: 1px;
}
#sipkaurl {
text-decoration: none;
}
#sipka:hover {
background-color: #3399FF;
}
#sipka2:hover {
background-color: #3399FF;
}
#sipka2 {
width:40;
height:40;
border-radius: 100px;
background-color: #DCDCDC;
float:right;
margin: 450px -100px 0px 0px;
}
#sipkatext2 {
font-family: Impact;
color: white;
font-size: 30px;
padding-left: 13px;
padding-top: 1px;
}
<div id="middle">
<div id="vvvmiddle">
<div id="sipka" onclick="change('left')">
<div id="sipkatext">
<</div>
</div>
<div id="sipka2" onclick="change('right')">
<div id="sipkatext2">></div>
</div>
</div>
</div>
A possible solution may be this one:
var img = ["img1.png", "img2.png", "img3.png"];
var len = img.length;
var url = 'Some url...';
var current=0;
var middle = document.getElementById("vvvmiddle");
middle.style.backgroundImage = "url(" + url + img[current] + ")";
function change(dir){
if(dir == "right" && current < len-1){
current++;
middle.style.backgroundImage = "url(" + url + img[current] + ")";
} else if(dir == "left" && current > 0){
current--;
middle.style.backgroundImage = "url(" + url + img[current] + ")";
}
}
See it in action, check here jsfiddle.
You can try with that:
function change(lol) {
var img = ["veni1.jpg", "veni2.jpg", "veni3"];
var middle = document.getElementById("vvvmiddle");
var index = img.indexOf(middle.style.backgroundImage);
if(lol === "right"){
index = (index + 1) % img.length;
} else {
index = (index + img.length - 1) % img.length;
}
middle.style.backgroundImage = img[index];
}
You are checking wrong variable in condition, it should be lol, not change:
if(lol === "right"){
var current = index + 1;
middle.style.backgroundImage = img[current];
}
Also you should handle "last image" case like Nicolas suggests.

Categories

Resources