Background toggle JS only works once - javascript

So I have a button on my website that looks like this:
<button id = "bgb">Toggle Background</button>
And I want this button to turn on and off the background in a box. Therefore I made a script in JavaScript to do this.
var bg = true;
document.querySelector("#bgb").onclick = function(){
const mb = document.querySelector(".Main-Box");
if (bg == true)
{
mb.style.background = "white";
bgb = false;
}
if (bg == false)
{
mb.style.background = "linear-gradient(45deg,#F17C58, #E94584, #24AADB , #27DBB1,#FFDC18, #FF3706)";
bgb = true;
}
}
However, when I click on the button, It tuns it off fine but when I want to turn it back on it doesn't work; any suggestions?

bg is always set true.
why you change "bgb"?
try
<script>
var bg = true;
document.querySelector("#bgb").onclick = function () {
const mb = document.querySelector(".Main-Box");
if (bg) {
mb.style.background = "red";
bg = false;
} else {
mb.style.background = "linear-gradient(45deg,#F17C58, #E94584, #24AADB , #27DBB1,#FFDC18, #FF3706)";
bg = true;
}
}
</script>

Here is a demo of what you want:
let bg = true;
document.querySelector("#bgb").onclick = function(){
const mb = document.querySelector(".Main-Box");
if (bg == true)
{
mb.style.background = "white";
bg = false;
}
else if (bg == false)
{
mb.style.background = "linear-gradient(45deg,#F17C58, #E94584, #24AADB , #27DBB1,#FFDC18, #FF3706)";
bg = true;
}
}
.Main-Box {
width: 100vw;
height: 100vh;
background: linear-gradient(45deg,#F17C58, #E94584, #24AADB , #27DBB1,#FFDC18, #FF3706);
}
<div class='Main-Box'>
<button id="bgb">Click Me!</button>
</div>

#cSharp already gave you a solution to your issue. However to make your entire code shorter and easier you could simply use: classList.toggle() and apply the changes by toggeling a CSS-Class on and off:
document.querySelector('#bgb').addEventListener("click", function() {
document.querySelector('.Main-Box').classList.toggle('class-name');
});
.Main-Box {
width: 100vw;
height: 100vh;
background: linear-gradient(45deg, #F17C58, #E94584, #24AADB, #27DBB1, #FFDC18, #FF3706);
}
.class-name {
background: white;
}
/* for visualisation only */
body {
margin: 0;
}
<div class='Main-Box'>
<button id="bgb">Click Me!</button>
</div>

If it is not necessary, I will not use global variables to control the state.
In addition, you can also create a new class attribute, and you only need to control the class when switching.
Below are examples of both approaches for your reference.
document.querySelector('input[type=button]').onclick = function() {
switchLinearGradientBackground('.main-box', 'linear-gradient');
}
function switchLinearGradientBackground(selector, switchClassName) {
const elems = document.querySelectorAll(selector);
for (let index = 0; index < elems.length; index++) {
elems[index].classList.toggle(switchClassName);
}
}
body {
display: flex;
}
.main-box {
flex-direction: column;
display: flex;
width: 200px;
height: 200px;
}
.linear-gradient {
background: linear-gradient(45deg, #F17C58, #E94584, #24AADB, #27DBB1, #FFDC18, #FF3706) !important;
}
<div class='main-box' />
<input type='button' value="switch background">
document.querySelector('input[type=button]').onclick = function() {
switchLinearGradientBackground('.main-box');
}
function switchLinearGradientBackground(selector) {
const elems = document.querySelectorAll(selector);
const grad = 'linear-gradient(45deg, #F17C58, #E94584, #24AADB, #27DBB1, #FFDC18, #FF3706)';
for (let index = 0; index < elems.length; index++) {
const style = elems[index].style;
style.background = style.background.length > 0 ? '' : grad;
}
}
body {
display: flex;
}
.main-box {
flex-direction: column;
display: flex;
width: 200px;
height: 200px;
}
<div class='main-box' />
<input type='button' value="switch background">

Related

On-off button function two condition

Only working if side. El
let openedTopAdsButton = true;
const onOffCollapsedAds = () => {
if (openedTopAdsButton) {
document.querySelector(".collapsed-top-ads").style.opacity = "0";
document.querySelector(".collapsed-top-ads").style.height = "0";
document.querySelector(".collapsed-top-ads-button").textContent =
"show";
openedTopAdsButton = false;
} else {
document.querySelector(".collapsed-top-ads").style.opacity = "1";
document.querySelector(".collapsed-top-ads").style.height = "auto";
document.querySelector(".collapsed-top-ads-button").textContent =
"close";
openedTopAdsButton = true;
}
};
.collapsed-top-ads {
width: 10%;
height:100px;
margin-left: auto;
margin-right: auto;
height: auto;
transition: all 0.5 ease-in-out;
}
.collapsed-top-ads-img {
width: 100%;
}
.collapsed-top-ads-img img {
width: 100%;
height: 100%;
object-fit: contain !important;
}
.collapsed-top-ads-button {
width: 100%;
border: none;
height: 30px;
background-color: white;
font-weight: 500;
transition: all 0.5 ease-in-out;
}
<div class="collapsed-top-ads">
<div class="collapsed-top-ads-img">
<img src="https://pbs.twimg.com/profile_images/1502802652777779200/6_hqg9tl_400x400.png" alt="british-turks">
</div>
</div>
<button onclick="onOffCollapsedAds()" class="collapsed-top-ads-button"close</button>
se condition doesnt work. whats wrong here? EDİT: I have attached the example upon request. I didn't get any changing result. When I declare it from the outside, only the first condition is accepted as true and the other one is not triggered.
This condition will always be true:
let openedTopAdsButton = true;
if (openedTopAdsButton) {
//...
}
Because when you define a variable to equal true, that variable will then equal true.
It looks like you are expecting the value of the variable to change over time for multiple calls to the onOffCollapsedAds function. If that's the case then you don't want to re-define the variable and explicitly set it to true on every call to the function. Instead, define the variable outside the function so its value can persist across function calls:
let openedTopAdsButton = true;
const onOffCollapsedAds = () => {
if (openedTopAdsButton) {
//...
openedTopAdsButton = false;
} else {
//...
openedTopAdsButton = true;
}
};

How to show "next" and "previous" buttons of a item in a array?

Im trying to use a array who contains 4 diferent maps.
The first element of the array must be "sticked" and change the current element of the array by clicking next.
The next button when it reaches to the last item of the array must be showed disabled.
The previous button is disabled and when the next is clicked it should be unabled.
Im pretty lost right now any suggestion or advice will be very welcomed
var i = 0;
var mapsArray = [
"https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d209569.44700750793!2d-56.380275318336025!3d-34.84309361411796!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x959f802b6753b221%3A0x3257eb39860f05a6!2sPalacio%20Salvo!5e0!3m2!1sen!2suy!4v1614269355326!5m2!1sen!2suy",
"https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d92110.09563909167!2d17.958933187703266!3d59.32686333113927!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x465f763119640bcb%3A0xa80d27d3679d7766!2sStockholm%2C%20Sweden!5e0!3m2!1sen!2suy!4v1614704350417!5m2!1sen!2suy",
"https://www.google.com/maps/embed?pb=!1m14!1m8!1m3!1d88989.45462143555!2d15.9390973!3d45.8128514!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x4765d701f8ef1d1d%3A0x312b512f1e7f6df9!2sCathedral%20of%20Zagreb!5e0!3m2!1sen!2suy!4v1614704668458!5m2!1sen!2suy",
"https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d6709.917127499258!2d-78.51409209928569!3d0.3576385746900253!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x8e2a5da2881494ab%3A0xae89047fc027c897!2sapuela%20imbabura%20intac!5e0!3m2!1sen!2suy!4v1614704741586!5m2!1sen!2suy"
];
document.getElementById('myIframe').src = mapsArray[Math.floor(Math.random() * mapsArray.length)];
const prevBtn = document.querySelector(".prev");
const nextBtn = document.querySelector(".next");
function nextBtn() {
i = i + 1;
i = i % mapsArray.length;
return mapsArray[i];
}
function prevBtn() {
if (i === 0) {
i = mapsArray.length;
}
i = i - 1;
return mapsArray[i]
}
.maps {
display: flex;
justify-content: center;
align-items: center;
}
#myIframe {
width: 600px;
height: 600px;
}
<div class="maps">
<iframe id='myIframe' class="maps-gallery active"></iframe>
</div>
<div class="btns">
<button disabled onclick="nextBtn()" class="btn prev">Prev</button>
<button onclick="prevBtn()" class="btn next">Next</button>
you can not have button name and function calling the same name hence the error in console.
save your iframe in variable and then do iFrame.src = mapsArray[i] inside both back and next functions.
Check the index numbers in functions and accordingly disable the buttons based on first/last/middle number of index array.
var i = 0;
var mapsArray = [
"https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d209569.44700750793!2d-56.380275318336025!3d-34.84309361411796!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x959f802b6753b221%3A0x3257eb39860f05a6!2sPalacio%20Salvo!5e0!3m2!1sen!2suy!4v1614269355326!5m2!1sen!2suy",
"https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d92110.09563909167!2d17.958933187703266!3d59.32686333113927!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x465f763119640bcb%3A0xa80d27d3679d7766!2sStockholm%2C%20Sweden!5e0!3m2!1sen!2suy!4v1614704350417!5m2!1sen!2suy",
"https://www.google.com/maps/embed?pb=!1m14!1m8!1m3!1d88989.45462143555!2d15.9390973!3d45.8128514!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x4765d701f8ef1d1d%3A0x312b512f1e7f6df9!2sCathedral%20of%20Zagreb!5e0!3m2!1sen!2suy!4v1614704668458!5m2!1sen!2suy",
"https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d6709.917127499258!2d-78.51409209928569!3d0.3576385746900253!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x8e2a5da2881494ab%3A0xae89047fc027c897!2sapuela%20imbabura%20intac!5e0!3m2!1sen!2suy!4v1614704741586!5m2!1sen!2suy"
];
let iFrame = document.getElementById('myIframe')
iFrame.src = mapsArray[Math.floor(Math.random() * mapsArray.length)];
const prevB = document.querySelector(".prev");
const nextB = document.querySelector(".next");
function nextBtn() {
console.clear()
if (i >= 0 && i < 3) {
iFrame.src = mapsArray[i]
prevB.disabled = false
console.log("next button array index set:" + i)
i++
} else {
iFrame.src = mapsArray[i]
nextB.disabled = true
console.log("next button array index set:" + i)
i++
}
}
function prevBtn() {
if (i === 0) {
i = mapsArray.length;
}
i = i - 1;
console.clear()
console.log("prev array index:" + i)
if (i <= 3 && i > 0) {
iFrame.src = mapsArray[i]
nextB.disabled = false
} else {
iFrame.src = mapsArray[i]
prevB.disabled = true
}
}
.maps {
display: flex;
justify-content: center;
align-items: center;
}
#myIframe {
width: 150px;
height: 150px;
}
<div class="maps">
<iframe id='myIframe' class="maps-gallery active"></iframe>
</div>
<div class="btns">
<button disabled onclick="prevBtn()" class="btn prev">Prev</button>
<button onclick="nextBtn()" class="btn next">Next</button>
</div>
This should work:
var mapsArray = [
"https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d209569.44700750793!2d-56.380275318336025!3d-34.84309361411796!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x959f802b6753b221%3A0x3257eb39860f05a6!2sPalacio%20Salvo!5e0!3m2!1sen!2suy!4v1614269355326!5m2!1sen!2suy",
"https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d92110.09563909167!2d17.958933187703266!3d59.32686333113927!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x465f763119640bcb%3A0xa80d27d3679d7766!2sStockholm%2C%20Sweden!5e0!3m2!1sen!2suy!4v1614704350417!5m2!1sen!2suy",
"https://www.google.com/maps/embed?pb=!1m14!1m8!1m3!1d88989.45462143555!2d15.9390973!3d45.8128514!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x4765d701f8ef1d1d%3A0x312b512f1e7f6df9!2sCathedral%20of%20Zagreb!5e0!3m2!1sen!2suy!4v1614704668458!5m2!1sen!2suy",
"https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d6709.917127499258!2d-78.51409209928569!3d0.3576385746900253!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x8e2a5da2881494ab%3A0xae89047fc027c897!2sapuela%20imbabura%20intac!5e0!3m2!1sen!2suy!4v1614704741586!5m2!1sen!2suy"
];
var i = Math.floor(Math.random() * mapsArray.length);
var iFrameElement = document.getElementById('myiFrame')
iFrameElement .src = mapsArray[i];
function nextBtn() {
if (i === mapsArray.length) i = 0;
else i += 1;
iFrameElement.src = mapsArray[i];
}
function prevBtn() {
if (i === 0) i = mapsArray.length;
else i -= 1;
iFrameElement.src = mapsArray[i];
}
.maps {
display: flex;
justify-content: center;
align-items: center;
}
#myiFrame {
width: 600px;
height: 600px;
}
<div class="maps">
<iframe id="myiFrame"></iframe>
</div>
<div class="btns">
<button onclick="nextBtn()">Prev</button>
<button onclick="prevBtn()">Next</button>
</div>
Here is a simple approach -->
var mapsArray = [
"https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d209569.44700750793!2d-56.380275318336025!3d-34.84309361411796!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x959f802b6753b221%3A0x3257eb39860f05a6!2sPalacio%20Salvo!5e0!3m2!1sen!2suy!4v1614269355326!5m2!1sen!2suy",
"https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d92110.09563909167!2d17.958933187703266!3d59.32686333113927!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x465f763119640bcb%3A0xa80d27d3679d7766!2sStockholm%2C%20Sweden!5e0!3m2!1sen!2suy!4v1614704350417!5m2!1sen!2suy",
"https://www.google.com/maps/embed?pb=!1m14!1m8!1m3!1d88989.45462143555!2d15.9390973!3d45.8128514!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x4765d701f8ef1d1d%3A0x312b512f1e7f6df9!2sCathedral%20of%20Zagreb!5e0!3m2!1sen!2suy!4v1614704668458!5m2!1sen!2suy",
"https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d6709.917127499258!2d-78.51409209928569!3d0.3576385746900253!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x8e2a5da2881494ab%3A0xae89047fc027c897!2sapuela%20imbabura%20intac!5e0!3m2!1sen!2suy!4v1614704741586!5m2!1sen!2suy"
];
var index = 0;
const _prevBtn = document.querySelector(".prev");
const _nextBtn = document.querySelector(".next");
update();
function update() {
document.getElementById('myIframe').src = mapsArray[index];
btnDisableCheck();
}
function nextBtn() {
if (index < mapsArray.length - 1) {
index++;
_prevBtn.disabled = false;
update();
}
}
function prevBtn() {
if (index > 0) {
index--;
_nextBtn.disabled = false;
update();
}
}
function btnDisableCheck() {
if (index == 0)
_prevBtn.disabled = true;
if (index == mapsArray.length - 1)
_nextBtn.disabled = true;
}
<iframe id='myIframe' class="maps-gallery active"></iframe>
<button onclick="prevBtn()" class="btn prev">Prev</button>
<button onclick="nextBtn()" class="btn next">Next</button>
I think this is what you want, but i had to change a few things:
var mapsArray = [
"https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d209569.44700750793!2d-56.380275318336025!3d-34.84309361411796!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x959f802b6753b221%3A0x3257eb39860f05a6!2sPalacio%20Salvo!5e0!3m2!1sen!2suy!4v1614269355326!5m2!1sen!2suy",
"https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d92110.09563909167!2d17.958933187703266!3d59.32686333113927!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x465f763119640bcb%3A0xa80d27d3679d7766!2sStockholm%2C%20Sweden!5e0!3m2!1sen!2suy!4v1614704350417!5m2!1sen!2suy",
"https://www.google.com/maps/embed?pb=!1m14!1m8!1m3!1d88989.45462143555!2d15.9390973!3d45.8128514!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x4765d701f8ef1d1d%3A0x312b512f1e7f6df9!2sCathedral%20of%20Zagreb!5e0!3m2!1sen!2suy!4v1614704668458!5m2!1sen!2suy",
"https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d6709.917127499258!2d-78.51409209928569!3d0.3576385746900253!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x8e2a5da2881494ab%3A0xae89047fc027c897!2sapuela%20imbabura%20intac!5e0!3m2!1sen!2suy!4v1614704741586!5m2!1sen!2suy"
];
var myIframe = document.getElementById('myIframe');
var prevButton = document.getElementById('prevBtn');
var nextButton = document.getElementById('nextBtn');
var i = Math.floor(Math.random() * mapsArray.length);
function update() {
myIframe.src = mapsArray[i];
if ( i == mapsArray.length - 1 ) {
prevButton.disabled = false;
nextButton.disabled = true;
}
else if ( i == 0 ) {
prevButton.disabled = true;
nextButton.disabled = false;
}
else {
prevButton.disabled = false;
nextButton.disabled = false;
}
}
function nextBtn() {
if ( i < mapsArray.length - 1 ) {
i++;
}
update();
}
function prevBtn() {
if (i > 0) {
i--;
}
update();
}
update();
.maps{
display: flex;
justify-content: center;
align-items: center;
}
#myIframe {
width: 600px;
height: 600px;
}
<div class ="maps">
<iframe id='myIframe' class="maps-gallery active"></iframe>
</div>
<div class="btns">
<button id="prevBtn" onclick="prevBtn()" class="btn prev">Prev</button>
<button id="nextBtn" onclick="nextBtn()" class= "btn next" >Next</button>
</div>
Here is a minimalist solution to your problem. The short style probably is not everybody's but it shows how little you need to write to actually reproduce the logic.
The core of the random sequencing of array elements is the shuffling of the array according to Fisher-Yates. After that I simply step through the shuffled array and enable/disable the buttons accordingly.
function shuffle(a,n){ // shuffle array a in place (Fisher-Yates)
let m=a.length;
n=n||m-1;
for(let i=0,j;i<n;i++){
j=Math.floor(Math.random()*(m-i)+i);
if (j-i) [ a[i],a[j] ] = [ a[j],a[i] ]; // swap 2 array elements
}; return a
}
const mapsArray = shuffle([
"https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d209569.44700750793!2d-56.380275318336025!3d-34.84309361411796!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x959f802b6753b221%3A0x3257eb39860f05a6!2sPalacio%20Salvo!5e0!3m2!1sen!2suy!4v1614269355326!5m2!1sen!2suy",
"https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d92110.09563909167!2d17.958933187703266!3d59.32686333113927!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x465f763119640bcb%3A0xa80d27d3679d7766!2sStockholm%2C%20Sweden!5e0!3m2!1sen!2suy!4v1614704350417!5m2!1sen!2suy",
"https://www.google.com/maps/embed?pb=!1m14!1m8!1m3!1d88989.45462143555!2d15.9390973!3d45.8128514!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x4765d701f8ef1d1d%3A0x312b512f1e7f6df9!2sCathedral%20of%20Zagreb!5e0!3m2!1sen!2suy!4v1614704668458!5m2!1sen!2suy",
"https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d6709.917127499258!2d-78.51409209928569!3d0.3576385746900253!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x8e2a5da2881 494ab%3A0xae89047fc027c897!2sapuela%20imbabura%20intac!5e0!3m2!1sen!2suy!4v1614704741586!5m2!1sen!2suy"]);
btns=document.querySelectorAll("button"), trgt=document.getElementById('myIframe');
trgt.src=mapsArray[0];
(i=>{
let n=mapsArray.length;
btns.forEach((b,k)=>b.onclick=()=>{
trgt.src=mapsArray[i=i+2*k-1];
btns[0].disabled=!i; btns[1].disabled=(i+1===n);
})
})(1); btns[0].click();
.maps {
display: flex;
justify-content: center;
align-items: center;
}
#myIframe {
width: 600px;
height: 600px;
}
<iframe id='myIframe' class="maps-gallery active"></iframe><br>
<button>Prev</button>
<button>Next</button>
The main function is embedded in an IIFE that encapsulates the current position index i and sets it to 0 as the starting value. The only "visible" global elements are the function shuffle() and the array mapsArray itself. For the actual stepping I apply a little trick: while in the .forEach() loop I use the index k to determine whether next(=1) or previous(=0) was clicked and then I calculate the increment accordingly.

Carousel that automatically changes image [JS]

I'm trying to make a carousel that after 3 seconds changes image.
I got 3 images as slide1, slide2, slide3
and thanks to the methods change1,change2,change3 changes image.
I would like to automate everything like this:
function time(change1, change2, change3) {
this.change1 = change1;
this.change2 = change2;
this.change3 = change3;
t = setInterval(change1 && change2 && change3, 3000); //obviously it doesn't work.
}
/*
---------------ANOTHER METHOD-----------------
*/
function time() {
t = setInterval(check, 3000);
}
function check() {
if (slide1.style.display = "inline-block") {
change2();
} else if (slide2.style.display = "inline-block") {
change3();
} else {
change1();
}
}
but i don't know how
Any ideas?
well that is an easy job, here is a simple example on how you could do it
I used jq but you will get the idee. if you want only js that let me know will do it to
/// use jq for batter effekt
var sliders = $(".container > div");
var current;
function change() {
if (!current)
current = sliders.first();
else {
current.hide("fast");
current = current.next();
}
if (current.length == 0)
current = sliders.first();
current.show();
}
setInterval(change, 2000);
.container {
display: flex;
border: 1px solid #CCC;
}
.container>div {
width: 100%;
min-height: 100px;
}
.container>div:not(:first-child){
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div style="background:red;"></div>
<div style="background:green"></div>
<div style="background:blue"></div>
</div>

Appending JS to the HTML

I am trying to append my variables 'showName' and 'showDescription' to the 'results' div object. I have tried to add them in using 'innerHTML' but I just get the description shown. I have tried making additional divs to put INSIDE the 'results' div but that didn't work either.
I want the 'showName' to appear above the 'showDescription in the div.
I am challenging myself to not use JQuery so that is not a viable option.
code:
document.querySelector('.search').addEventListener('keypress', function(e){//On button click of enter, get the value of the search bar and concatanate it to the end of the url
if(e.key==='Enter'){
var query = document.getElementById('main').value;
var url = fetch("http://api.tvmaze.com/search/shows?q="+query) //use fetch to get the data from the url, THEN convert it to json THEN console.log the data.
.then(response => response.json())
.then(data => {
console.log(data)
var domObject = document.createElement('div')
domObject.id="myDiv";
domObject.style.width="800px";
domObject.style.height="5000px";
domObject.style.display="flex";
domObject.style.flexDirection="column";
domObject.style.margin="auto";
domObject.style.borderRadius="30px";
domObject.style.background="";
document.body.appendChild(domObject);
for (var i = 0; i < data.length; i++) { //for all the items returned, loop through each one and show the name of the show and the dsescription of the show.
var showName = data[i].show.name;
//console.log(showName);
var showDescription = data[i].show.summary
//console.log(showDescription);
var results = document.createElement('div')
results.id="myResults";
results.style.width="600px"
results.style.height="400px";
results.style.background="white";
results.style.margin="auto";
results.style.borderRadius="30px";
results.style.fontFamily="Poppins"
results.style.display="flex";
results.style.flexDirection="column";
results.innerHTML=showName;
results.innerHTML=showDescription;
document.getElementById("myDiv").appendChild(results);
}
})
}
});
document.querySelector('.search').addEventListener('keydown', function(o){
if(o.key==='Backspace'){
location.reload();
}
});
result of searching in 'car'
results.innerHTML = showName;
results.innerHTML = showDescription;
With this you are overwriting showName with showDescription.
What you need to do is concatenate with +=.
Also, it will be much easier to replace this:
domObject.style.width = "800px";
domObject.style.height = "5000px";
domObject.style.display = "flex";
domObject.style.flexDirection = "column";
domObject.style.margin = "auto";
domObject.style.borderRadius = "30px";
domObject.style.background = "";
with domObject.classList.add('some-class');
and CSS will be:
.some-class {
width: 800px;
height: 500px;
// etc...
}
Moved your code to a working example.
Note: because of authors styles, it is only possible to run snippet in fullscreen. =)
const dosearch = () => {
var query = document.getElementById('main').value;
var url = fetch("https://api.tvmaze.com/search/shows?q=" + query)
.then(response => response.json())
.then(data => {
const myDiv = document.getElementById("myDiv");
myDiv.innerHTML = ''; // <---- this is for testing
for (var i = 0; i < data.length; i++) {
var showName = data[i].show.name;
var showDescription = data[i].show.summary
var results = document.createElement('div');
results.className = 'myResults';
var header = document.createElement('h2');
header.innerHTML = showName;
results.appendChild(header);
var desc = document.createElement('div');
desc.innerHTML = showDescription;
results.appendChild(desc);
myDiv.appendChild(results);
}
});
}
document.querySelector('.search').addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
dosearch();
}
});
#myDiv {
width: 800px;
height: 5000px;
display: flex;
flex-direction: column;
margin: auto;
border-radius: 30px;
background: black;
}
.myResults {
width: 600px;
height: 400px;
background: white;
margin: auto;
border-radius: 30px;
font-family: Poppins;
display: flex;
flex-direction: column;
}
.myResults p, .myResults h2 {
margin: 1em;
}
<input type="text" id="main" class="search" style="margin-bottom: 4px" value="Car" /><button onclick="dosearch()">Go</button>
<div id="myDiv"></div>

How to sort elements on DOM by its inner Text

I have a graph that is rendering its values as a div inside the body element with a class according to their number values. This is working fine. But next I need to sort the divs according to their number values or background color. BUT, it needs to start on the lower left corner of the page and fan out upwards to towards the right as the numbers increase. Basically just like a line graph.
I'd like to stay away from libraries if at all possible.
How would I approach this? Thank you all.
let interval = setInterval(makeDivs, 5);
function makeDivs(){
let cont = checkHeight();
if(cont){
let div = document.createElement('div');
let randNum = Math.random() * 100;
if(randNum < 20) { div.classList.add('blue') }
if(randNum >= 20 && randNum < 40) { div.classList.add('green') }
if(randNum >= 40 && randNum < 60) { div.classList.add('yellow') }
if(randNum >= 60 && randNum < 80) { div.classList.add('orange') }
if(randNum >= 80 && randNum < 101) { div.classList.add('red') }
div.textContent = randNum.toFixed(2);
document.querySelector('body').appendChild(div);
} else {
alert('done');
clearInterval(interval);
sortDivs(); // Begin sorting divs
}
}
function checkHeight(){
let w = window.innerHeight;
let b = document.querySelector('body').offsetHeight;
if(b < w) {
return true;
} else {
return false;
}
}
function sortDivs(){
document.querySelector("body div:last-child").remove();
alert('sorting now...')
}
* { box-sizing: border-box;}
body { width: 100vw; margin: 0; padding: 0; display: flex; flex-wrap: wrap; align-items: end;}
body div { width: calc(10% + 1px); text-align: center; border: 1px solid #ddd; margin: -1px 0 0 -1px; padding: 10px;}
body div.blue { background: aqua; }
body div.green { background: green; }
body div.yellow { background: yellow; }
body div.orange { background: orange; }
body div.red { background: red; }
UPDATE!!!
So I have this so far based on the feed back down below. The problem now is the sorting is only happening laterally and not on an angle (spreading right and to the top).
let interval = setInterval(makeDivs, 10);
function makeDivs(){
let cont = checkHeight();
if(cont){
let div = document.createElement('div');
let randNum = Math.random() * 100;
if(randNum < 20) { div.classList.add('blue') }
if(randNum >= 20 && randNum < 40) { div.classList.add('green') }
if(randNum >= 40 && randNum < 60) { div.classList.add('yellow') }
if(randNum >= 60 && randNum < 80) { div.classList.add('orange') }
if(randNum >= 80 && randNum < 101) { div.classList.add('red') }
div.textContent = randNum.toFixed(2);
document.querySelector('.outPut').appendChild(div);
} else {
clearInterval(interval);
document.querySelector(".outPut div:last-child").remove();
compileArrays(); // Begin sorting divs
}
}
function checkHeight(){
let w = window.innerHeight;
let b = document.querySelector('.outPut').offsetHeight;
if(b < w) {
return true;
} else {
return false;
}
}
function compileArrays(){
let divs = document.querySelectorAll('.outPut div');
let bArr = [], gArr = [], yArr = [], oArr = [], rArr = [];
divs.forEach( (d) => {
if( d.classList.contains('blue') ){ bArr.push(d) }
if( d.classList.contains('green') ){ gArr.push(d) }
if( d.classList.contains('yellow') ){ yArr.push(d) }
if( d.classList.contains('orange') ){ oArr.push(d) }
if( d.classList.contains('red') ){ rArr.push(d) }
});
let finalArr = sortArray(bArr).concat(sortArray(gArr)).concat(sortArray(yArr)).concat(sortArray(oArr)).concat(sortArray(rArr));
newDom(finalArr);
}
function sortArray(arr){
let newArr = arr;
newArr.sort( (a, b) => {
return a.innerText - b.innerText;
});
return newArr;
}
function newDom(arr){
let b = document.querySelector('.outPut');
b.innerHTML = '';
arr.reverse();
arr.forEach((a) => {
b.appendChild(a);
});
}
* { box-sizing: border-box;}
body { width: 100vw; height: 100vh; margin: 0; padding: 0; display: flex; align-items: flex-end;}
body .outPut { flex: 1; display: flex; flex-wrap: wrap; flex-direction:row-reverse; }
body .outPut div { width: calc(10% + 1px); text-align: center; border: 1px solid #ddd; margin: -1px 0 0 -1px; padding: 10px;}
body .outPut div.blue { background: aqua; }
body .outPut div.green { background: #44df15; }
body .outPut div.yellow { background: yellow; }
body .outPut div.orange { background: orange; }
body .outPut div.red { background: red; }
<div class="outPut"></div>
Supposed you already have a mechanism to organise such DIVs in a grid as shown, the following should give you what you are looking for:
var items = divList.filter((div) => div.nodeType == 1); // get rid of the whitespace text nodes
items.sort(function(a, b) {
return a.innerHTML == b.innerHTML
? 0
: (a.innerHTML > b.innerHTML ? 1 : -1);
});
Then, place them back in the DOM as needed, example:
for (i = 0; i < items.length; ++i) {
divList.appendChild(items[i]);
}
This worked with the first code example!!!
try this sortDivs function:
function sortDivs() {
document.querySelector("body div:last-child").remove();
alert('sorting now...')
let toSort = document.getElementsByTagName("div")
toSort = Array.prototype.slice.call(toSort, 0)
toSort.sort((a, b) => {
let aord = parseFloat(a.textContent);
let bord = parseFloat(b.textContent);
return bord - aord;
})
document.body.innerHTML = ""
for(var i = 0, l = toSort.length; i < l; i++) {
document.querySelector('body').appendChild(toSort[i]);
}
}
and in the css file set flex-wrap to wrap-reverse. Hope I could help :)
PS: please, implement some else if instead of doing only if
Here is a small fiddle with my sample code demonstrating a simple solution in pure JavaScript and absolute CSS positioning for what you are trying to achieve. Link
As some pointed out already, there might be a library, that already provides a better and complete solution for this - I did not research if it is so.
Code:
file.js
var container = document.getElementById("container")
var results = [1,2,3,4,5,6,7,8]
//you can pre-calculate the order of the distances
//here already orderdered array [distanec][X-axis][Y-axis]
var distances =[[0,0,0],
[1,1,0],
[1,0,1],
[1.414, 1,1],
[2,0,2],
[2,2,0],
[2.234, 2,1],
[2.234, 1,2]]
for (i = 0; i < results.length; i++){
var newDiv = document.createElement("div")
newDiv.className = "result"
newDiv.innerHTML = results[i]
newDiv.style.left = distances[i][1]*20 + "px"
newDiv.style.bottom = distances[i][2]*20 + "px"
container.appendChild(newDiv)
}
function setColor(element){
// set class based on value - you already have this part
}
style.css
#container {
border: 4px;
border-color: red;
border-style: solid;
height: 200px;
width: 200px;
position: relative;
}
.result{
border: 2px;
width: 20px;
height: 20px;
position: absolute;
border-color: blue;
border-style: solid;
text-align: center;
}
site.html
<div id="container">
</div>
Output:

Categories

Resources