CSS transition doesn't work - javascript

My sidebar.css :
body
{
margin: 0;
padding: 0;
}
#header
{
background-color: #577481;
float: left;
height: 50px;
width: 100%;
}
#sidebar
{
background-color: #4ea9d1;
float: left;
height: 100%;
left: -200px;
position: absolute;
top: 50px;
width: 200px;
}
#wrapper
{
float: left;
height: 100%;
width: 100%;
}
#content
{
background-color: #d6b141;
float: left;
height: 500px;
width: 100%;
}
#sideBarButton
{
background-image: url('SideBarButton.png');
background-position: center;
background-repeat: no-repeat;
background-size: 70% 70%;
border-radius: 25px;
height: 50px;
margin-left: 30px;
width: 50px;
}
My index.html:
<<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="sidebar.css">
<script>
function slideIn(element1, element2, element3) {
var elem = document.getElementById(element1);
var elem2 = document.getElementById(element2);
var elem3 = document.getElementById(element3);
elem.style.transition = "left 0.5s ease-in 0s";
elem.style.left = "0px";
elem2.style.transition = "marginLeft 0.5s ease-in 0s";
elem2.style.marginLeft = "200px";
elem2.style.opacity = 0.75;
elem3.style.backgroundImage = 'url(SideBarButtonHover.png)';
elem3.style.backgroundColor = '#3f545d';
}
function slideOut(element1, element2, element3) {
var elem = document.getElementById(element1);
var elem2 = document.getElementById(element2);
var elem3 = document.getElementById(element3);
elem.style.transition = "left 0.5s ease-out 0s";
elem.style.left = "-200px";
elem2.style.transition = "marginLeft 0.5s ease-out 0s";
elem2.style.marginLeft = "0px";
elem2.style.opacity = 1;
elem3.style.backgroundImage = 'url(SideBarButton.png)';
elem3.style.backgroundColor = '#577481';
}
</script>
</head>
<body>
<div id="header">
<div id="sideBarButton" onMouseOver="slideIn('sidebar', 'content', 'sideBarButton');" onMouseOut="slideOut('sidebar', 'content', 'sideBarButton');"></div>
</div>
<div id="wrapper">
<div id="sidebar">
<ul>
<li>Hallo
</li>
</ul>
</div>
<div id="content">Ich bin der Content</div>
</div>
</body>
</html>
The transition with the first element(sidebar) works but not with the second one(content). It should work like this when you hover over the sidebarbutton, the sidebar will come out and the content will move at the same time to the right. My question is why doesn't the content transition work? Thanks for your help guys!
The transition with the first element(sidebar) works but not with the second one(content).
It should work like this when you hover over the sidebarbutton, the sidebar will come out and the content will move at the same time to the right. My question is why doesn't the content transition work?
Thanks for your help guys!

When setting a style value in javascript your style name should be camelCase'd, but if setting a value with a CSS property within it you should use the CSS property syntax. Correctly being:
elem2.style.transition = "margin-left 0.5s ease-in 0s";
elem2.style.marginLeft = "200px";

Related

transition doesn't work editing while window onload

I'm trying to move this square to right 100px after clicking on it with js, I've set the transition to 1s, but it doesn't work
window.onload = function(){
var square = document.querySelector(".square");
square.onclick = function(){
square.style.right = "100px";
};
};
.square {
position: absolute;
background-color: red;
width: 500px;
height: 500px;
transition: 1s;
}
<div class="square">
</div>
CSS won't animate things from auto to px.
Since right is not defined, it's defaulting to auto.
window.onload = function(){
var square = document.querySelector(".square");
square.onclick = function(){
square.style.right = "100px";
};
};
.square {
position: absolute;
background-color: red;
width: 500px;
height: 500px;
right: 0;
transition: 1s;
}
<div class="square">
</div>
However, if you want to animate it without setting right at the beginning, you can also use translate.
window.onload = function(){
var square = document.querySelector(".square");
square.onclick = function(){
square.style.transform = "translateX(100px)";
};
};
.square {
position: absolute;
background-color: red;
width: 500px;
height: 500px;
transition: 1s;
}
<div class="square">
</div>

Several elements use the same css class, how can I change the css properties of only one of those elements

I am creating a little game that should be like a 2d version of "guitar hero" (if you don't know what "guitar hero" is don't worry, it was just to give context). I have a red square creator function called squareCreator that adds each new square created a CSS class of .newMostLeftNote. Afterward, I want each one of those squares to fall down (like gravity) using the function fallingMostLeftNote. The problem is that the margin-top that function adds to the square generated by the squareCreator adds to every single square at the same time (even before the square is created), so a square could be created when the .newMostLeftNote CSS class has a margin-top of 700 and it appears way at the bottom.
How can I make it so that every square that falls, but starts falling after they appear?
Notice that in this image, every margin-top CSS property for every new generated square is exactly the same.
var mostLeftNoteMarginTop = 0;
function squareCreator(){
var newNote = document.createElement("div");
newNote.className = "newMostLeftNote";
document.body.appendChild(newNote);
}
var generationSpeed = setInterval(squareCreator, 300);
function fallingMostLeftNote() {
mostLeftNoteMarginTop += 2;
$(".newMostLeftNote").css({
'margin-top': mostLeftNoteMarginTop + 'px'
});
}
proc = setInterval(fallingMostLeftNote, 5);
.newMostLeftNote {
height: 100px;
width: 100px;
background-color: red;
margin-left: 400px;
position: absolute;
}
.mostLeftNote {
height: 100px;
width: 100px;
background-color: red;
margin-left: 300px;
position: absolute;
}
.middleNote {
height: 100px;
width: 100px;
background-color: blue;
margin-left: 600px;
position: absolute;
}
.mostRightNote {
height: 100px;
width: 100px;
background-color: green;
margin-left: 900px;
position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<h1>Score: 0</h1>
<div class="middleNote"></div>
<div class="mostLeftNote"></div>
<div class="mostRightNote"></div>
<div class="scoreLineTop"></div>
<div class="scoreLineButtom"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="main.js" charset="utf-8"></script>
</body>
Update
var squareQuantity = [];
function squareCreator(){
var newNote = document.createElement("div");
newNote.className = "newMostLeftNote";
document.body.appendChild(newNote);
squareQuantity.push(this.newNote);
}
var generationSpeed = setInterval(squareCreator, 300);
function fallingMostLeftNote() {
mostLeftNoteMarginTop += 2;
squareQuantity[2].css({
'margin-top': mostLeftNoteMarginTop + 'px'
});
}
Instead of using javascript to update your margin-top, you could use CSS animations. Each new square will animate independently.
Here's an example for your use case:
function addSquare() {
var squaresElement = document.getElementById("squares");
var squareElement = document.createElement("div");
squareElement.className = "square";
squaresElement.append(squareElement);
}
#squares {
display: flex;
}
.square {
height: 100px;
width: 100px;
margin-right: 10px;
background-color: red;
animation-name: fall;
animation-duration: 4s;
animation-timing-function: linear;
}
/* The animation code */
#keyframes fall {
from {margin-top: 0px;}
to {margin-top: 300px;}
}
<button onclick="addSquare()">Add square</button>
<div id="squares"></div>
My approach is giving a css variable while creating divs for transform delay. If you need more complex movements, you can use the same logic for animation instead of transform.
<div class="parent"></div>
.parent {
display: flex;
flex-direction: row;
align-items: flex-start;
}
.lets-try {
flex: 1;
background: #000;
height: 60px;
margin-right: 5px;
margin-left: 5px;
transition: all 0.5s ease-in-out var(--delay);
}
.lets-try.is-falling {
margin-top: 100px;
}
let parent = document.querySelector(".parent");
let numOfSquares = 12;
for (let i = 0; i < numOfSquares ; i++) {
let delay = i * 0.2;
let div = document.createElement('div');
div.setAttribute('class', 'lets-try');
div.setAttribute('style', `--delay:${delay}s`);
parent.appendChild(div);
}
setTimeout(() => {
let items = document.querySelectorAll(".lets-try");
[...items].forEach(item => {
item.classList.add("is-falling")
})
}, 1)

Uncaught TypeError: Cannot read property 'addEventListener' of null (querySelector)

I'm getting the following error:
Uncaught TypeError: Cannot read property 'addEventListener' of null
addEventListener works perfectly fine on a single id (menu)... Is there a restriction that I can't use it on querySelector?
(Yes, JavaScript is at the bottom of the HTML document)
Any help will be appreciated.
https://plnkr.co/edit/AIAOZk40ssoofpvrt9dm?p=preview
var menu = document.getElementById("menu");
var area = document.querySelector("#menu + #envelope + #links");
menu.addEventListener("mouseenter", addHref);
area.addEventListener("mouseleave", remHref);
menu.addEventListener("click", addHref);
document.addEventListener("click", function (){
if (this != area){
remHref();
}
});
function remHref (){
document.getElementById("google").removeAttribute("href");
document.getElementById("mysite").removeAttribute("href");
}
function addHref (){
setTimeout(activate, 2500);
}
function activate (){
document.getElementById("google").setAttribute("href", "https://www.google.com");
document.getElementById("mysite").setAttribute("href", "https://www.mywebsite.com");
}
<div id="menu">Click here to browse the internet.
<div id="envelope">
<div id="links" >
<div><a ><img id="google" src="https://seomofo.com/wp-content/uploads/2010/05/google_logo_new.png" /></a></div>
<div style="width: 20%;"></div>
<div><a ><img id="mysite" src="https://toppng.com/uploads/preview/wwf-logo-horizontal-world-wildlife-foundation-logo-shirt-11563219164hg5hfcveei.png"/></a></div>
</div>
</div>
</div>
#menu{
height: 10vh;
background-color: red;
text-align: center;
transition: all 1s ease-out;
padding-top: 5vh;
}
#menu:hover{
color: red;
}
#envelope{
height: 0;
display: block;
visibility: hidden;
background-color: blue;
min-width: 100%;
z-index: 1;
position: absolute;
left: 0;
content: "";
opacity: 0;
transition: all 1.3s ease-out;
}
#links{
height: 0;
visibility: hidden;
display: flex;
background-color: pink;
justify-content: center;
z-index: 2;
min-width: 100%;
opacity: 0;
transition: all 1s ease-in;
}
#google{
margin-top: -1vh;
width: 150px;
}
#mysite{
padding-left: 5%;
margin-top: -1vh;
width: 150px;
}
#menu:hover #envelope{
height: 100px;
opacity: 1;
visibility: visible;
}
#menu:focus #envelope{
height: 100px;
opacity: 1;
visibility: visible;
}
#menu:hover #links{
opacity: 1;
height: 300px;
visibility: visible;
}
#menu:focus #links{
opacity: 1;
height: 300px;
visibility: visible;
}
Try changing:
var area = document.querySelector("#menu + #envelope + #links");
for:
var area = document.querySelector("#menu #envelope #links");
As your html is:
<div id="menu">Click here to browse the internet.
<div id="envelope">
<div id="links" >
...
</div>
</div>
</div>
The element+element selector (Adjacent Sibling Selector) is used to select elements that are placed immediately after (not inside) the first specified element. You need the Descendant Selector or the Child Selector.
Have a look at the w3cschools CSS Combinators.
Or, in this case and as epascarello says, you can just use:
var area = document.querySelector("#links");
as the ids must be unique if the document validates.
i've edited your plunk to fit the 2 small mistake you've made.
The first mistake was to include the script in the tag.
i've put in before the closing tag
Also, as mentionned #jeprubio you need to remove the '+' from the querySelector() call.
Here is the edited plunk
https://plnkr.co/edit/sB7r0MguCN3KvhdHvB4i
code
// Code goes here
var menu = document.getElementById("menu");
var area = document.querySelector("#menu #envelope #links");
menu.addEventListener("mouseenter", addHref);
area.addEventListener("mouseleave", remHref);
menu.addEventListener("click", addHref);
document.addEventListener("click", function (){
if (this != area){
remHref();
}
});
function remHref (){
document.getElementById("google").removeAttribute("href");
document.getElementById("mysite").removeAttribute("href");
}
function addHref (){
setTimeout(activate, 2500);
}
function activate (){
document.getElementById("google").setAttribute("href", "https://www.google.com");
document.getElementById("mysite").setAttribute("href", "https://www.mywebsite.com");
}
Your code is fine you need just to :
Place your script before closing tag </body>.
Correct querySelector fo element area from "#menu + #envelope + #links" to "#menu #envelope #links"
Example :
// Code goes here
var menu = document.getElementById("menu");
var area = document.querySelector("#menu #envelope #links");
menu.addEventListener("mouseenter", addHref);
area.addEventListener("mouseleave", remHref);
menu.addEventListener("click", addHref);
document.addEventListener("click", function (){
if (this != area){
remHref();
}
});
function remHref (){
document.getElementById("google").removeAttribute("href");
document.getElementById("mysite").removeAttribute("href");
}
function addHref (){
setTimeout(activate, 2500);
}
function activate (){
document.getElementById("google").setAttribute("href", "https://www.google.com");
document.getElementById("mysite").setAttribute("href", "https://www.mywebsite.com");
}
/* Styles go here */
#menu{
height: 10vh;
background-color: red;
text-align: center;
transition: all 1s ease-out;
padding-top: 5vh;
}
#menu:hover{
color: red;
}
#envelope{
height: 0;
display: block;
visibility: hidden;
background-color: blue;
min-width: 100%;
z-index: 1;
position: absolute;
left: 0;
content: "";
opacity: 0;
transition: all 1.3s ease-out;
}
#links{
height: 0;
visibility: hidden;
display: flex;
background-color: pink;
justify-content: center;
z-index: 2;
min-width: 100%;
opacity: 0;
transition: all 1s ease-in;
}
#google{
margin-top: -1vh;
width: 150px;
}
#mysite{
padding-left: 5%;
margin-top: -1vh;
width: 150px;
}
#menu:hover #envelope{
height: 100px;
opacity: 1;
visibility: visible;
}
#menu:focus #envelope{
height: 100px;
opacity: 1;
visibility: visible;
}
#menu:hover #links{
opacity: 1;
height: 300px;
visibility: visible;
}
#menu:focus #links{
opacity: 1;
height: 300px;
visibility: visible;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="menu">Click here to browse the internet.1
<div id="envelope">
<div id="links">
<div>
<a><img id="google" src="https://seomofo.com/wp-content/uploads/2010/05/google_logo_new.png" /></a>
</div>
<div style="width: 20%;"></div>
<div>
<a><img id="mysite" src="https://toppng.com/uploads/preview/wwf-logo-horizontal-world-wildlife-foundation-logo-shirt-11563219164hg5hfcveei.png" /></a>
</div>
</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
Wrap your Javascript in window.onload()
window.onload=function() {
/*your code here*
/*var date = document.getElementById("date");
/*alert(date);
}
It looks like the browser is executing your JavaScript before it has "executed your HTML"/made the page, so those HTML elements/DOM nodes don't exist yet. This introduces a delay until the HTML is loaded, so that the nodes exist (not null) before JavaScript tries to attach methods to them. (And what jprubio said below about your selector.)

Uniform page load

I have two problems:
Animation issue(moving while scrolling):
My HTML:
<body>
<header class="stable">
<div id="object">
<img src="img/object.png">
</div>
</header>
</body>
My CSS:
#object{
position: absolute;
left: 0;
right: 0;
margin:auto;
bottom: 0%;
width: 45.9%;
height: auto;
animation: animation 1s ease-out;
z-index: 99;
}
#keyframes animation{
from{
left: -200%;
}
}
My JS:
var object = document.querySelector('#object');
window.addEventListener('scroll', function() {
var s = $(document).scrollTop();
var percent_from_top = s/this.innerHeight;
if(0 <= percent_from_top <= 1){
object.style.left = 150*(percent_from_top)+'%';
object.style.transition = "0.75s linear";
}
});
Problem with strip:
My HTML:
<section id="first_section">
<div class="strip"></div>
</section>
My CSS:
#first_section > .strip{
left: 0%;
right:0;
margin: auto;
margin-top:-30%;
width: 40%;
height: 130%;
transform: rotate(70deg);
background: rgba(0,0,0, 0.9);
}
It all works...
but it doesn't seem effective enough, because
it slows down, and
it partially appears
I tried to use clip-path for example, but it works the same way.
Is there a way to create a page more "evenly"?

Javascript is having problems with moving divs around

Here's a function:
function rollImgOnSwipe(direction) {
changeDirection(direction);
rollImage(direction);
}
The first called function (changeDirection(direction);) is supposed to place a div in either the left or right side of the screen, depending on the value of its argument. The second one (rollImage(direction);) is to make the div move from left to right or from right to left, depending on where the first function placed it.
Well, it seems like it first calls rollImage and then changeDirection because it takes rollImgOnSwipe to be called more than once in order for the div to be placed on the other side.
The best way to explain this to you is to show you - run the code snippet and try switching between the divs with the prev and next buttons and see how they behave.
var nextBtn = document.getElementById('next'),
prevBtn = document.getElementById('prev'),
shown = document.getElementsByClassName('shown')[0],
hidden = document.getElementsByClassName('hidden')[0];
function rollImage(direction) {
shown.classList.remove("shown");
shown.classList.add("hidden");
hidden.classList.remove("hidden");
hidden.classList.add("shown");
shown = document.getElementsByClassName('shown')[0];
hidden = document.getElementsByClassName('hidden')[0];
changeDirection(direction);
}
function rollImgOnSwipe(direction) {
changeDirection(direction);
rollImage(direction);
}
function changeDirection(direction) {
hidden.style.left = (105 * direction) + "%";
shown.style.left = 0;
}
nextBtn.addEventListener('click', function () { rollImgOnSwipe(1); });
prevBtn.addEventListener('click', function () { rollImgOnSwipe(-1); });
.img {
position: absolute;
display: block;
width: 80px;
height: 30px;
border-style: solid;
border-color: red;
border-width: 5px;
}
.shown{
left: 0;
transition: left .6s ease, transform .6s ease;
}
.hidden{
left: 105%;
}
.img-wrapper{
position: relative;
width: 80px;
height: 30px;
padding: 30px;
white-space: nowrap;
overflow: hidden;
}
<button id="prev">prev</button>
<div class="img-wrapper">
<div class="img shown"></div>
<div class="img hidden"></div>
</div>
<button id="next">next</button>
To fix this, i make the compiler wait for a bit before calling rollImage by using the setTimeout function in rollImgOnSwipe.
And now the program works as expected:
var nextBtn = document.getElementById('next'),
prevBtn = document.getElementById('prev'),
shown = document.getElementsByClassName('shown')[0],
hidden = document.getElementsByClassName('hidden')[0];
function rollImage(direction) {
shown.classList.remove("shown");
shown.classList.add("hidden");
hidden.classList.remove("hidden");
hidden.classList.add("shown");
shown = document.getElementsByClassName('shown')[0];
hidden = document.getElementsByClassName('hidden')[0];
changeDirection(direction);
}
function rollImgOnSwipe(direction) {
changeDirection(direction);
setTimeout(function() { rollImage(direction); }, 50);
}
function changeDirection(direction) {
hidden.style.left = (105 * direction) + "%";
shown.style.left = 0;
}
nextBtn.addEventListener('click', function(){ rollImgOnSwipe(1); });
prevBtn.addEventListener('click', function(){ rollImgOnSwipe(-1); });
.img {
position: absolute;
display: block;
width: 80px;
height: 30px;
border-style: solid;
border-color: red;
border-width: 5px;
}
.shown{
left: 0;
transition: left .6s ease, transform .6s ease;
}
.hidden{
left: 105%;
}
.img-wrapper{
position: relative;
width: 80px;
height: 30px;
padding: 30px;
white-space: nowrap;
overflow: hidden;
}
<button id="prev">prev</button>
<div class="img-wrapper">
<div class="img shown"></div>
<div class="img hidden"></div>
</div>
<button id="next">next</button>
My question is:
What is the problem and why is it fixed by making the compiler wait?

Categories

Resources