Show the data and loader inside carousel - javascript

Before appending the loader to my page carousel works fine. But after adding loader to my page data not appending in the carousel. It appends after carousel. I want to show data inside carousel. I have tried but have not been able to figure out the problems. In this code, I am not fetching the data from the server but I have hard-coded data which is showing using local storage.
let movieData = JSON.parse(localStorage.getItem("movies"));
//console.log(movieData)
function sortLH() {
let data = JSON.parse(localStorage.getItem('movies'));
sort_data = data.sort(function(a, b) {
return a.rating - b.rating;
});
displayDOM(sort_data);
console.log(sort_data);
}
function sortHL() {
let data = JSON.parse(localStorage.getItem('movies'));
sort_data = data.sort(function(a, b) {
return b.rating - a.rating;
});
displayDOM(sort_data);
}
function displayDOM(data) {
let parent = document.querySelector('.carousel');
parent.innerHTML = null;
data.forEach(function(el) {
let container = document.createElement("div");
container.className = "carousel-cell";
let poster = document.createElement("img");
poster.src = el.poster;
let name = document.createElement("p");
name.innerText = `Movie: ${el.name}`;
let release = document.createElement("p");
release.innerText = `Year: ${el.release_Date}`;
let rating = document.createElement("p");
rating.innerText = `Rating: ${el.rating}`;
container.append(poster, name, release, rating)
parent.append(container);
});
}
////Loader/////
getme_dataPromise = new Promise(function(resolve, reject) {
setTimeout(function() {
let data = movieData;
if (data != null) {
resolve(data);
} else {
reject(`ERR: Server could not get your data`);
}
}, 5000);
});
//console.log(getme_dataPromise)
getme_dataPromise.then(function(res) {
displayDOM(res);
}).catch(function(err) {
console.log('err:', err);
});
* {
box-sizing: border-box;
}
div>img {
display: block;
margin: auto;
margin-left: 20%;
}
/* changes seen after refresh */
body {
font-family: sans-serif;
background: #0c111b;
}
.carousel {
/* background: #0c111b; */
width: 95%;
margin: auto;
margin-top: 49px;
padding: 8px 8px;
}
.carousel-cell {
width: 24%;
height: 500px;
margin-right: 80px;
margin-bottom: 40px;
/* border: 2px solid red; */
border-radius: 5px;
box-shadow: rgba(0, 0, 0, 0.25) 0px 54px 55px, rgba(0, 0, 0, 0.12) 0px -12px 30px, rgba(0, 0, 0, 0.12) 0px 4px 6px, rgba(0, 0, 0, 0.17) 0px 12px 13px, rgba(0, 0, 0, 0.09) 0px -3px 5px;
}
.flickity-page-dots {
display: none;
}
/* cell number */
.carousel-cell>img {
height: 80%;
width: 100%;
border-radius: 5px;
}
.carousel-cell>p {
color: #fff;
font-size: 0.8em;
text-align: center;
}
<link rel="stylesheet" href="./body-carousel.css">
<link rel="stylesheet" href="https://unpkg.com/flickity#2/dist/flickity.min.css">
<body>
<button onclick="sortLH()">Low to High</button>
<button onclick="sortHL()">High to low</button>
<div class="carousel" data-flickity='{ "cellAlign": "left", "contain": true }'>
<!-- gif image for loader -->
<img src="./uxplanet.gif" alt="gif">
</div>
</body>
<script src="./data.js"></script>
<script src="./body.js"></script>
<script src="https://unpkg.com/flickity#2/dist/flickity.pkgd.min.js"></script>

Why are you calling same function three times?
1.displayDOM(sort_data);inside SortLH()
2.displayDOM(res); inside .then
3.displayDOM(sort_data); inside SortHL().
i am calling the function that generates our html one time only that is inside my .then
I am just mimicking the data with an array of objects & checked cells are appended inside .carousel.
Update:Added Loading Animation Before Promise is Resolved or Timeout
Duration.
The svg will be generated(length of movieData)times.fore.g in this
case we have 2 movies so there are two loading circles.
I don't think there is any other issue. feel free to respond if you think otherwise
/*let svg = `<svg version="1.1" id="L9" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 100 100" enable-background="new 0 0 0 0" xml:space="preserve">
<path fill="#e72f2f" d="M73,50c0-12.7-10.3-23-23-23S27,37.3,27,50 M30.9,50c0-10.5,8.5-19.1,19.1-19.1S69.1,39.5,69.1,50">
<animateTransform
attributeName="transform"
attributeType="XML"
type="rotate"
dur="1s"
from="0 50 50"
to="360 50 50"
repeatCount="indefinite" />
</path>
</svg>`;*/
let movieData = [{
name: "CuttPutlli",
release_Date: "2022",
rating: "5.9/10 ImDb",
poster: "https://img1.hotstarext.com/image/upload/f_auto,t_web_vl_3x/sources/r1/cms/prod/6531/1326531-v-e6302c49fcd9"
},
{
name: "Thor:Love & Thunder",
release_Date: "2022",
rating: "6.5/10 ImDb",
poster: "https://img1.hotstarext.com/image/upload/f_auto,t_web_vl_3x/sources/r1/cms/prod/8317/1328317-v-56412010beba"
}
];
const getme_dataPromise = new Promise(function(resolve, reject) {
/*let parent = document.querySelector(".carousel");
let i = 0;
while (i < movieData.length) {
parent.innerHTML += svg;
i++
}*/
setTimeout(function() {
let data = movieData;
if (data != null) {
resolve(data);
} else {
reject(`ERR: Server could not get your data`);
}
}, 2000);
});
//console.log(getme_dataPromise)
getme_dataPromise
.then(function(res) {
displayDOM(res); //<--------------------Calling The DisplayDom Fuction.
})
.catch(function(err) {
console.log("err:", err);
});
function displayDOM(data) {
let parent = document.querySelector(".carousel");
/*parent.innerHTML = "";*/
data.forEach(function(el) {
let container = document.createElement("div");
container.className = "carousel-cell";
let poster = document.createElement("img");
poster.src = el.poster;
let name = document.createElement("p");
name.innerText = `Movie: ${el.name}`;
let release = document.createElement("p");
release.innerText = `Year: ${el.release_Date}`;
let rating = document.createElement("p");
rating.innerText = `Rating: ${el.rating}`;
container.append(poster, name, release, rating);
parent.append(container);
});
}
* {
box-sizing: border-box;
}
/* changes seen after refresh */
body {
font-family: sans-serif;
background: #0c111b;
}
.carousel {
/* background: #0c111b; */
width: 95%;
margin: auto;
margin-top: 49px;
padding: 8px 8px;
}
.carousel-cell {
width: min-content;
/*let it take the size of the image*/
/*height: 500ox; let it take the space it needs*/
margin-right: 80px;
margin-bottom: 40px;
/* border: 2px solid red; */
border-radius: 5px;
box-shadow: rgba(0, 0, 0, 0.25) 0px 54px 55px, rgba(0, 0, 0, 0.12) 0px -12px 30px, rgba(0, 0, 0, 0.12) 0px 4px 6px, rgba(0, 0, 0, 0.17) 0px 12px 13px, rgba(0, 0, 0, 0.09) 0px -3px 5px;
}
.flickity-page-dots {
display: none;
}
/* cell number */
.carousel-cell>img {
height: 60%;
/*width: 100%; change only one of height or width to maintaint the aspect ratio*/
border-radius: 5px;
}
.carousel-cell>p {
color: #fff;
font-size: 0.8em;
text-align: center;
}
svg {
width: 200px;
height: 200px;
margin-bottom: 100px;
display: block;
}
<link rel="stylesheet" href="https://unpkg.com/flickity#2/dist/flickity.min.css">
<div class="carousel" data-flickity='{ "cellAlign": "left", "contain": true }'></div>
<script src="https://unpkg.com/flickity#2/dist/flickity.pkgd.min.js"></script>

Related

<styleSCOPED> ruin my css in my Nuxt js app

My problem is quite simple and complicated at the same time, I forked this simple HTML, CSS, JS repo : Snake game.
and then I transformed it to a Nuxt Js app : My repo .
when I use the Scoped attribute in my style tag , the Js code works fine, but with no pissibility to see the snake :
When I remove the Scoped attribute, The snake goes crazy and ouf of borders, and it ruins the style either :
my code :
window.onload = function() {
// GAME_PIXEL_COUNT is the pixels on horizontal or vertical axis of the game board (SQUARE).
const GAME_PIXEL_COUNT = 40;
const SQUARE_OF_GAME_PIXEL_COUNT = Math.pow(GAME_PIXEL_COUNT, 2);
let totalFoodAte = 0;
let totalDistanceTravelled = 0;
/// THE GAME BOARD:
const gameContainer = document.getElementById("gameContainer");
const createGameBoardPixels = () => {
// Populate the [#gameContainer] div with small div's representing game pixels
for (let i = 1; i <= SQUARE_OF_GAME_PIXEL_COUNT; ++i) {
gameContainer.innerHTML = `${gameContainer.innerHTML} <div class="gameBoardPixel" id="pixel${i}"></div>`;
}
};
// This variable always holds the updated array of game pixels created by createGameBoardPixels() :
const gameBoardPixels = document.getElementsByClassName("gameBoardPixel");
/// THE FOOD:
let currentFoodPostion = 0;
const createFood = () => {
// Remove previous food;
gameBoardPixels[currentFoodPostion].classList.remove("food");
// Create new food
currentFoodPostion = Math.random();
currentFoodPostion = Math.floor(
currentFoodPostion * SQUARE_OF_GAME_PIXEL_COUNT
);
gameBoardPixels[currentFoodPostion].classList.add("food");
};
/// THE SNAKE:
// Direction codes (Keyboard key codes for arrow keys):
const LEFT_DIR = 37;
const UP_DIR = 38;
const RIGHT_DIR = 39;
const DOWN_DIR = 40;
// Set snake direction initially to right
let snakeCurrentDirection = RIGHT_DIR;
const changeDirection = (newDirectionCode) => {
// Change the direction of the snake
if (newDirectionCode == snakeCurrentDirection) return;
if (newDirectionCode == LEFT_DIR && snakeCurrentDirection != RIGHT_DIR) {
snakeCurrentDirection = newDirectionCode;
} else if (newDirectionCode == UP_DIR && snakeCurrentDirection != DOWN_DIR) {
snakeCurrentDirection = newDirectionCode;
} else if (
newDirectionCode == RIGHT_DIR &&
snakeCurrentDirection != LEFT_DIR
) {
snakeCurrentDirection = newDirectionCode;
} else if (newDirectionCode == DOWN_DIR && snakeCurrentDirection != UP_DIR) {
snakeCurrentDirection = newDirectionCode;
}
};
// Let the starting position of the snake be at the middle of game board
let currentSnakeHeadPosition = SQUARE_OF_GAME_PIXEL_COUNT / 2;
// Initial snake length
let snakeLength = 1000;
// Move snake continously by calling this function repeatedly :
const moveSnake = () => {
switch (snakeCurrentDirection) {
case LEFT_DIR:
--currentSnakeHeadPosition;
const isSnakeHeadAtLastGameBoardPixelTowardsLeft =
currentSnakeHeadPosition % GAME_PIXEL_COUNT == GAME_PIXEL_COUNT - 1 ||
currentSnakeHeadPosition < 0;
if (isSnakeHeadAtLastGameBoardPixelTowardsLeft) {
currentSnakeHeadPosition = currentSnakeHeadPosition + GAME_PIXEL_COUNT;
}
break;
case UP_DIR:
currentSnakeHeadPosition = currentSnakeHeadPosition - GAME_PIXEL_COUNT;
const isSnakeHeadAtLastGameBoardPixelTowardsUp =
currentSnakeHeadPosition < 0;
if (isSnakeHeadAtLastGameBoardPixelTowardsUp) {
currentSnakeHeadPosition =
currentSnakeHeadPosition + SQUARE_OF_GAME_PIXEL_COUNT;
}
break;
case RIGHT_DIR:
++currentSnakeHeadPosition;
const isSnakeHeadAtLastGameBoardPixelTowardsRight =
currentSnakeHeadPosition % GAME_PIXEL_COUNT == 0;
if (isSnakeHeadAtLastGameBoardPixelTowardsRight) {
currentSnakeHeadPosition = currentSnakeHeadPosition - GAME_PIXEL_COUNT;
}
break;
case DOWN_DIR:
currentSnakeHeadPosition = currentSnakeHeadPosition + GAME_PIXEL_COUNT;
const isSnakeHeadAtLastGameBoardPixelTowardsDown =
currentSnakeHeadPosition > SQUARE_OF_GAME_PIXEL_COUNT - 1;
if (isSnakeHeadAtLastGameBoardPixelTowardsDown) {
currentSnakeHeadPosition =
currentSnakeHeadPosition - SQUARE_OF_GAME_PIXEL_COUNT;
}
break;
default:
break;
}
let nextSnakeHeadPixel = gameBoardPixels[currentSnakeHeadPosition];
// Kill snake if it bites itself:
if (nextSnakeHeadPixel.classList.contains("snakeBodyPixel")) {
// Stop moving the snake
clearInterval(moveSnakeInterval);
if (!alert(
`You have ate ${totalFoodAte} food by travelling ${totalDistanceTravelled} blocks.`
))
window.location.reload();
}
nextSnakeHeadPixel.classList.add("snakeBodyPixel");
setTimeout(() => {
nextSnakeHeadPixel.classList.remove("snakeBodyPixel");
}, snakeLength);
// Update total distance travelled
totalDistanceTravelled++;
// Update in UI:
document.getElementById("blocksTravelled").innerHTML = totalDistanceTravelled;
if (currentSnakeHeadPosition == currentFoodPostion) {
// Update total food ate
totalFoodAte++;
// Update in UI:
document.getElementById("pointsEarned").innerHTML = totalFoodAte;
// Increase Snake length:
snakeLength = snakeLength + 100;
createFood();
}
};
/// CALL THE FOLLOWING FUNCTIONS TO RUN THE GAME:
// Create game board pixels:
createGameBoardPixels();
// Create initial food:
createFood();
// Move snake:
var moveSnakeInterval = setInterval(moveSnake, 80);
// Call change direction function on keyboard key-down event:
addEventListener("keydown", (e) => changeDirection(e.keyCode));
// ON SCREEN CONTROLLERS:
const leftButton = document.getElementById("leftButton");
const rightButton = document.getElementById("rightButton");
const upButton = document.getElementById("upButton");
const downButton = document.getElementById("downButton");
leftButton.onclick = () => changeDirection(LEFT_DIR);
rightButton.onclick = () => changeDirection(RIGHT_DIR);
upButton.onclick = () => changeDirection(UP_DIR);
downButton.onclick = () => changeDirection(DOWN_DIR);
}
<style scoped>
body {
background-color: darkslategrey;
text-align: center;
}
/* GAME BOARD STYLES */
#gameContainer {
/*
width and height of .gameBoardPixel should 1/40 of the width and height of #gameContainer,
because it is used in calculation in the jscript.js file
*/
width: 40vw;
height: 40vw;
margin: 2vw auto;
background-color: #0c1021;
border: solid 10px slategrey;
border-radius: 10px;
-webkit-box-shadow: 0px 0px 20px 3px rgba(0, 0, 0, 0.6);
-moz-box-shadow: 0px 0px 20px 3px rgba(0, 0, 0, 0.6);
box-shadow: 0px 0px 20px 3px rgba(0, 0, 0, 0.6);
}
.gameBoardPixel {
/* background-color: slategrey; */
/*
width and height of .gameBoardPixel should 1/40 of the width and height of #gameContainer,
because it is used in calculation in the jscript.js file
*/
width: 1vw;
height: 1vw;
border-radius: 10px;
float: left;
}
/* GAME BOARD STYLES END*/
/* SNAKE STYLES */
.snakeBodyPixel {
background-color: #fd6401;
box-shadow: 0 0 5px #fd6401;
}
/* SNAKE STYLES END*/
/* FOOD STYLES */
.food {
background-color: #68e768;
}
/* FOOD STYLES END*/
/* SCORE STYLES */
#scoreContainer {
width: 40vw;
display: flex;
margin: auto;
justify-content: space-around;
}
.scoreBoard {
border-radius: 10px;
border: solid 5px slategrey;
color: dimgray;
background-color: #0c1021;
display: inline-block;
padding: 1vw;
width: 40%;
-webkit-box-shadow: 0px 0px 20px 3px rgba(0, 0, 0, 0.6);
-moz-box-shadow: 0px 0px 20px 3px rgba(0, 0, 0, 0.6);
box-shadow: 0px 0px 20px 3px rgba(0, 0, 0, 0.6);
}
/* SCORE STYLES END */
/* Hide #onScreenControllers on desktop */
#onScreenControllers {
display: none;
}
.developerDetails {
margin-top: 2vw;
display: flex;
flex-direction: column;
color: #0c1021;
font-family: monospace;
}
.developerDetails a {
color: #0c1021;
}
#media only screen and (max-width: 768px) {
/* MOBILE */
#gameContainer {
width: 80vw;
height: 80vw;
}
.gameBoardPixel {
width: 2vw;
height: 2vw;
}
#scoreContainer {
width: 80vw;
}
#onScreenControllers {
width: 80vw;
margin: 5vw auto;
display: flex;
justify-content: space-evenly;
align-items: center;
}
#onScreenControllers>div {
display: flex;
flex-direction: column;
}
#onScreenControllers button {
background-color: transparent;
height: 20vw;
width: 20vw;
font-size: 10vw;
border: none;
}
#onScreenControllers button:focus {
outline: none;
}
#onScreenControllers button:active {
background-color: slategray;
}
}
</style>
<template>
<body>
<div>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Snake v8</title>
<!-- #gameContainer is the main game board-->
<div id="gameContainer"></div>
<!-- #scoreContainer contains the scores -->
<div id="scoreContainer">
<div class="scoreBoard">Food: <span id="pointsEarned">0</span></div>
<div class="scoreBoard">Blocks: <span id="blocksTravelled">0</span></div>
</div>
<!-- #onScreenControllers contains the navigation buttons for mobile screens -->
<div id="onScreenControllers">
<button id="leftButton">◀️</button>
<div>
<button id="upButton">🔼</button>
<button id="downButton">🔽</button>
</div>
<button id="rightButton">▶️</button>
</div>
</div>
</body>
</template>
Any help please ? thank you
I actually found where the problem is :
in my Nuxt.js app, im using Tailwind, and it applies a default style to all my <div> tags .
the solution was to add this to my global CSS :
*
{
box-sizing: initial;
}

First click is not working in javascript for manipulating DOM elements

I am working on one JavaScript project, where I need to toggle between Dark and Light mode.
The HTML is here.
var btnToggle = document.getElementById("btn-toggle")
var btnToggleIcon = document.getElementById("btn-toggle-icon")
var isDark = true;
btnToggleIcon.addEventListener("click", () => {
if (isDark) {
console.log(btnToggle.style)
btnToggle.style.justifyContent = "flex-start";
isDark = false;
document.documentElement.style.setProperty('--color1', '#10111f');
document.documentElement.style.setProperty('--bg1', 'linear-gradient(145deg, #111221, #0e0f1c)');
document.documentElement.style.setProperty('--color5', '#f1f1f3');
document.documentElement.style.setProperty('--bs', '9px 9px 23px #0f111a, -9px -9px 20px #1a1b32');
document.getElementById("toggle-img").src = "https://img.icons8.com/ios/2x/moon-man.png"
} else {
console.log(btnToggle.style)
btnToggle.style.justifyContent = "flex-end";
isDark = true;
document.documentElement.style.setProperty('--color1', '#f1f1f3');
document.documentElement.style.setProperty('--bg1', '#f1f1f3');
document.documentElement.style.setProperty('--color5', '#10111f');
document.documentElement.style.setProperty('--bs', '20px 20px 60px #bebebe,20px 20px 60px #ffffff');
document.getElementById("toggle-img").src = "https://img.icons8.com/fluent-systems-regular/2x/sun.png"
}
})
:root {
--color1: #10111f;
--color2: #6c6c76;
--color3: #265385;
--color4: #6bc3ff;
--color5: #f1f1f3;
--bg1: linear-gradient(145deg, #111221, #0e0f1c);
--bs: 9px 9px 23px #0f111a, -9px -9px 23px #1a1b32;
}
.keyboard {
width: 80vw;
height: 52vh;
background-color: var(--color1);
position: absolute;
left: 10vw;
right: 10vw;
bottom: 5%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
padding: 10px;
}
.btn {
color: var(--color5);
font-size: 1.3rem;
cursor: pointer;
border-radius: 8px;
background: var(--bg1);
box-shadow: var(--bs);
padding: 1rem 1.8rem;
transition: all 0.2s ease;
}
<div class="btn-toggle" id="btn-toggle">
<div class="btn-toggle-icon" id="btn-toggle-icon">
<img id="toggle-img" src="https://img.icons8.com/ios/2x/moon-man.png" alt="" />
</div>
</div>
When I click first time on icon but nothing gets changed. But after first click on every click code's running perfectly well.
So please solve this error.
you misinterpret the state, your if(isDark) check the previous state.
i.e. if isDark == true then you should change icon to sun
var btnToggle = document.getElementById("btn-toggle")
var btnToggleIcon = document.getElementById("btn-toggle-icon")
var isDark = true;
btnToggleIcon.addEventListener("click", () => {
if (isDark) {
isDark = false;
//at this point it's not dark
document.getElementById("toggle-img").src = "https://img.icons8.com/fluent-systems-regular/2x/sun.png"
} else {
isDark = true;
//at this point it's dark
document.getElementById("toggle-img").src = "https://img.icons8.com/ios/2x/moon-man.png"
}
})
<div class="btn-toggle" id="btn-toggle">
<div class="btn-toggle-icon" id="btn-toggle-icon">
<img id="toggle-img" src="https://img.icons8.com/ios/2x/moon-man.png" alt="" />
</div>
</div>
Your logic is wrong.
You need to change the variable before the check.
btnToggleIcon.addEventListener("click", () => {
isDark = !isDark;
if (isDark) {
console.log(btnToggle.style)
btnToggle.style.justifyContent = "flex-start";
document.documentElement.style.setProperty('--color1', '#10111f');
document.documentElement.style.setProperty('--bg1', 'linear-gradient(145deg, #111221, #0e0f1c)');
document.documentElement.style.setProperty('--color5', '#f1f1f3');
document.documentElement.style.setProperty('--bs', '9px 9px 23px #0f111a, -9px -9px 20px #1a1b32');
document.getElementById("toggle-img").src = "https://img.icons8.com/ios/2x/moon-man.png"
} else {
console.log(btnToggle.style)
btnToggle.style.justifyContent = "flex-end";
document.documentElement.style.setProperty('--color1', '#f1f1f3');
document.documentElement.style.setProperty('--bg1', '#f1f1f3');
document.documentElement.style.setProperty('--color5', '#10111f');
document.documentElement.style.setProperty('--bs', '20px 20px 60px #bebebe,20px 20px 60px #ffffff');
document.getElementById("toggle-img").src = "https://img.icons8.com/fluent-systems-regular/2x/sun.png"
}
})

How to reload a page only once is javascript

The code detects a click outside an element and reloads the page. However, anytime a user clicks outside the page it keeps on reloading the page. How can I reload the page once when the user clicks outside the element?
The reason I want to do this is so when a user inputs text into a form and clicks away the other forms can be rendered with the updated contents. It wouldn't be ideal for the user to click outside the element and the page constantly reloading.
document.addEventListener("click", (evt) => {
const flyoutElement = document.getElementById("flyout-example");
let targetElement = evt.target; // clicked element
do {
if (targetElement == flyoutElement) {
// This is a click inside. Do nothing, just return.
document.getElementById("flyout-debug").textContent = "Clicked inside!";
return;
}
// Go up the DOM
targetElement = targetElement.parentNode;
} while (targetElement);
// This is a click outside.
document.getElementById("flyout-debug").textContent = "Clicked outside!";
location.reload();
});
body {
font-family: "Arial", sans-serif;
}
h6 {
margin: 0;
font-size: .85rem;
font-weight: normal;
color: #999;
}
.flyout {
position: absolute;
top: 50px;
left: 50px;
padding: 1em;
border: 1px solid rgba(16, 152, 173, .3);
background: white;
box-shadow: 0 .1rem .2rem rgba(0, 0, 0, .15);
}
.flyout-title {
font-size: 1em;
margin: 0 0 .5em 0;
}
.flyout-debug {
min-height: 1.5em;
margin: 0 0 .5em 0;
font-size: .8em;
color: #999;
}
.flyout-buttons {
text-align: center;
}
.button {
display: inline-block;
box-sizing: border-box;
margin: 0 .25em;
padding: .5em 1em;
border: .075rem solid rgba(0, 0, 0, .1);
border-radius: .15em;
background-color: #1098ad;
background-image: linear-gradient(rgba(255, 255, 255, .2), rgba(255, 255, 255, 0));
color: white;
text-decoration: none;
font-family: inherit;
font-size: inherit;
line-height: 1;
box-shadow:
0 .075rem .1rem rgba(0, 0, 0, .15),
inset 0 .075rem rgba(255, 255, 255, .3);
}
.button:hover,
.button:focus {
border-color: rgba(0, 0, 0, .5);
background-image: linear-gradient(rgba(255, 255, 255, .1), rgba(0, 0, 0, .1));
}
.button:active {
background-image: linear-gradient(rgba(0, 0, 0, .1), rgba(0, 0, 0, 0));
box-shadow:
inset 0 .075rem .1rem rgba(0, 0, 0, .2);
}
.button-outline {
background-color: transparent;
background-image: none;
border-color: #1098ad;
color: #1098ad;
box-shadow: none;
}
.button-outline:hover,
.button-outline:focus {
background-color: #1098ad;
background-image: none;
color: white;
}
<div class="flyout" id="flyout-example">
<h5 class="flyout-title">This could be a flyout…</h5>
<div class="flyout-debug" id="flyout-debug"></div>
<div class="flyout-buttons">
<button class="button button-outline" type="button">Cancel</button>
<button class="button" type="button">Ok</button>
</div>
</div>
You can use session storage & add a key to maintain if the page was reloaded before.If the key exist in session storage,it mean it was loaded before. If not then add a key a reload it
document.addEventListener("click", (evt) => {
const flyoutElement = document.getElementById("flyout-example");
let targetElement = evt.target; // clicked element
do {
if (targetElement == flyoutElement) {
// This is a click inside. Do nothing, just return.
document.getElementById("flyout-debug").textContent = "Clicked inside!";
return;
}
// Go up the DOM
targetElement = targetElement.parentNode;
} while (targetElement);
// This is a click outside.
yee = document.getElementById("flyout-debug").textContent = "Clicked outside!";
const getIsFirstClick = sessionStorage.getItem('firstClick'); // change from here
if (!getIsFirstClick) {
sessionStorage.setItem('firstClick', true)
location.reload()
}
});
I'm not sure exactly what you're trying to do, but what I understood is that when you click within an area you don't want to reload, but if you click any outside, reload should happen, correct me if I'm wrong. Here's a script to do it:
document.addEventListener("click", (evt) => {
const flyoutElement = "flyout-example";
const targetElement = evt.target; // clicked element
if (targetElement.id === flyoutElement) {
// This is a click inside. Do nothing, just return.
document.getElementById(flyoutElement).textContent = "Clicked inside!";
} else {
// This is a click outside.
document.getElementById(flyoutElement).textContent = "Clicked outside!";
const isReloaded = localStorage.getItem('reloaded');
if (!isReloaded) {
localStorage.setItem('reloaded', true);
location.reload();
}
}
});

.Width() & .clientWidth get same bad info

I'm trying to Gsap a Horizontal scrolling text, but when I want to receive the width of the div element for check it's width (depending on a dynamic .txt file) It returns me a wrong width.
Sometimes when I refresh the page (brackets) it gives me the good width but when I refresh again always become wrong again!
Only when I let the page refresh without looking active window, and check it after a sec from being auto-refreshed it bring the exact value.
Code:
<!DOCTYPE html>
<html>
<head>
<style>
#font-face {
font-family: aclonica;
src: url(./fonts/Aclonica-Regular.ttf);
}
div {
display: inline-block;
position: relative;
font-family: aclonica;
}
div.hijos{
white-space: nowrap;
display: inline-block;
text-align: right;
vertical-align: bottom;
background-color: lightblue;
left: 160px;
width: 300px;
height: 50px;
overflow: hidden;
}
div.Titulos {
display: block;
left: 160px;
width: 300px;
height: 25px;
}
.nombres {
padding-top: 2px;
}
.dinero {
padding-top: 2px;
color: #53a9ea;
}
.Titulos{
margin-top: 2px;
margin-bottom: 2px;
text-align: right;
vertical-align: middle;
color: #53a9ea;
font-family: aclonica;
font-size: 24px;
text-shadow: 0px 0px 3px rgba(0, 0, 0, 1),1px 1px 5px rgba(0, 0, 0, 1), 0px 0px 4px rgba(0, 0, 0, 1), 0px 0px 4px rgba(0, 0, 0, 0.5);
}
.hijos{
display: block;
text-align: right;
color: #ffffff;
font-family: aclonica;
font-size: 22px;
text-shadow: 0px 0px 3px rgba(0, 0, 0, 1),1px 1px 5px rgba(0, 0, 0, 1), 0px 0px 4px rgba(0, 0, 0, 1), 0px 0px 4px rgba(0, 0, 0, 0.5);
}
.info{
padding-top: 2px;
}
span {
line-height: 100%;
display: inline-block;
}
#Top1{
display: block;
white-space: nowrap;
position: relative;
background-color:blue;
}
.NoWrap {
white-space: normal;
}
#Tinfo{
padding-left: 5px;
padding-right: 25px;
}
#Tinfo2{
padding-left: 5px;
padding-right: 25px;
}
#Sline{
line-height: 200%;
}
.Inline{
display: inline-block;
vertical-align:top;
}
#Inside1{
position: relative;
display:inline-block;
background-color: chocolate;
}
#Inside2{
position: relative;
display:inline-block;
background-color:chartreuse;
}
#TDonator{
display: block;
}
</style>
<script src="js/jquery.js"></script>
<script src="js/TimelineLite.min.js"></script>
<script src="js/TimelineMax.min.js"></script>
<script src="js/TweenMax.min.js"></script>
<script type="text/JavaScript">
setTimeout("location.href = 'TwitchAlerts.html';",30000);
</script>
</head>
<body bgcolor="#E6E6FA">
<div id="5Don" class="Titulos" >Last 5 Donators</div>
<div id="Donators" class="hijos"></div>
<div id="LastF" class="Titulos" >Last Follow</div>
<div id="Follower" class="hijos" class="NoWrap"></div>
<div id="TopDonator" class="Titulos" >Top Donator</div>
<div id="TDonator" class="hijos"></div>
<div id="salida1" ><h1></h1></div>
<div id="salida2" >holaaaaa</div>
<div id="salida3" ></div>
<script>
function hola(){
$("#Follower").load("../StreamLabs/most_recent_follower.txt");
$("#Donators").load("../StreamLabs/session_donators.txt");
$("#TDonator").load("../StreamLabs/all_time_top_donator.txt");
}
hola();
function animation(){
//var width1 = $Inside1.width();
var tl = new TimelineMax();
tl.staggerFrom(".Titulos", 0.5, {left:400, autoAlphalpha:0, ease: Back.easeOut.config(1.7)},0.25);
//.from("#Inside1", 5, {left:500, autoAlphalpha:0, ease: Linear.easeNone},0.25);
var $hold = $("#Inside1");
var $holdclone = $("#Inside2");
var listWidth = $("#Inside1").width();
//var listWidth = 253.36; //Real Value//
//listWidth = document.getElementById("Inside1").offsetWidth;;
document.getElementById("salida1").innerHTML = listWidth;
var salida2 = document.getElementById("Tname").offsetWidth;
//var salida2 = " uno "
document.getElementById("salida2").innerHTML = "hola a todos si "+salida2;
var infinite = new TimelineMax({repeat: -1, paused: false});
var time = 10;
infinite.fromTo($hold, time, {left:0}, {left: -listWidth, ease: Linear.easeNone}, 1);
infinite.fromTo($holdclone, time, {left:0}, {left:-listWidth, ease: Linear.easeNone}, 1);
infinite.fromTo($hold, time, {left:0}, {left: -250, ease: Linear.easeNone}, 11);
infinite.fromTo($holdclone, time, {left:0}, {left: -250, ease: Linear.easeNone}, 11);
//infinite.set($hold, {left: 50});
//infinite.to($holdclone, time, {left: -listWidth, ease: Linear.easeNone}, time);
//infinite.to($hold, time, {left: 0, ease: Linear.easeNone}, time);
}
$(document).ready(function(){
var str = document.getElementById("Donators").innerHTML;
var res = str.split(" ");
document.getElementById("Donators").innerHTML ="";
for (i = 1; i < res.length; i+=2) {
document.getElementById("Donators").innerHTML += '<span class="nombres">'+res[i-1] +'</span>';
document.getElementById("Donators").innerHTML += ' <span class="dinero">'+res[i] +' </span> ';
}
var str2 = document.getElementById("TDonator").innerHTML;
var res2 = str2.split(" ");
document.getElementById("TDonator").innerHTML ="";
document.getElementById("TDonator").innerHTML += '<div id="Top1"><div id="Inside1" ><div class="info2 nombres" id="Tname" >'+res2[0] +' </div><div class="info2 dinero" id="Tinfo">'+res2[1] +'</div></div></div>';
$('<div id="Inside2"><div class="info2 nombres" id="Tname2" >'+"hola" +' </div><div class="info2 dinero" id="Tinfo2"> '+"res2[1]" +'</div></div>').insertAfter("#Inside1");
var str3 = document.getElementById("Follower").innerHTML;
document.getElementById("Follower").innerHTML = '<span class="info" id="Fline">'+str3 +' </span><br><span class="info" id="Sline">'+str3+'</span>';
animation();
});
</script>

Why doesn't CSS transition get applied?

I've built a small stacked bar visual just using floated divs that underneath is bound to some data using knockout. What I want to be able to do is to animate changes in the size of these stacks when the data changes.
I've managed to do this in the general case, so of the 4 bars that I've got, 3 of them transition correctly. The problem is my final bar seems to ignore the transition and instantly re-sizes and I can't understand why. Here's a picture of the before/during/after states:
The way that I've defined this transition is simply via css
-webkit-transition: width 1s;
transition: width 1s;
The width of the bars is a computed value, calculating the percentage of items, so each bar should have it's width defined as a percentage. Although the red bar is calculated differently to the other 3 bars, I don't see why that should affect the transition.
What I find quite strange, is that if I modify the width through the developer console for example, then the bar does correctly animate. I'm wondering if anyone can suggest why this might be the case?
var vm = (function generateModel() {
var data = {
name: "Sign-off",
id: "XX",
values: [{ text: "Signed-off", count: 150, color: "#5fb5cc" },
{ text: "Submitted", count: 90, color: "#75d181" },
{ text: "Not Submitted", count: 75, color: "#f8a25b" }
],
aggregates: {
count: 650
}
};
// Create a view model directly from the data which we will update
var vm = ko.mapping.fromJS(data);
// Add a computed value to calculate percentage
vm.values().forEach(function (d) {
d.percentage = ko.computed(function () {
return d.count() / vm.aggregates.count() * 100;
});
});
// Create a
vm.allValues = ko.computed(function() {
var values = [];
var count = 0;
var total = vm.aggregates.count();
debugger;
// Add each of these results into those that will be returned
vm.values().forEach(function(d) {
values.push(d);
count += d.count();
});
// Create an other category for everything else
values.push({
text: ko.observable("Other"),
count: ko.observable(total - count),
percentage: ko.observable((total - count) / total * 100),
color: ko.observable("#ff0000")
});
return values;
});
return vm;
})();
ko.applyBindings(vm);
setTimeout(function() {
vm.values()[0].count(90);
vm.values()[1].count(40);
vm.values()[2].count(35);
vm.aggregates.count(3550);
}, 3000);
body {
background: rgb(40, 40, 40);
}
.spacer {
height: 230px;
}
.cards {
float: right;
}
/* Small Card */
.card {
margin-bottom: 3px;
background: white;
border-radius: 3px;
width:398px;
float: right;
clear: both;
min-height: 100px;
padding: 10px 5px 15px 5px;
font-family:'Open Sans', Arial, sans-serif;
}
.title {
color: rgb(105, 161, 36);
font-size: 16px;
}
.states {
padding-top: 10px;
}
.state {
font-size: 12px;
color: rgb(67, 88, 98);
padding: 0px 5px 2px 5px;
clear: both;
}
.circle {
width: 10px;
height: 10px;
border-radius: 50%;
float: left;
margin: 1px 5px 5px 0px;
}
.value {
float: right;
}
.graph {
padding: 10px 5px 0px 5px;
}
.bar {
float: left;
height: 10px;
-webkit-transition: width 10s;
transition: width 10s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script>
<div class="card">
<div class="content">
<div class="graph" data-bind="foreach: allValues">
<div class="bar" data-bind="style: { background: color, width: percentage() + '%' }"/>
</div>
</div>
</div>
As the first 3 are based on object references that don't change, knockout is preserving the actual <div> that's been rendered.
For the final bar, each time allValues is evaluated, it's pushing a brand new object into the returned array. I would assume that since knockout sees that as a new object, it re-renders the div from scratch, rather than updating existing bindings.
You'll need to rework your model slightly to hold an actual object for that final value so that you can then update the observables on it in the same way.
Here's a fixed version using a static object for the "other" value:
var vm = (function generateModel() {
var data = {
name: "Sign-off",
id: "XX",
values: [{ text: "Signed-off", count: 150, color: "#5fb5cc" },
{ text: "Submitted", count: 90, color: "#75d181" },
{ text: "Not Submitted", count: 75, color: "#f8a25b" }
],
aggregates: {
count: 650
}
};
// Create a view model directly from the data which we will update
var vm = ko.mapping.fromJS(data);
// Add a computed value to calculate percentage
vm.values().forEach(function (d) {
d.percentage = ko.computed(function () {
return d.count() / vm.aggregates.count() * 100;
});
});
//Create a static "others" object
vm.other = {
text: ko.observable("Other"),
count: ko.computed(function() {
var total = vm.aggregates.count();
var count = 0;
vm.values().forEach(function(d) { count += d.count(); });
return total - count;
}),
percentage: ko.computed(function(d, b) {
var total = vm.aggregates.count();
var count = 0;
vm.values().forEach(function(d) { count += d.count(); });
return (total - count) / total * 100;
}),
color: ko.observable("#ff0000")
};
// Create a
vm.allValues = ko.computed(function() {
var values = [];
var count = 0;
var total = vm.aggregates.count();
debugger;
// Add each of these results into those that will be returned
vm.values().forEach(function(d) {
values.push(d);
count += d.count();
});
// and push static object in instead of creating a new one
values.push(vm.other);
return values;
});
return vm;
})();
ko.applyBindings(vm);
setTimeout(function() {
vm.values()[0].count(90);
vm.values()[1].count(40);
vm.values()[2].count(35);
vm.aggregates.count(3550);
}, 3000);
body {
background: rgb(40, 40, 40);
}
.spacer {
height: 230px;
}
.cards {
float: right;
}
/* Small Card */
.card {
margin-bottom: 3px;
background: white;
border-radius: 3px;
width:398px;
float: right;
clear: both;
min-height: 100px;
padding: 10px 5px 15px 5px;
font-family:'Open Sans', Arial, sans-serif;
}
.title {
color: rgb(105, 161, 36);
font-size: 16px;
}
.states {
padding-top: 10px;
}
.state {
font-size: 12px;
color: rgb(67, 88, 98);
padding: 0px 5px 2px 5px;
clear: both;
}
.circle {
width: 10px;
height: 10px;
border-radius: 50%;
float: left;
margin: 1px 5px 5px 0px;
}
.value {
float: right;
}
.graph {
padding: 10px 5px 0px 5px;
}
.bar {
float: left;
height: 10px;
-webkit-transition: width 10s;
transition: width 10s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script>
<div class="card">
<div class="content">
<div class="graph" data-bind="foreach: allValues">
<div class="bar" data-bind="style: { background: color, width: percentage() + '%' }"/>
</div>
</div>
</div>

Categories