Question
How do I align the ticks and text labels with the colour gradient, and so that the legend container expands to contain those elements
Notes
The colour gradient, ticks and labels have to be created dynamically in JS
The width of labels will vary, so the legend container has to expand accordingly
I can't use JQuery
I'm not a javascript/html/css developer, so happy to hear alternative approaches
HTML
<div id="legend"></div>
Javascript
var legend = document.getElementById("legend");
var divColours = document.createElement('div');
var jsColours = ["#440154", "#443A83", "#31688E", "#21908C", "#35B779", "#8FD744", "#FDE725"];
var colours = '(' + jsColours.join() + ')';
style = 'height: ' + jsColours.length * 20 + 'px; width: 10px; ';
style += 'background: ' + jsColours[1] + ';';
style += 'background: -webkit-linear-gradient' + colours + ';'
style += 'background: -o-linear-gradient' + colours + ';'
style += 'background: -moz-linear-gradient' + colours + ';'
style += 'background: linear-gradient' + colours + ';'
divColours.setAttribute('style', style);
legend.appendChild(divColours);
for (var i = 0; i < 7; i++) {
var left = 10 + 10 + 1;
var top = 10 + (i * 20);
var tick = 'position: absolute; top: ' + top + 'px; left: ' + left + 'px; width: 3px; height: 1px; background: #b8b9ba;';
var tickVal = 'position: absolute; top: ' + (top - 5) + 'px; left: ' + (left + 5) + 'px; background: red; color: #b8b9ba;';
var divTicks = document.createElement('div');
var divVal = document.createElement('div');
divTicks.setAttribute('style', tick);
divVal.setAttribute('style', tickVal);
divVal.innerHTML = ' this is a variable ' + i;
legend.appendChild(divTicks);
legend.appendChild(divVal);
}
CSS
#legend {
font-family: Arial, sans-serif;
background: #fff;
padding: 10px;
margin: 10px;
border: 1px solid #b8b8b8;
border-radius: 4px;
height: auto;
display: inline-block;
}
Working Demo
JSFiddle
Related
I'm trying to adapt this answer
I wrapped your ticks on a parent div tag and appended ticks inside it.
Replace your current JavaScript code with following one. I think you want something like this.
JavaScript
var legend = document.getElementById("legend");
var divColours = document.createElement('div');
var jsColours = ["#440154", "#443A83", "#31688E", "#21908C", "#35B779", "#8FD744", "#FDE725"];
var colours = '(' + jsColours.join() + ')';
style = 'height: ' + jsColours.length * 20 + 'px; width: 10px; ';
style += 'background: ' + jsColours[1] + ';';
style += 'background: -webkit-linear-gradient' + colours + ';'
style += 'background: -o-linear-gradient' + colours + ';'
style += 'background: -moz-linear-gradient' + colours + ';'
style += 'background: linear-gradient' + colours + ';'
divColours.setAttribute('style', style);
legend.appendChild(divColours);
var divTicksParent = document.createElement('div');
divTicksParent.style.position = "absolute";
divTicksParent.style.width = "200px";
divTicksParent.style.top = "28px";
legend.appendChild(divTicksParent);
for (var i = 0; i < 7; i++) {
var left = 10;
var top = (i * 23) + (1);
var tick = 'position: absolute; top: ' + top + 'px; left: ' + left + 'px; width: 6px; height: 1px; background: #b8b9ba;';
var tickVal = 'position: absolute; top: ' + (top - 6) + 'px; left: ' + (left + 12) + 'px; color: #b8b9ba; font-size: 12px;';
var divTicks = document.createElement('div');
var divVal = document.createElement('div');
divTicks.setAttribute('style', tick);
divVal.setAttribute('style', tickVal);
divVal.innerHTML = ' this is a variable ' + i;
divTicksParent.appendChild(divTicks);
divTicksParent.appendChild(divVal);
}
CSS
#legend {
font-family: Arial, sans-serif;
background: #fff;
padding: 10px;
margin: 10px;
border: 1px solid #b8b8b8;
border-radius: 4px;
height: auto;
width: 130px;
display: inline-block;
}
<head>
<style>
#legend {
font-family: Arial, sans-serif;
background: #fff;
padding: 10px;
margin: 10px;
border: 1px solid #b8b8b8;
border-radius: 4px;
display:inline-flex;
}
</style>
</head>
<body onload="myFunc()">
<div id="legend"></div>
<script>
function myFunc(){
var legend = document.getElementById("legend");
var divColours = document.createElement('div');
var jsColours = ["#440154", "#443A83", "#31688E", "#21908C", "#35B779", "#8FD744", "#FDE725"];
var colours = '(' + jsColours.join() + ')';
style = 'height: ' + jsColours.length * 20 + 'px; width: 10px; ';
style += 'background: ' + jsColours[1] + ';';
style += 'background: -webkit-linear-gradient' + colours + ';'
style += 'background: -o-linear-gradient' + colours + ';'
style += 'background: -moz-linear-gradient' + colours + ';'
style += 'background: linear-gradient' + colours + ';'
divColours.setAttribute('style', style);
legend.appendChild(divColours);
var divTicksParent = document.createElement('div');
divTicksParent.style.position = "relative";
divTicksParent.style.width = "170px";
legend.appendChild(divTicksParent);
for (var i = 0; i < 7; i++) {
var left = 20;
var top = (i * 23) + (1);
var tick = 'position: absolute; top: ' + top + 'px; left: ' + left + 'px; width: 8px; height: 1px; background: #b8b9ba;';
var tickVal = 'position: absolute; top: ' + (top - 8) + 'px; left: ' + (left + 15) + 'px; background: red; color: #b8b9ba;';
var divTicks = document.createElement('div');
var divVal = document.createElement('div');
divTicks.setAttribute('style', tick);
divVal.setAttribute('style', tickVal);
divVal.innerHTML = ' this is a variable ' + i;
divTicksParent.appendChild(divTicks);
divTicksParent.appendChild(divVal);
}
};
</script>
</body>
check the demo, I've updated
The other solutions didn't quite answer my question about auto-sizing the width based on the content.
I think this resolves my problem
Updated fiddle
Javascript
var legend = document.getElementById("legend");
var tickContainer = document.createElement("div");
tickContainer.setAttribute('class', 'labelContainer');
var labelContainer = document.createElement("div");
labelContainer.setAttribute('class', 'labelContainer');
var legendColours = document.createElement('div');
var jsColours = ["#440154", "#443A83", "#31688E", "#21908C", "#35B779", "#8FD744", "#FDE725"];
var colours = '(' + jsColours.join() + ')';
style = 'display: inline-block; height: ' + jsColours.length * 20 + 'px; width: 10px;';
style += 'background: ' + jsColours[1] + ';';
style += 'background: -webkit-linear-gradient' + colours + ';'
style += 'background: -o-linear-gradient' + colours + ';'
style += 'background: -moz-linear-gradient' + colours + ';'
style += 'background: linear-gradient' + colours + ';'
legendColours.setAttribute('style', style);
legend.appendChild(legendColours);
for (var i = 0; i < jsColours.length; i++) {
var tickVal = 'text-align: center; color: #b8b9ba; font-size: 12px; height: 20px;';
var divTicks = document.createElement('div');
var divVal = document.createElement('div');
divTicks.setAttribute('style', tickVal);
divTicks.innerHTML = '-';
tickContainer.appendChild(divTicks);
divVal.setAttribute('style', tickVal);
divVal.innerHTML = ' this is a variable ' + i;
labelContainer.appendChild(divVal);
}
legend.appendChild(tickContainer);
legend.appendChild(labelContainer);
CSS
.legend {
font-family: Arial, sans-serif;
background: #fff;
padding: 8px;
margin: 8px;
border: 1px solid #b8b8b8;
border-radius: 4px;
display:inline-flex;
}
.labelContainer{
border: 1px solid #00FF00;
padding-left: 4px;
height: auto;
display: inline-block;
}
Related
This code is working, but google pagespeed detect avoid document.write.
I've tested various alternatives, lining up my HTML elements prior to the JS, then using getElementById, followed by either innerHTML or appendChild, or even lining up the elements inside the JS, by means of createElement, but to no avail, really. maybe my tested was wrong.
Probably a factor as to why they're doing so poorly. I'm sure I couldn't sort the above codes correctly. I'm basically not experienced in JavaScript.
Here is my CSS/HTML/JS inside this snipet code:
.cat-back {
font-size: 18px;
font-weight: 400;
border-bottom: 1px solid #000;
margin-top: 13px;
margin-bottom: 5px;
padding: 5px;
border-left: 3px solid #000
}
.row:after {
content: "";
display: table;
clear: both
}
.catcol {
float: left;
width: 33.33%;
padding: 10px;
box-sizing: border-box
}
.mbtlist {
list-style-type: none;
overflow: hidden
}
.mbtlist li {
margin: 0px auto 20px auto;
clear: both;
color: #666;
font-family: Helvetica;
font-size: 12px;
border-bottom: 1px dotted #ddd;
padding-bottom: 10px;
}
.mbtlist .mbttitle {
font-family: oswald;
font-size: 16px;
color: #0080ff;
font-weight: normal;
text-decoration: none;
}
.mbtlist .mbttitle:hover {
color: #00A5FF;
}
font-family:georgia;
font-size:15px;
font-weight:bold
}
.mbtlist div span {
margin: 0 10px 0 0;
display: inline-block;
}
.mbtlist span {
display: block;
margin: 5px 0px 0px;
padding-right: 5px;
}
.mbtlist .imore {
font-size: 16px;
font-weight: bold;
text-decoration: none;
color: #666;
line-height: 0.7em;
}
.mbtlist img {
float: left;
margin: 0px 10px 10px 0px;
border: 6px solid #fff;
padding: 0px;
width: 80px;
height: 65px;
box-shadow: -1px -1px 4px #777;
}
.mbtlist .icontent {
text-align: justify;
}
<script>
//----------------------------Defaults
var ListBlogLink = window.location.hostname;
var ListCount = 5;
var TitleCount = 70;
var ListLabel = " ";
var ChrCount = 80;
var ImageSize = 100;
//----------------------------Function Start
function mbtlist(json) {
document.write('<ul class="mbtlist">');
for (var i = 0; i < ListCount; i++) {
//-----------------------------Variables Declared
var listing = ListUrl = ListTitle = ListConten = ListContent = ListImage = thumbUrl = sk = "";
//----------------------------- Title URL
for (var j = 0; j < json.feed.entry[i].link.length; j++) {
if (json.feed.entry[i].link[j].rel == 'alternate') {
break;
}
}
ListUrl = "'" + json.feed.entry[i].link[j].href + "'";
//----------------------------------- Title Stirng
if (json.feed.entry[i].title != null) {
ListTitle = json.feed.entry[i].title.$t.substr(0, TitleCount);
}
//----------------------------------- Content Check
ListConten = json.feed.entry[i].content.$t;
ListContent = ListConten.replace(/(<([^>]+)>)/ig, "").substr(0, ChrCount);
//------------------------------------ Thumbnail Check
if (json.feed.entry[i].media$thumbnail) {
thumbUrl = json.feed.entry[i].media$thumbnail.url;
sk = thumbUrl.replace("/s72-c/", "/s" + ImageSize + "/");
ListImage = "'" + sk.replace("?imgmax=800", "") + "'";
}
// Support For 3rd Party Images
else if (json.feed.entry[i].content.$t.match(/src=(.+?[\.jpg|\.gif|\.png]")/) != null) {
ListImage = json.feed.entry[i].content.$t.match(/src=(.+?[\.jpg|\.gif|\.png]")/)[1];
} else {
ListImage = "'http://4.bp.blogspot.com/-HALLtgFeep0/VfryhQ0C5oI/AAAAAAAAPcY/77mSGND4q84/s200/Icon.png'";
}
//----------------------------------- Printing List
var listing = "<li><a href=" +
ListUrl +
"><img src=" +
ListImage +
"/></a><a class='mbttitle' href=" +
ListUrl +
"target='_blank'>" +
ListTitle +
"</a><span class='icontent'>" +
ListContent +
" ... <a href=" +
ListUrl +
" class='imore'>»</a></span></li>";
document.write(listing);
}
document.write("</ul>");
}</script>
<div class='row'>
<div class='catcol'><div class='cat-back'><h3>Seba Top</h3></div></div>
<script>
ListBlogLink = "https://www.sebahotnews.org";
ListCount = 4;
TitleCount = 70;
ListLabel = "seba-top";
ChrCount = 150;
document.write("<script src='" + ListBlogLink + "/feeds/posts/default/-/" + ListLabel + "?alt=json-in-script&callback=mbtlist'></" + "script>");
</script>
</div>
<div class='catcol'><div class='cat-back'><h3>Lead News</h3></div></div>
<script>
ListBlogLink = "https://www.sebahotnews.org";
ListCount = 4;
TitleCount = 70;
ListLabel = "lead-news";
ChrCount = 150;
document.write("<script src='" + ListBlogLink + "/feeds/posts/default/-/" + ListLabel + "?alt=json-in-script&callback=mbtlist'></" + "script>");
</script>
</div>
<div class='catcol'><div class='cat-back'><h3>Top News</h3></div></div>
<script>
ListBlogLink = "https://www.sebahotnews.org";
ListCount = 4;
TitleCount = 70;
ListLabel = "top-news";
ChrCount = 150;
document.write("<script src='" + ListBlogLink + "/feeds/posts/default/-/" + ListLabel + "?alt=json-in-script&callback=mbtlist'></" + "script>");
</script>
</div>
</div>
<div class='row'>
<div class='catcol'><div class='cat-back'><h3>জাতীয়</h3></div></div>
<script>
ListBlogLink = "https://www.sebahotnews.org";
ListCount = 4;
TitleCount = 70;
ListLabel = "জাতীয়";
ChrCount = 150;
document.write("<script src='" + ListBlogLink + "/feeds/posts/default/-/" + ListLabel + "?alt=json-in-script&callback=mbtlist'></" + "script>");
</script>
</div>
<div class='catcol'><div class='cat-back'><h3>রাজনীতি</h3></div></div>
<script>
ListBlogLink = "https://www.sebahotnews.org";
ListCount = 4;
TitleCount = 70;
ListLabel = "রাজনীতি";
ChrCount = 150;
document.write("<script src='" + ListBlogLink + "/feeds/posts/default/-/" + ListLabel + "?alt=json-in-script&callback=mbtlist'></" + "script>");
</script>
</div>
<div class='catcol'><div class='cat-back'><h3>বিশ্ব</h3></div></div>
<script>
ListBlogLink = "https://www.sebahotnews.org";
ListCount = 4;
TitleCount = 70;
ListLabel = "বিশ্ব";
ChrCount = 150;
document.write("<script src='" + ListBlogLink + "/feeds/posts/default/-/" + ListLabel + "?alt=json-in-script&callback=mbtlist'></" + "script>");
</script>
</div>
</div>
Would it be possible for anyone to point me to the right direction?
Please solve this problem any one.
So based on new code I suggest this
//----------------------------Defaults
var ListBlogLink = "https://www.sebahotnews.org",
ListCount = 4,
TitleCount = 70,
ChrCount = 150,
ImageSize = 100;
const lists = [{"label":"seba-top" },{"label":"lead-news" },{"label":"top-news" }]
let cnt = 0;
function next() {
if (cnt>=lists.length) return
document.getElementById("container").innerHTML += `<div class='catcol ${lists[cnt].label}'></div>`
const scr = document.createElement("script");
scr.src = ListBlogLink + "/feeds/posts/default/-/" + lists[cnt].label + "?alt=json-in-script&callback=mbtlist";
document.querySelector("head").appendChild(scr);
};
next(); // start
function mbtlist(json) {
let div = document.querySelector("#container ."+lists[cnt].label);
let html = '<ul class="mbtlist">';
for (var i = 0; i < ListCount; i++) {
//-----------------------------Variables Declared
var listing = ListUrl = ListTitle = ListConten = ListContent = ListImage = thumbUrl = sk = "";
//----------------------------- Title URL
for (var j = 0; j < json.feed.entry[i].link.length; j++) {
if (json.feed.entry[i].link[j].rel == 'alternate') {
break;
}
}
ListUrl = "'" + json.feed.entry[i].link[j].href + "'";
//----------------------------------- Title Stirng
if (json.feed.entry[i].title != null) {
ListTitle = json.feed.entry[i].title.$t.substr(0, TitleCount);
}
//----------------------------------- Content Check
ListConten = json.feed.entry[i].content.$t;
ListContent = ListConten.replace(/(<([^>]+)>)/ig, "").substr(0, ChrCount);
//------------------------------------ Thumbnail Check
if (json.feed.entry[i].media$thumbnail) {
thumbUrl = json.feed.entry[i].media$thumbnail.url;
sk = thumbUrl.replace("/s72-c/", "/s" + ImageSize + "/");
ListImage = "'" + sk.replace("?imgmax=800", "") + "'";
}
// Support For 3rd Party Images
else if (json.feed.entry[i].content.$t.match(/src=(.+?[\.jpg|\.gif|\.png]")/) != null) {
ListImage = json.feed.entry[i].content.$t.match(/src=(.+?[\.jpg|\.gif|\.png]")/)[1];
} else {
ListImage = "'http://4.bp.blogspot.com/-HALLtgFeep0/VfryhQ0C5oI/AAAAAAAAPcY/77mSGND4q84/s200/Icon.png'";
}
//----------------------------------- Printing List
var listing = "<li><a href=" +
ListUrl +
"><img src=" +
ListImage +
"/></a><a class='mbttitle' href=" +
ListUrl +
"target='_blank'>" +
ListTitle +
"</a><span class='icontent'>" +
ListContent +
" ... <a href=" +
ListUrl +
" class='imore'>»</a></span></li>";
html += listing;
}
html += "</ul>";
div.innerHTML = html;
cnt++;
next(); // call next
}
.seba-top { background-color:orange;}
.top-news { background-color:tan;}
.lead-news { background-color:yellow;}
.catcol {
float: left;
width: 33.33%;
padding: 10px;
box-sizing: border-box;
border: 1px solid black;
}
.mbtlist {
list-style-type: none;
overflow: hidden
}
.mbtlist li {
margin: 0px auto 20px auto;
clear: both;
color: #666;
font-family: Helvetica;
font-size: 12px;
border-bottom: 1px dotted #ddd;
padding-bottom: 10px;
}
.mbtlist .mbttitle {
font-family: oswald;
font-size: 16px;
color: #0080ff;
font-weight: normal;
text-decoration: none;
}
.mbtlist .mbttitle:hover {
color: #00A5FF;
}
font-family:georgia;
font-size:15px;
font-weight:bold
}
.mbtlist div span {
margin: 0 10px 0 0;
display: inline-block;
}
.mbtlist span {
display: block;
margin: 5px 0px 0px;
padding-right: 5px;
}
.mbtlist .imore {
font-size: 16px;
font-weight: bold;
text-decoration: none;
color: #666;
line-height: 0.7em;
}
.mbtlist img {
float: left;
margin: 0px 10px 10px 0px;
border: 6px solid #fff;
padding: 0px;
width: 80px;
height: 65px;
box-shadow: -1px -1px 4px #777;
}
.mbtlist .icontent {
text-align: justify;
}
<div id="container"></div>
I'm playing around with a Colour Generator app and I added a "disco" function which will trigger random colours to "flash" to the rythm of a song. By the way, you won't be able to hear it but it's "Turn down for what" :))
Everything works, but: If I click multiple times the "Disco" button, setInterval() will accelerate (which I don't mind, in fact I like it), but it won't be cleared no more once I decide to stop it by scrolling or swiping on mobile.
I read multiple similar questions here, but none had a similar problem, and I really have no clue of what I could do.
I'd like to make it accelerate if clicked multiple times, but I also want to be able to clear it.
let button = document.querySelector('.button')
let body = document.querySelector('.body')
let container = document.querySelector('.container')
let disco = document.querySelector('.disco')
let song = document.querySelector('.song')
button.addEventListener('click', ()=> {
let colorOne = parseInt((Math.random() * 255) + 1)
let colorTwo = parseInt((Math.random() * 255) + 1)
let colorThree = parseInt((Math.random() * 255) + 1)
body.style.background = 'rgb(' + colorOne + ', ' + colorTwo + ', ' + colorThree
+ ')'
document.querySelector('.color').innerText = 'rgb (' + colorOne + ', ' + colorTwo + ', ' + colorThree
+ ')'
button.style.border = 'none'
document.querySelector('.scrollto').style.display = 'block'
disco.style.display = 'none'
})
let dance = function() {
let colorOne = parseInt((Math.random() * 255) + 1)
let colorTwo = parseInt((Math.random() * 255) + 1)
let colorThree = parseInt((Math.random() * 255) + 1)
body.style.background = 'rgb(' + colorOne + ', ' + colorTwo + ', ' + colorThree
+ ')'
}
let dancing;
let stopping;
disco.addEventListener('click', ()=> {
document.querySelector('.scrollto').style.display = 'block'
dancing = setInterval(dance,300)
stopping = setTimeout(function() {
clearInterval(dancing)
button.style.display = 'block'
body.style.background = 'white'
document.querySelector('.scrollto').style.display = 'none'
}, 15400)
if(song.paused) {
song.play()
button.style.display = 'none'
}
})
window.addEventListener('touchmove', ()=> {
body.style.background = 'white'
document.querySelector('.color').innerText = ''
document.querySelector('.scrollto').style.display = 'none'
button.style.border = '1px solid black'
clearInterval(dancing)
clearTimeout(stopping)
song.pause()
song.currentTime = 0
button.style.display = 'block'
disco.style.display = 'block'
})
.button {
font-family: 'Poppins', sans-serif;
border-radius: .5em;
padding: .3em .7em;
font-size: 1.1em;
position: relative;
background: white;
mix-blend-mode: screen;
border: 1px solid black;
}
.color {
font-family: 'Poppins', sans-serif;
color: white;
text-shadow: 1px 1px 3px black;
letter-spacing: 1px;
}
.container {
text-align: center;
position: absolute;
top: 40vh;
left: 50vw;
transform: translate(-50%, -50%);
}
.scrollto {
position: absolute;
bottom: 10px;
left: 50vw;
transform: translateX(-50%);
font-family: 'Poppins', sans-serif;
font-size: .7em;
display: none;
}
.disco {
position: absolute;
bottom: 5px;
right: 10px;
font-family: 'Poppins', sans-serif;
font-size: .8em;
border: .5px solid black;
border-radius: .3em;
padding: 0 .3em;
padding-top: .1em;
}
<body class="body">
<div class="container">
<h3 class="button">Generate Colour</h3>
<p class="color"></p>
</div>
<div class="line">
<p class="scrollto">swipe on screen to reset</p>
</div>
<h3 class="disco">Disco</h3>
<audio class="song" src="song.mp3"></audio>
It is because you change the content of the dancing variable at each click. Means that at click 1 it will reference the setInterval1, at click 2 setInterval2 etc. then when you try to do clearInterval you actually clear only the last reference you created.
You can avoid it by simply clearing the old interval before to add a new one:
(I changed the stop event to right click, for example purpose )
let button = document.querySelector('.button')
let body = document.querySelector('.body')
let container = document.querySelector('.container')
let disco = document.querySelector('.disco')
let song = document.querySelector('.song')
button.addEventListener('click', ()=> {
let colorOne = parseInt((Math.random() * 255) + 1)
let colorTwo = parseInt((Math.random() * 255) + 1)
let colorThree = parseInt((Math.random() * 255) + 1)
body.style.background = 'rgb(' + colorOne + ', ' + colorTwo + ', ' + colorThree
+ ')'
document.querySelector('.color').innerText = 'rgb (' + colorOne + ', ' + colorTwo + ', ' + colorThree
+ ')'
button.style.border = 'none'
document.querySelector('.scrollto').style.display = 'block'
disco.style.display = 'none'
})
let dance = function() {
let colorOne = parseInt((Math.random() * 255) + 1)
let colorTwo = parseInt((Math.random() * 255) + 1)
let colorThree = parseInt((Math.random() * 255) + 1)
body.style.background = 'rgb(' + colorOne + ', ' + colorTwo + ', ' + colorThree
+ ')'
}
let dancing;
let stopping;
disco.addEventListener('click', ()=> {
document.querySelector('.scrollto').style.display = 'block'
clearInterval(dancing);
clearTimeout(stopping)
dancing = setInterval(dance,300)
stopping = setTimeout(function() {
clearInterval(dancing)
button.style.display = 'block'
body.style.background = 'white'
document.querySelector('.scrollto').style.display = 'none'
}, 15400)
if(song.paused) {
//song.play()
button.style.display = 'none'
}
})
window.addEventListener('contextmenu', ()=> {
body.style.background = 'white'
document.querySelector('.color').innerText = ''
document.querySelector('.scrollto').style.display = 'none'
button.style.border = '1px solid black'
clearInterval(dancing)
clearTimeout(stopping)
song.pause()
song.currentTime = 0
button.style.display = 'block'
disco.style.display = 'block'
})
.button {
font-family: 'Poppins', sans-serif;
border-radius: .5em;
padding: .3em .7em;
font-size: 1.1em;
position: relative;
background: white;
mix-blend-mode: screen;
border: 1px solid black;
}
.color {
font-family: 'Poppins', sans-serif;
color: white;
text-shadow: 1px 1px 3px black;
letter-spacing: 1px;
}
.container {
text-align: center;
position: absolute;
top: 40vh;
left: 50vw;
transform: translate(-50%, -50%);
}
.scrollto {
position: absolute;
bottom: 10px;
left: 50vw;
transform: translateX(-50%);
font-family: 'Poppins', sans-serif;
font-size: .7em;
display: none;
}
.disco {
position: absolute;
bottom: 5px;
right: 10px;
font-family: 'Poppins', sans-serif;
font-size: .8em;
border: .5px solid black;
border-radius: .3em;
padding: 0 .3em;
padding-top: .1em;
}
<body class="body">
<div class="container">
<h3 class="button">Generate Colour</h3>
<p class="color"></p>
</div>
<div class="line">
<p class="scrollto">swipe on screen to reset</p>
</div>
<h3 class="disco">Disco</h3>
<audio class="song" src="song.mp3"></audio>
EDIT:
From the comments, I see that you want to keep the accelerating effect:
let button = document.querySelector('.button')
let body = document.querySelector('.body')
let container = document.querySelector('.container')
let disco = document.querySelector('.disco')
let song = document.querySelector('.song')
button.addEventListener('click', ()=> {
let colorOne = parseInt((Math.random() * 255) + 1)
let colorTwo = parseInt((Math.random() * 255) + 1)
let colorThree = parseInt((Math.random() * 255) + 1)
body.style.background = 'rgb(' + colorOne + ', ' + colorTwo + ', ' + colorThree
+ ')'
document.querySelector('.color').innerText = 'rgb (' + colorOne + ', ' + colorTwo + ', ' + colorThree
+ ')'
button.style.border = 'none'
document.querySelector('.scrollto').style.display = 'block'
disco.style.display = 'none'
})
let dance = function() {
let colorOne = parseInt((Math.random() * 255) + 1)
let colorTwo = parseInt((Math.random() * 255) + 1)
let colorThree = parseInt((Math.random() * 255) + 1)
body.style.background = 'rgb(' + colorOne + ', ' + colorTwo + ', ' + colorThree
+ ')'
}
let dancing;
let stopping;
let speed = 300;
const accFactor = 1.5;
disco.addEventListener('click', ()=> {
document.querySelector('.scrollto').style.display = 'block'
if(dancing) {
clearInterval(dancing);
clearTimeout(stopping);
speed = speed/accFactor;
}
dancing = setInterval(dance,speed);
stopping = setTimeout(function() {
clearInterval(dancing)
button.style.display = 'block'
body.style.background = 'white'
document.querySelector('.scrollto').style.display = 'none'
}, 15400)
if(song.paused) {
//song.play()
button.style.display = 'none'
}
})
window.addEventListener('contextmenu', ()=> {
body.style.background = 'white'
document.querySelector('.color').innerText = ''
document.querySelector('.scrollto').style.display = 'none'
button.style.border = '1px solid black'
clearInterval(dancing)
clearTimeout(stopping)
song.pause()
song.currentTime = 0
button.style.display = 'block'
disco.style.display = 'block'
})
.button {
font-family: 'Poppins', sans-serif;
border-radius: .5em;
padding: .3em .7em;
font-size: 1.1em;
position: relative;
background: white;
mix-blend-mode: screen;
border: 1px solid black;
}
.color {
font-family: 'Poppins', sans-serif;
color: white;
text-shadow: 1px 1px 3px black;
letter-spacing: 1px;
}
.container {
text-align: center;
position: absolute;
top: 40vh;
left: 50vw;
transform: translate(-50%, -50%);
}
.scrollto {
position: absolute;
bottom: 10px;
left: 50vw;
transform: translateX(-50%);
font-family: 'Poppins', sans-serif;
font-size: .7em;
display: none;
}
.disco {
position: absolute;
bottom: 5px;
right: 10px;
font-family: 'Poppins', sans-serif;
font-size: .8em;
border: .5px solid black;
border-radius: .3em;
padding: 0 .3em;
padding-top: .1em;
}
<body class="body">
<div class="container">
<h3 class="button">Generate Colour</h3>
<p class="color"></p>
</div>
<div class="line">
<p class="scrollto">swipe on screen to reset</p>
</div>
<h3 class="disco">Disco</h3>
<audio class="song" src="song.mp3"></audio>
In my project there could be any amount of divs like a thousand, two thousand, a million etc.. I want their background colors to go from green to red. so they all get a different shade of color. the first div will be "real" green the last div will be "real" red.
Here is what I have. As you can see there are divs at the end that get left without a background-color. I would prefer to solve this using rgb.
$(function(){
var r = 20;
var g = 200;
var b = 10;
for(var i = 0; i < 300; i++){
$("body").append("<div class = 'box'>");
}
$(".box").each(function(){
if(g > 0 && r < 255){
$(this).css("background", "rgb("+ r + ","+ g + ","+ b + ")");
g-=1;
r+=1;
}
})
})
.box{
border:2px solid black;
margin: 10px;
width: 20%;
height: 100px;
float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
yea I don't mind if there is a little duplication. The main point is
that at the beginning of the display users see green and further away
they see things turning red.
Try without if condition
$(function(){
var r = 20;
var g = 200;
var b = 10;
for(var i = 0; i < 300; i++){
$("body").append("<div class = 'box'>");
}
$(".box").each(function(){
$(this).css("background", "rgb("+ r + ","+ g + ","+ b + ")");
g-= 1;
r+= 1;
})
})
.box{
border:2px solid black;
margin: 10px;
width: 20%;
height: 100px;
float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
Try this, do not Increment and decrements the value of r and g at the same time, do it alternatively...
$(function(){
var r = 55
var g = 200;
var b = 0;
for(var i = 0; i < 300; i++){
$("body").append("<div class = 'box'>");
}
$(".box").each(function(i){
if(g > 0 && r < 255){
$(this).css("background", "rgb("+ r + ","+ g + ","+ b + ")");
if(i%2 == 0)
{
g-=1;
}
else
{
r+=1;
}
}
})
})
.box{
border:2px solid black;
margin: 10px;
width: 20%;
height: 100px;
float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Someone wrote this earlier but deleted it.
$(function(){
var r = 20;
var g = 200;
var b = 10;
for(var i = 0; i < 300; i++){
$("body").append("<div class = 'box'>");
}
var noOfBoxes = $(".box").length,
minRed = 20,
maxRed = 255,
maxGreen = 200
$(".box").each(function(i){
$(this).css("background", "rgb(" + r + "," + g + "," + b + ")");
g = parseInt(maxGreen - maxGreen * (i /noOfBoxes), 10)
r = parseInt(minRed + maxRed * (i/ noOfBoxes), 10)
console.log(g)
})
})
.box{
border:2px solid black;
margin: 10px;
width: 20%;
height: 100px;
float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
An approach utilizing css linear-gradient at background of container element holding .box elements, transparent background at .box elements; included outline , border to mask linear-gradient visibility at outside right of container; note this portion of css could still be improved. Set for loop to 2000 iterations. linear-gradient should display expected color transitions gradually from lime to red between 0 to n .box elements.
for (var i = 0, container = document.getElementById("container"); i < 2000; i++) {
container.insertAdjacentHTML("beforeend", "<div class=box></div>");
};
body {
overflow-x: hidden;
}
#container {
background: linear-gradient(to bottom, lime, red);
outline:25px solid #fff;
border:25px solid #fff;
width: calc(100vw - 2.5%); /* adjusted for width of stacksnippets */
height: auto;
display: block;
overflow-x: hidden;
}
.box {
border: 2px solid black;
margin: 10px;
width: 20%;
height: 100px;
float: left;
background: transparent;
outline: 20px solid #fff;
}
<div id="container">
</div>
jsfiddle https://jsfiddle.net/0kL4f59z/5/
I am making a game so I stared at it for awhile (and yes, I did look at the developer log console for errors), and found no errors (within my reasoning) of why it wouldn't open a battle function.
It is saying that for whatever reason that Giant is not defined when clicked, Zombie is not defined when clicked, and for Giant Spider it says something along the lines of missing parameter. I am quite sure it falls down to the code below -->
for(var z = 0; z < monsters.length; z++) {
Gid("atkOpt_container").innerHTML += ("<div onclick='battle(" + monsters[z].name + "," + this.value + ")' class='monsterContainer' value=" + z + "><div class='monsterT'>" + monsters[z].name + "</div><table><tr><td>Strength</td><td>Health</td><td>XP</td><td>Level</td></tr><tr><td>" + monsters[z].dmg + "</td><td>" + monsters[z].hp + "</td><td>" + monsters[z].xp + "</td><td>" + monsters[z].lvl + "</td></tr></table></div>");
}
If you wish to look at all the code look below. And if you're wondering why everything is so small it's because I'm making it on my phone, and transferred it to ask via GitHub.
var monsters = []; //All monsters are stored here
//All types of monsters are listed below
monsters.push(new monster_prototype("Giant", 50, 30, 1, 20, 20));
monsters.push(new monster_prototype("Giant spider", 20, 50, 1, 15, 30));
monsters.push(new monster_prototype("Zombie", 50, 50, 2, 40, 70));
for (var z = 0; z < monsters.length; z++) {
Gid("atkOpt_container").innerHTML += ("<div onclick='battle(" + monsters[z].name + "," + this.value + ")' class='monsterContainer' value=" + z + "><div class='monsterT'>" + monsters[z].name + "</div><table><tr><td>Strength</td><td>Health</td><td>XP</td><td>Level</td></tr><tr><td>" + monsters[z].dmg + "</td><td>" + monsters[z].hp + "</td><td>" + monsters[z].xp + "</td><td>" + monsters[z].lvl + "</td></tr></table></div>");
} //Where I believe the error occurs, it basically loads all monster stats into a div
function Gid(id) {
return document.getElementById(id);
} //So I don't have to write the whole document.getElementById
function monster_prototype(name, hp, dmg, lvl, xp, money) {
this.name = name;
this.hp = hp;
this.dmg = dmg;
this.lvl = lvl;
this.xp = xp,
this.money = money;
} //How I store the monsters info
function save() {
localStorage.player = JSON.stringify(playerStats);
}
var playerStats = {
lvl: 1,
xp: 0,
xpToLvl: 100,
name: null,
dmg: null,
hp: null,
money: 100
};
if (localStorage.player === undefined) {
save();
playerSetup();
} else {
playerStats = JSON.parse(localStorage.player);
alert("Welcome back " + playerStats.name);
refreshStats();
} //Checks if the player is new, and if so starts the main player setup. If not it loads it
function refreshStats() {
Gid("maxDmg").innerHTML = "Max damage: " + playerStats.dmg;
Gid("hp").innerHTML = "Health: " + playerStats.hp;
} //Refreshes some stats
function playerSetup() {
document.getElementById("mainContainer").style.display = "none";
$("#class_container").show();
}
function classChosen(pClass) {
if (pClass === "Juggernaut") {
playerStats.hp = 100;
playerStats.dmg = 10;
} else if (pClass === "Average Joe") {
playerStats.hp = 60;
playerStats.dmg = 30;
} else {
playerStats.hp = 40;
playerStats.dmg = 70;
}
refreshStats();
document.getElementById("class_container").style.display = "none";
var getName = prompt("What is your name?");
playerStats.name = getName;
document.getElementById("mainContainer").style.display = "block";
save();
} //Starts the class choosing feature
function toggle(id) {
$("#" + id).toggle();
} //Toggles display (Hidden or block)
function restartGame() {
localStorage.removeItem('player');
location.reload();
}
function battle(enemy, enemyLoc) {
console.log(enemy + " and " + enemyLoc);
enemy = enemy.toLowerCase();
Gid("attackInfo").innerHTML = "";
var battleWords = ['slashed', 'bashed', 'stabbed', 'punched'];
var enemyHp = monsters[enemyLoc].hp;
var enemyDmg = monsters[enemyLoc].dmg;
var playerHp = playerStats.hp;
var playerDmg = playerStats.dmg;
var battleLoop = setInterval(function() {
var atkName1 = Math.floor(Math.random() * battleWords.length);
var atkName2 = Math.floor(Math.random() * battleWords.length);
var enemyDealt = Math.round(Math.random() * enemyDmg);
var playerDealt = Math.round(Math.random() * enemyDmg);
playerHp -= enemyDealt;
enemyHp -= playerDealt;
Gid("attackInfo").innerHTML += ("<strong>•</strong>" + enemy + " " + battleWords[atkName1] + " you and dealt " + enemyDealt + " damage to you and you now have " + playerHp + " health remaining.<br>You " + battleWords[atkName2] + " the " + enemy + " and dealt " + playerDealt + " damage. The " + enemy + " has " + enemyHp + " health remaining.<br><br>");
if (enemyHp <= 0 && playerHp <= 0) {
clearInterval(battleLoop);
alert("You both died at the same time! A win... but mainly a loss. Game over");
restartGame();
} else if (enemyHp <= 0) {
clearInterval(battleLoop);
alert("You won!");
playerStats.money += monsters[enemyLoc].money;
playerStats.xp += monsters[enemyLoc].xp;
if (playerStats.xp >= playerStats.xpToLvl) levelUp();
} else if (playerHp <= 0) {
alert("Game over");
clearInterval(battleLoop);
restartGame();
}
}, 1000);
} //Main battle, this is the function that won't load
function levelUp() {
} //TBA
#container {
background-color: gray;
width: 300px;
height: 350px;
margin: auto;
}
#atkOpt_container {
display: none;
}
#attackBtn {
background-color: black;
width: 96px;
color: yellow;
border: 4px groove red;
float: left;
font-size: 30px;
text-align: center;
display: block;
margin-top: 5px;
margin-left: 5px;
}
#attackInfo {
float: left;
background-color: #eee;
width: 200px;
font-size: 10px;
height: 250px;
clear: left;
display: block;
margin-top: 5px;
margin-left: 5px;
border: 2px solid red;
}
#class_container {
z-index: 10;
display: none;
width: 300px;
height: 150px;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
background-color: orange;
overflow: auto;
border: 5px groove black;
}
.playerClass {
margin: auto;
width: 200px;
border: 5px groove red;
color: #00FF00;
font-size: 35px;
text-align: center;
margin-bottom: 5px;
display: block;
background-color: black;
}
#title {
width: 95%;
background-color: black;
color: #00FF00;
border: 1px solid orange;
font-size: 25px;
font-weight: bolder;
text-align: center;
margin: auto;
}
#atkOpt_container {
z-index: 11;
width: 275px;
height: 300px;
overflow: auto;
background-color: black;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
border: 2px solid orange;
}
.monsterContainer {
width: 200px;
margin: auto;
text-align: center;
background-color: orange;
border: 5px groove red;
margin-bottom: 5px;
}
.monsterT {
width: 100%;
background-color: black;
color: #eee;
font-size: 30px;
text-align: center;
}
td {
background-color: Cyan;
font-size: 15px;
width: 49%;
border: 1px solid black;
}
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-1.9.1.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div id="class_container">
<div id="title">Choose a class</div>
<div onclick="classChosen(this.innerHTML)" class="playerClass">Juggernaut</div>
<div onclick="classChosen(this.innerHTML)" class="playerClass">Masculine Mat</div>
<div onclick="classChosen(this.innerHTML)" class="playerClass">Average Joe</div>
</div>
<div id="mainContainer">
<div id="container">
<div id="attackBtn" onclick="toggle('atkOpt_container'); toggle('mainContainer');">Attack</div>
<div id="attackInfo"></div>
<div id="maxDmg">Max damage: 0</div>
<div id="hp">Health: 0</div>
</div>
<button onclick="restartGame();">Delete stats</button>
</div>
<div id="atkOpt_container"></div>
</body>
</html>
Because
"<div onclick='battle(" + monsters[z].name + "," + this.value + ")'
produces
<div onclick='battle(whatever, whatever)'
Which is wrong, because you do not have quotes around the strings. You need to quote them. So add in the "
"<div onclick='battle(\"" + monsters[z].name + "\",\"" + this.value + "\")'
Ideally you would use DOM methods such as createElement and addEventListener so you would not have to deal with this.
In the below code, why aren't the values in the array appending to the div element but I am able to append it to the heading? I am storing semicolon separated values in a local storage, then splitting each item and appending it to the div.
<!DOCTYPE html>
<html>
<head>
<title>To do</title>
<style type="text/css">
html {
overflow-y: scroll;
}
body {
padding: 0px;
margin: 0px;
font-family: Verdana, Geneva, sans-serif
}
h2 {
color: black;
text-align: center
}
#omnibox {
margin-left: 400px;
height: 30px;
width: 500px;
font-size: 14px;
padding: 10px;
position: center;
}
#searchWrapper {
margin-left: 500px
}
/*#omnibox,#listWrapper{margin:20px;position:center}*/
.searchable {
color: white;
display: block;
padding: 10px;
font-size: 16px;
background: #4298E8;
width: 300px;
margin-bottom: 10px
}
.searchable:hover {
background-color: #E8C420;
}
.delete {
display: block;
float: right;
height: 20px;
width: 20px;
line-height: 20px;
border-radius: 10px;
background-color: black;
color: white;
text-align: center;
font-size: 1em;
transform: rotate(-45deg);
}
.delete:hover {
background-color: #D8FFF1;
color: red;
cursor: pointer;
}
.comments {
margin-left: -10px;
margin-top: 10px;
width: 310px;
display: inline-block
}
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
console.log('ready');
$(function() {
// body...
$('#omnibox').focus();
if (window.localStorage) {
localStorage.setItem(1,"how do;you do");
localStorage.setItem(2,"ok;got it");
myList();
function myList() {
var list = "";
console.log('Items in Local Storage = ' + localStorage.length);
document.querySelector('h2').innerHTML = "To do - " + localStorage.length;
for (var i = localStorage.length - 1; i >= 0; i--) {
var itemKey = localStorage.key(i);
var values = new Array();
values = localStorage.getItem(itemKey);
values = values.split(";");
console.log("Array - " + values + " Items - " + values.length);
list += "<div class='searchable' id='" + itemKey + "'><span class='note'>" + itemKey + " " + values[0] + " </span><input type='text' class='comments' placeholder='Comments.'><br/></div>";
var myComments = ""
for (var j = values.length - 1; j >= 0; j--) {
console.log("Element - " + values[j] + " parentNode is " + itemKey);
myComments += '<span>' + ' ' + values[j] + ' ' + '</span>';
};
//Why doesn't this work?
$("#itemKey").append(myComments);
//This works though.
$("h2").append(myComments);
}
$("#listWrapper").html(list);
}
var todo = document.querySelector('#omnibox');
$('#omnibox').keyup(function(e) {
document.querySelector('.errorMessage').innerHTML = "";
if (e.keyCode == 13) {
var todoVal = document.querySelector('#omnibox').value;
if (!todoVal.match(/\S/)) {
console.log('Empty value entered.');
document.querySelector('.errorMessage').innerHTML = "Enter something!";
return false;
} else {
console.log("Some value entered.");
$(this).trigger("enterKey");
var remember = new Array();
myNote = document.querySelector('#omnibox').value;
$('#omnibox').val("");
document.location.reload(true);
return true;
}
}
});
}
});
</script>
</head>
<body>
<h2></h2>
<div id='searchWrapper'>
<div id="listAddWrapper">
<div id="empty"></div>
</div>
<div id="listWrapper">
</div>
</div>
</body>
</html>
You can't use a selector to find an element before you've added it to the DOM. Even if you could, your selector is wrong — it should be "#" + itemKey. But that doesn't matter because it won't work anyway; the element it would match is still just part of that list string you're building.
Looking at your code, I think the best thing to do is to add the comments to the text while you're building it.
list += "<div class='searchable' id='" + itemKey + "'><span class='note'>" + itemKey + " " + values[0] + " </span><input type='text' class='comments' placeholder='Comments.'><br/>";
var myComments = ""
for (var j = values.length - 1; j >= 0; j--) {
console.log("Element - " + values[j] + " parentNode is " + itemKey);
myComments += '<span>' + ' ' + values[j] + ' ' + '</span>';
};
list += myComments + "</div>";