How to toggle 2 classes with ECMAScript - ecmascript-6

I have two CSS classes. One that fades in an element's opacity class-A (using CSS3 Keyframes). And the other that fades out the opacity back to 0 class-B (using CSS3 Keyframes). Is there a way in pure ecmascript to toggle between these two classes? On first click, class-A loads. If you click it again, Class-B loads. If you click it a third time class-A loads, etc...
The following is the extent of my knowledge on toggling classes, relating to click event handling....
var anchors = document.querySelectorAll('a');
for (var i = 0, len = anchors.length; i < len; i++) {
anchors[i].addEventListener('click', function (e) {
e.preventDefault();
if (this.classList.contains('my-trigger')) {
document.querySelector('.what-i-am-fading-in-and-fading-out-on-clicks').classList.toggle('class-A');
}
}
};
It's easy to fade in an element when I click on my link my-trigger the first time. But my end goal is to have a nice fade out process on the element, when my link is clicked a 2nd time, or 4th time, etc...How can I capitalize on this?

I dont know if i understand it right, but you could add an if statement to look if the opacity is 0 or 1, and then add the classes, once a class is added you dont need to look for it.
You can change the opacity of #test to 1 or 0 and it will change respectivley to it.
let test = document.getElementById("test");
let but = document.getElementById("but");
but.onclick = ()=>{
if(test.classList.contains("a")||test.classList.contains("b")){
test.classList.toggle("a");
test.classList.toggle("b");
}else{
if(window.getComputedStyle(test).getPropertyValue("opacity") == "0"){
test.classList.add("b")
}else{
test.classList.add("a")
}
}
}
#test{
width:100px;
height:25px;
background:black;
opacity:1;
}
#but{
width:50px;
background: lightgrey;
margin-top:20px;
}
.a{
opacity:0 !important;
transition:opacity 300ms;
}
.b{
opacity:1 !important;
transition:opacity 300ms;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Grocery Bud</title>
<!-- font-awesome -->
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css"
/>
<!-- styles -->
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="test"></div>
<div id="but">Button</div>
</body>
<script src="app.js"></script>
</html>

I think this is the easiest way to toggle the class with Animation using ES6 (classList.toggle)
let toggleElement = document.getElementById("toggleElement");
let but = document.getElementById("btn");
but.onclick = ()=>{
toggleElement.classList.toggle('active');
}
#toggleElement{
width:150px;
height:25px;
background:Red;
opacity:1;
padding:10px;
}
.ele{
opacity:0 !important;
transition:opacity 300ms;
}
.ele.active{
opacity:1 !important;
transition:opacity 300ms;
}
<button id="btn">Button</button>
<div id="toggleElement" class="ele" > Toggle CSS Class </div>

Related

How to change modal's background color?

I was wondering how would I go around changing my modal's background color after it has displayed, like the following: I want the background color to cover the whole page and not just color the modal itself. I tried:
.modal {
background-color: rgb(255, 0, 0);
}
But this resulted as I said in the colored modal and not the whole page.
Here's a snippet for refrence:
const modal = document.querySelector(".modal");
const openModal = document.querySelector(".open-button");
const closeModal = document.querySelector(".close-button");
openModal.addEventListener("click", () => {
modal.showModal();
});
closeModal.addEventListener("click", () => {
modal.close();
});
.modal {
background-color: rgb(255, 0, 0);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<button class="button open-button" >Open</button>
<dialog class="modal">
Hi! I'm 15Rabi
<button class="button close-button" >Close</button>
</dialog>
</body>
<script src="script.js"></script>
</html>
To change the backdrop color for a <dialog> element you needs to style the ::backdrop pseudo element like this:
.modal::backdrop {
background-color: rgb(255, 0, 0);
}
Ideally though you'd want to to be a semi transparent color, not solid red, so you might want to use rgba instead
.modal::backdrop {
background-color: rgba(255, 0, 0, 0.5);
}
Links to the relevant docs:
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog
https://developer.mozilla.org/en-US/docs/Web/CSS/::backdrop
Try this in your CSS
dialog::backdrop {
background-color: rgb(255, 0, 0);
}

How do i modify :hover values after an animation has occurred and changed the font-size of an h1?

How do i modify :hover after an animation has occurred and changed the font-size of an h1?
it goes like this:
text: font-size: 12.5rem; letter-spacing: 0;
hover over the text- font-size: 13.5rem letter-spacing: 1rem; , after a few seconds, an animation with #keyframes comes and is changing the font-size, from 12.5rem to 5 rem. with the new change applied (font-size: 5rem;) I want to hover over it again but this time the values of :hover to change, the size when I hover to be from 5rem(the new values after the animation) to 6 rem, and letter-spacing, from 1rem; to 0.2rem.
i don't know how to do it.. please help me with some code
solution created with vanilla Js
let title = document.getElementById('title');
let i = 0;
title.addEventListener('mouseover', function() {
if (i >= 1) {
hoverText(5, 6);
title.removeEventListener('mouseover', function() {});
} else {
hoverText(12.5, 13.5);
i++;
}
});
function hoverText(small, big) {
title.style.fontSize = big + "rem";
setTimeout(function() {
title.style.fontSize = small + "rem";
}, 1000);
}
h1#title {
font-size: 12.5rem;
letter-spacing: 0;
transition-duration: 1s;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
<script src="./script.js" defer></script>
</head>
<body>
<h1 id="title">h1 element</h1>
</body>
</html>

babylon.js scene with transparent background won't show image/ text behind it z-index

i want to show text behind a babylon.js scene. I've made the background transparent but i can't see the text behind it. I've also tried z-index:-1 for the text.
I've only been learning Babylon since last night so I'm really not too sure whats going on. I'm also not good at java Script so any help would be greatly appreciated :)
\\\\\<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>BBY TIAL </title>
<script src="https://cdn.babylonjs.com/babylon.max.js"></script>
<style>
*{
background-color: pink;
}
#canvas {
width:80%;
height:80vh;
z-index:10;
border:0;
padding:0;
margin:0;
background-color: transparent;
}
#maya{
font-size: 300px;
color:white;
position: absolute;;
background-color: transparent;
z-index:-200;
}
#wright{
font-size: 300px;
color:white;
position: fixed;
z-index:1;
top:50vh;
left:40%;
background-color: transparent;
}
#full{
z-index: -9;
}
</style>
</head>
<body>
<h1 id="maya">MAYA</h1>
<h2 id="wright">WRIGHT</h2>
<canvas id="canvas"></canvas>
<script>
window.addEventListener('DOMContentLoaded', function(){
var canvas = document.getElementById('canvas');
var engine = new BABYLON.Engine(canvas, true,);
engine.enableOfflineSupport = false; // Dont require a manifest file
var createScene = function(){
var scene = new BABYLON.Scene(engine);
scene.clearColor = new BABYLON.Color4(0, 0, 0, 0);
var camera = new BABYLON.ArcRotateCamera("arcCam",
BABYLON.Tools.ToRadians(0),
BABYLON.Tools.ToRadians(0),
7.,BABYLON.Vector3.Zero(),scene);
camera.attachControl(canvas,true);
var light = new BABYLON.PointLight("PointLight",new BABYLON.Vector3(
5,5,5),scene);
light.parent = camera;
light.intensity = 1000.5;
BABYLON.SceneLoader.ImportMesh("","","ShippingContainer.babylon",
scene,function(newMeshes) {
newMeshes.forEach(function(mesh){
mesh.rotation = new BABYLON.Vector3(BABYLON.Tools.ToRadians(
0),0,0);
} );
});
return scene;
}
var scene = createScene();
engine.runRenderLoop(function(){
scene.render();
});
});
</script>
<h1 id="full">Maya<br/>Wright</h1>
<style>
#canvas{
background: transparent;
}
h1{
background-color: transparent;
font-size: large;
top:5vh;
left:40%;
position: absolute;
}
</style>
</body>
</html>
\\
The main issue here is setting background color to '*' elements, which prevents the image to be shown. When removing it (and adding it only to body), the h1s (with the negative z index) are shown behind the babylon scene:
Note that I didn't use your model, but the default babylon scene, as i have no access to it.
There is no need to set the canvas' background color to be transparent, the scene.clearColor parameter is doing it for you.

CSS: Invisible element with transition: all flashes on page load [duplicate]

This question already has answers here:
Stop CSS transition from firing on page load
(9 answers)
Closed 3 months ago.
I have a popup element which is hidden by default and only shows up programmatically when the script assigns a specific class to its container and populates the popup text.
In css/stylesheet.css:
.error-message {
opacity: 0;
visibility: hidden;
transition: all 0.2s ease;
}
.container.with-error .error-message {
opacity: 1;
visibility: visible;
}
In index.html:
<link rel="stylesheet" href="css/stylesheet.css">
<div class="container">
<div class="error-message">This text will be changed by a script.</div>
</div>
According to this simple style declaration, the .error-message element should always be invisible, unless it is preceded by a .container.with-error, in which case it becomes visible, and its appearance is always animated because of transition property.
However, the .error-message triggers its transition when the page is loaded, resulting in a flash which I believe it should not do.
Related behavior I have observed:
The flash does not appear if the style is declared in an inline <style> tag
The flash appears if every style but transition: all is declared in an inline <style> tag
The flash does not appear if the style is loaded from a Base-64 encoded Data URL like this: <link href="data:text/css;base64,...">
The flash does not appear if the style loaded from <link rel="stylesheet"> is retrieved from cache.
I've created a demo that reproduces this bug every time. To simulate requesting a remote stylesheet without cache, a blob:// Object URL is generated from the style instead. The inline demo is available at the end of this question, but for best results, use JSBin. Use F5 to see the bug in action.
I'm curious how to fix this and what causes this issue as this is clearly not intended behavior.
<!doctype html>
<html lang="en">
<head>
<script>
/* jshint browser: true, esversion: 6 */
window.onload = function() {
// Log all transition events
window.ontransitioncancel = appendToTransitionLog;
window.ontransitionstart = appendToTransitionLog;
window.ontransitionrun = appendToTransitionLog;
window.ontransitionend = appendToTransitionLog;
// Simulates loading a stylesheet from a remote location
// Works the same way as if #simulated-stylesheet's content
// was hosted and served from <link rel=stylesheet> without cache
//
// Keep in mind that this bug does not appear
// if the style is injected or loaded from cache!
createFakeStylesheet();
};
function createFakeStylesheet() {
var styleContent = document.getElementById("simulated-stylesheet").text;
var styleBlob = new Blob([styleContent], {type: "text/css"});
var styleURL = URL.createObjectURL(styleBlob);
var linkElement = document.createElement("link");
linkElement.rel = "stylesheet";
linkElement.href = styleURL;
document.head.appendChild(linkElement);
}
// Functions below handle transition events logging
// Template import helper
function importTemplateFromId(id) {
return document.importNode(document.getElementById(id).content, true);
}
// Returns a string like "div.class1.class2" to describe an element
function describeElement(element) {
var tagName = element.tagName.toLowerCase();
var classes = element.classList.toString().split(" ").filter(className => className != "").map(className => "." + className).join("");
return tagName + classes;
}
// Returns a matching log group wrapper.
// The wrapper is created if the group does not exists.
// Used for grouping transition events by element descriptor
function getLogWrapper(logContainer, elementText) {
var matchingWrapper = logContainer.querySelector(".wrapper[data-for-element=\"" + elementText + "\"] .logs");
if (matchingWrapper) {
return matchingWrapper;
}
var wrapperTemplate = importTemplateFromId("wrapper-template");
var wrapperName = wrapperTemplate.querySelector(".name");
var wrapperElement = wrapperTemplate.querySelector(".wrapper");
wrapperName.textContent = elementText;
wrapperElement.dataset.forElement = elementText;
return logContainer.appendChild(wrapperElement).querySelector(".logs");
}
// Logs a transition event.
// Logs are grouped by each event type (start, run, end)
// and target element's descriptor (see describeElement)
function appendToTransitionLog(transitionEvent) {
var eventType = transitionEvent.type;
var eventProperty = transitionEvent.propertyName;
var logContainer = document.getElementById("log-" + eventType);
var elementText = describeElement(transitionEvent.target);
var logWrapper = getLogWrapper(logContainer, elementText);
var logEntry = document.createElement("span");
logEntry.textContent = eventProperty;
logEntry.className = "entry";
logWrapper.appendChild(logEntry);
}
</script>
<style>
#edit-with-js-bin {
display: none!important;
}
.log {
font-size: 14px;
}
.log .wrapper {
padding-left: 16px;
}
.wrapper .name {
text-decoration: underline;
}
.wrapper .logs {
padding-left: 12px;
}
.wrapper .entry {
display: inline-block;
color: grey;
padding: 8px 4px;
}
.wrapper .entry:nth-child(2n) {
color: lightgrey;
}
body {
font-family: monospace;
font-size: 0;
}
.side {
display: inline-block;
font-size: 14px;
vertical-align: top;
width: 50%;
height: 100%;
}
</style>
<template id="wrapper-template">
<div class="wrapper" data-for>
<span class="name"></span>
<div class="logs"></div>
</div>
</template>
<script id="simulated-stylesheet" type="text/css">
.remote {
background: crimson;
color: white;
display: inline-block;
margin: 8px;
padding: 8px;
}
.remote.transparent {
opacity: 0;
visibility: hidden;
}
.remote.transition-some {
transition: opacity, visibility 1s ease;
}
.remote.transition-all {
transition: all 1s ease;
}
</script>
<style>
.transition-all-inline {
transition: all 1s ease;
}
.local {
background: green;
color: white;
display: inline-block;
margin: 8px;
padding: 8px;
}
.local.transparent {
opacity: 0;
visibility: hidden;
}
.local.transition-some {
transition: opacity, visibility 1s ease;
}
.local.transition-all {
transition: all 1s ease;
}
.mock {
background: orangered;
transition: all 1s ease;
}
.mock:hover {
background: orange;
}
</style>
</head>
<body>
<div class="side left">
<div>
<u>.remote</u> <div class="remote">I'm always styled.</div>
</div>
<div>
.remote<u>.transparent</u> <div class="remote transparent">I'm always transparent.</div>
</div>
<div>
.remote.transparent<u>.transition-some</u> <div class="remote transparent transition-some">I'm invisible!</div>
</div>
<div>
.remote.transparent<u>.transition-all</u> <div class="remote transparent transition-all">I will briefly flash when the page loads.</div>
</div>
<div>
.remote.transparent<u>.transition-all-inline</u> <div class="remote transparent transition-all-inline">I will briefly flash when the page loads.</div>
</div>
</div>
<div class="side right">
<div>
<u>.local</u> <div class="local">I'm always styled.</div>
</div>
<div>
.local<u>.transparent</u> <div class="local transparent">I'm always transparent.</div>
</div>
<div>
.local.transparent<u>.transition-some</u> <div class="local transparent transition-some">I'm invisible!</div>
</div>
<div>
.local.transparent<u>.transition-all</u> <div class="local transparent transition-all">I'm invisible!</div>
</div>
<div>
.local.transparent<u>.transition-all-inline</u> <div class="local transparent transition-all-inline">I'm invisible!</div>
</div>
<div>
.local.mock <div class="local mock">Use me to debug transition events!</div>
</div>
</div>
<div class="log">
<div>
<b>ontransitionstart</b>
<div id="log-transitionstart"></div>
</div>
<div>
<b>ontransitionrun</b>
<div id="log-transitionrun"></div>
</div>
<div>
<b>ontransitionend</b>
<div id="log-transitionend"></div>
</div>
<div>
<b>ontransitioncancel</b>
<div id="log-ontransitioncancel"></div>
</div>
</div>
</body>
</html>
EDIT: The flash appears regardless of what property is being transitioned.
This still creates the same effect:
.error-message {
transition: opacity 0.2s ease;
}
It's a normal behavior of transition (not a bug of any specific browser).
The issue in your case is that you already have elements (that flashes) in the DOM tree.
That also means the elements have an initial state and any new state performs a transition. If a new style applied and it has a transition property a browser will show you animation between the initial state and the new state with a transition property. (Note that the initial state of the element that flashes is not transparent).
The possible fix for that is to add hidden elements when new styles already exist. Or refactor your styles to have a transparent initial state.

Container hidden behind other container

I am pretty sure this is a positioning issue, but unfortunately positioning is my weakness.
I have a container with a jquery image slideshow in it. The images in the slideshow have to be {position: absolute;} or else they will just display one after the other down the page.
Unfortuntely, the containers that come after the slideshow container are displaying behind the slideshow container, not underneath it. I think this is because of the absolute positioning of the slideshow images, but I don't know how to rectify it.
#charset "UTF-8";
/* CSS Document */
#main {
position: relative;
width: 100%;
}
#slideshow {
position: relative;
width: auto;
}
#slideshow IMG {
position: absolute;
top: 0;
left: 0;
z-index: 8;
opacity: 0.0;
}
#slideshow IMG.active {
z-index: 10;
opacity: 1.0;
}
#slideshow IMG.last-active {
z-index: 9;
}
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script type="text/javascript">
/***
Simple jQuery Slideshow Script
Released by Jon Raasch (jonraasch.com) under FreeBSD license: free to use or modify, not responsible for anything, etc. Please link out to me if you like it :)
***/
function slideSwitch() {
var $active = $('#slideshow IMG.active');
if ($active.length == 0) $active = $('#slideshow IMG:last');
// use this to pull the images in the order they appear in the markup
var $next = $active.next().length ? $active.next() : $('#slideshow IMG:first');
// uncomment the 3 lines below to pull the images in random order
// var $sibs = $active.siblings();
// var rndNum = Math.floor(Math.random() * $sibs.length );
// var $next = $( $sibs[ rndNum ] );
$active.addClass('last-active');
$next.css({
opacity: 0.0
})
.addClass('active')
.animate({
opacity: 1.0
}, 500, function() {
$active.removeClass('active last-active');
});
}
$(function() {
setInterval("slideSwitch()", 3000);
});
</script>
<link href="../../Assignment5-Portfolio/HTML/style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="main">
<div id="slideshow">
<img src="../Images/bike.png" width="100%" height="auto" class="active" />
<img src="../Images/fish.png" width="100%" height="auto" />
<img src="../Images/stairs.png" width="100%" height="auto" />
<img src="../Images/gage.png" width="100%" height="auto" />
</div>
<div id="aboutme">About me</div>
<div id="videography">Video
<div id="text">text goes here</div>
<div id="video">video goes here</div>
</div>
<div id="photography">
<div id="photos">photos go here</div>
<div id="photography"></div>
</div>
</div>
</body>
</html>
So, #slideshow is the container in question. The images in it are blocking the containers below it. I want the images to stretch across the whole width of the screen.
As I said, I'm fairly certain it's a positioning problem, but I feel like I could also be missing something important from the #slideshow container, but I can't find what it is.
Thanks in advance for any help you can provide!
You should put a wrapper div around the entire slideshow and give it position:relative; That way it will contain the slideshow and create the spacing you need.
If you will consider a bit more javascript you could add this tidbit of code
$(document).ready(function()
{
var objHeight = 0;
$.each($('#slideshow').children(), function(){
objHeight = $(this).height();
});
$('#slideshow').height(objHeight);
});
DEMO
the absolute and also relative positioned elements should have certain height and width (however block elements have the width:100% initially). Otherwise next elements will overlap with them. So if you have certain height for your images e.g. 400px then:
#slideshow {
position:relative;
width:auto;
height:400px;
}