Hey am new to javascript but putting my all efforts I have written a javascript to copy the text inside a <p></p> element.
My javascript
function copyToClipboard(var1){
let val = document.getElementById(var1).innerHTML;
const selBox = document.createElement('textarea');
selBox.style.position = 'fixed';
selBox.style.left = '0';
selBox.style.top = '0';
selBox.style.opacity = '0';
selBox.value = val;
document.body.appendChild(selBox);
selBox.focus();
selBox.select();
document.execCommand('copy');
document.body.removeChild(selBox);
}
But I needed a custom alert button when text is copied.
My html
<div class="Engstatus">
<h2 class="statusheading">Latest English Status</h2>
<div id="englishstatus">
<div class="latestatus">
<p id="p1">life os good when hou have books</p>
<button class="copystatus btn" onclick="copyToClipboard('p1')">Copy</button>
<span class="copystatusalert">Copied!</span>
</div>
<div class="latestatus">
<p id="p2">Google is a open source library. It is a open source by lary page and sergy brime</p>
<button class="copystatus btn" onclick="copyToClipboard('p2')">Copy</button>
<span class="copystatusalert">Copied!</span>
</div>
<div class="latestatus">
<p id="p3">Cat is better than dog</p>
<button class="copystatus btn" onclick="copyToClipboard('p3')">Copy</button>
<span class="copystatusalert">Copied!</span>
</div>
</div>
</div>
I needed the <span class="copystatusalert">Copied!</span> to be visible for a few seconds when clicked the respective copy button and become vanished.
For more reference My Css
.copystatusalert{
position: relative;
background-color: var(--primary-color);
color: #ffffff;
margin-left: 10px;
padding: 3px 3px;
border-radius: 5px;
z-index: 2;
opacity: 1;
pointer-events: auto;
transition: opacity 0.4s, margin-top 0.4s;
}
.copystatusalert:before{
content:"";
position: absolute;
height: 10px;
width: 10px;
background-color: var(--primary-color);
left: -5px;
transform: translateY(50%) rotate(45deg);
z-index: -1;
top: 17%;
}
Here is a short addition to the copyToClipboard function in order to just change the .copystatusalert color...
function copyToClipboard(var1) {
let val = document.getElementById(var1).innerHTML;
const selBox = document.createElement('textarea');
selBox.style.position = 'fixed';
selBox.style.left = '0';
selBox.style.top = '0';
selBox.style.opacity = '0';
selBox.value = val;
document.body.appendChild(selBox);
selBox.focus();
selBox.select();
document.execCommand('copy');
document.body.removeChild(selBox);
// to change the color of .copystatusalert
let copyStatus = document.getElementById(var1).closest(".latestatus").querySelector(".copystatusalert")
copyStatus.style.color = "black";
// Change the color again in 800 milliseconds
setTimeout(function(){
copyStatus.style.color = "white";
},800)
}
.copystatusalert {
position: relative;
background-color: var(--primary-color);
color: #ffffff;
margin-left: 10px;
padding: 3px 3px;
border-radius: 5px;
z-index: 2;
opacity: 1;
pointer-events: auto;
transition: opacity 0.4s, margin-top 0.4s;
}
.copystatusalert:before {
content: "";
position: absolute;
height: 10px;
width: 10px;
background-color: var(--primary-color);
left: -5px;
transform: translateY(50%) rotate(45deg);
z-index: -1;
top: 17%;
}
<div class="Engstatus">
<h2 class="statusheading">Latest English Status</h2>
<div id="englishstatus">
<div class="latestatus">
<p id="p1">life os good when hou have books</p>
<button class="copystatus btn" onclick="copyToClipboard('p1')">Copy</button>
<span class="copystatusalert">Copied!</span>
</div>
<div class="latestatus">
<p id="p2">Google is a open source library. It is a open source by lary page and sergy brime</p>
<button class="copystatus btn" onclick="copyToClipboard('p2')">Copy</button>
<span class="copystatusalert">Copied!</span>
</div>
<div class="latestatus">
<p id="p3">Cat is better than dog</p>
<button class="copystatus btn" onclick="copyToClipboard('p3')">Copy</button>
<span class="copystatusalert">Copied!</span>
</div>
</div>
</div>
Now... Since you are "new to javascript", I suggest you to close look at this solution.
The intend is to create ONE function which will apply to as many as you want status elements... and avoid managing the unique id for all <p>... And to "reduce" the redondant HTML markup (buttons and alert spans).
Please look at the comments below for step-by-step details and feel free for questions. ;)
// The animation delay for the "copied" alert
let copyAlertAnimationDelay = 400; // ms
// Get all the status elements
let status = document.querySelectorAll(".status");
// For each status, add a button with its event listener
status.forEach(function(elem) {
// Create the button
let btn = document.createElement('button');
btn.setAttribute("class", "copystatus btn");
btn.innerText = "Copy";
// Append the button
elem.after(btn);
// Set the button event listener
btn.addEventListener("click", function() {
// Get the status
let statusToCopy = elem.innerText;
// Create the temporary textarea to copy the text
const selBox = document.createElement('textarea');
// Use a class instead of multiple element.style.property changes
selBox.setAttribute("class", "hiddenCopy");
selBox.value = statusToCopy;
// Append, copy and remove.
document.body.appendChild(selBox);
selBox.focus();
selBox.select();
document.execCommand('copy');
selBox.remove();
// create a "Copied!" element.
let alert = document.createElement("span");
alert.innerText = "Copied!";
alert.setAttribute("class", "copystatusalert");
// Use the copyAlertAnimationDelay variable to set the CSS transition
// So it matches the setTimeout delay below
alert.style.transition = `all ${copyAlertAnimationDelay/1000}s`;
// The animation timeouts
// Show
this.after(alert);
setTimeout(function() {
alert.style.opacity = 1;
}, 1)
// Hide
// Change opacity
setTimeout(function() {
alert.style.opacity = 0;
// Remove element
setTimeout(function() {
document.querySelector(".copystatusalert").remove();
}, copyAlertAnimationDelay);
}, copyAlertAnimationDelay * 3) // 3 times the animation delay...
});
});
body {
--primary-color: #a7d8f2; /* ADDED */
}
.copystatusalert {
position: relative;
background-color: var(--primary-color);
/*color: #ffffff; REMOVED */
margin-left: 10px;
padding: 3px 3px;
border-radius: 5px;
z-index: 2;
opacity: 0;
/* opacity was 1 */
pointer-events: auto;
/*transition: opacity 0.4s, margin-top 0.4s; REMOVED */
}
.copystatusalert:before {
content: "";
position: absolute;
height: 10px;
width: 10px;
background-color: var(--primary-color);
left: -5px;
transform: translateY(50%) rotate(45deg);
z-index: -1;
top: 17%;
}
/* ADDED */
.hiddenCopy {
position: "fixed";
left: 0;
top: 0;
opacity: 0;
}
<div class="Engstatus">
<h2 class="statusheading">Latest English Status</h2>
<div id="englishstatus">
<div class="latestatus">
<p class="status">life os good when hou have books</p>
</div>
<div class="latestatus">
<p class="status">Google is a open source library. It is a open source by lary page and sergy brime</p>
</div>
<div class="latestatus">
<p class="status">Cat is better than dog</p>
</div>
</div>
</div>
Toast is used to display tasks like this.
Use this code
function myFunction() {
var x = document.getElementById("message");
x.className = "show";
// you can set the time here//
setTimeout(function(){ x.className = x.className.replace("show", ""); }, 3000);
}
body {
font-family: 'Oswald', sans-serif;
}
#message {
visibility: hidden;
min-width: 250px;
margin-left: -125px;
background-color: #333;
color: #fff;
text-align: center;
border-radius: 2px;
padding: 16px;
position: fixed;
z-index: 1;
left: 50%;
bottom: 30px;
font-size: 17px;
}
#message.show {
visibility: visible;
-webkit-animation: fadein 0.5s, fadeout 0.5s 2.5s;
animation: fadein 0.5s, fadeout 0.5s 2.5s;
}
/* The animation*/
#-webkit-keyframes fadein {
from {bottom: 0; opacity: 0;}
to {bottom: 30px; opacity: 1;}
}
#keyframes fadein {
from {bottom: 0; opacity: 0;}
to {bottom: 30px; opacity: 1;}
}
#-webkit-keyframes fadeout {
from {bottom: 30px; opacity: 1;}
to {bottom: 0; opacity: 0;}
}
#keyframes fadeout {
from {bottom: 30px; opacity: 1;}
to {bottom: 0; opacity: 0;}
}
<button onclick="myFunction()">Copy</button>
<!-- This is the toast message -->
<div id="message">Text is copied!!</div>
Related
I'm making a website with a 'like' function and if you click the like icon it should make div as a alert at the bottom of the website. The code that I wrote makes the div fade in and after a few seconds the pop up fades out. Then after the fade out the pop up just shows up again on the screen, but stuck this time. I'm learning Javascript so it is new to me so anything would be appreciated.
function myFunction() {
var test = document.querySelector('#color');
var x = document.createElement('div');
if(test.style.color == ""){
test.style.color = "red";
x.innerHTML ='Liked this tournament!';
x.id = "snackbar";
x.className = "show";
} else{
test.style.color = "";
x.innerHTML('Removed like from this tournament!');
x.id = "snackbar";
x.className = "show";
}
document.body.appendChild(x);
}
#snackbar {
visibility: hidden;
min-width: 250px;
margin-left: -125px;
background-color: #333;
color: #fff;
text-align: center;
border-radius: 2px;
padding: 16px;
position: fixed;
z-index: 1;
left: 10%;
bottom: 30px;
font-size: 17px;
}
#snackbar.show {
visibility: visible;
-webkit-animation: fadein 0.5s, fadeout 0.5s 2.5s;
animation: fadein 0.5s, fadeout 0.5s 2.5s;
}
<link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css">
<ul>
<li onclick="myFunction();"><i id="color" class="fas fa-heart"></i></li>
<li><i class="fas fa-plus"></i></li>
<li><i class="fas fa-expand"></i></li>
</ul>
I think it's maybe because of the document.body.appendChild(x); overwriting the css? I'm not sure what's happening..
A short video about the pop up: https://imgur.com/a/KfD7hNW
I'm not sure if you forgot to copy a portion of your CSS but you don't seem to have any actual animations. If you want those effects you can use the CSS that https://animate.style/ provides either by importing it or extracting it from their GitHub files if you just want the two animations. But if you're going to use the animation attribute, you need some kind of keyframe animation built out otherwise nothing is going to happen. The forwards value lets the animations play and then doesn't repeat them so it's not flashing after the user clicks the button.
Also, you had some broken JS but that was a simple mistake.
Worth reading: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Animations/Using_CSS_animations so you can see how all of the attributes can be animated and controlled
function myFunction() {
var test = document.querySelector('#color');
var x = document.createElement('div');
if(test.style.color == ""){
test.style.color = "red";
x.innerHTML ='Liked this tournament!';
x.id = "snackbar";
x.className = "show";
} else{
test.style.color = "";
x.innerHTML='Removed like from this tournament!'
x.id = "snackbar";
x.className = "show";
}
document.body.appendChild(x);
}
#snackbar {
visibility: hidden;
min-width: 250px;
margin-left: -125px;
background-color: #333;
color: #fff;
text-align: center;
border-radius: 2px;
padding: 16px;
position: fixed;
z-index: 1;
left: 10%;
bottom: 30px;
font-size: 17px;
}
#snackbar.show {
visibility: visible;
animation: fadeIn 0.5s, fadeOut 0.5s 2.5s forwards;
}
#keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
#keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
.fadeOut {
animation-name: fadeOut;
}
.fadeIn {
animation-name: fadeIn;
}
<link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css">
<ul>
<li onclick="myFunction();">click me<i id="color" class="fas fa-heart"></i></li>
<li>not me<i class="fas fa-plus"></i></li>
<li>or me<i class="fas fa-expand"></i></li>
</ul>
In your approach every time that you click your icon you will create a new div element in the same place, which will create tons of div.. This is not efficient. So you can try something like this.
After adding show class to your div element you can set a timer which will wait for animation happens. Then remove that class with
myDiv.classList.remove('show');
const test = document.querySelector('#color');
const myDiv = document.createElement('div');
myDiv.id = "snackbar";
document.body.appendChild(myDiv);
test.addEventListener('click',() =>{
if(test.style.color == ""){
test.style.color = "red";
myDiv.innerText ='Liked this tournament!';
myDiv.className = "show";
setTimeout(() =>{
myDiv.classList.remove('show');
}, 2000);
}
else{
test.style.color = "";
myDiv.innerText = 'Removed like from this tournament!';
myDiv.className = "show";
setTimeout(() =>{
myDiv.classList.remove('show');
}, 2000);
}
})
*,
*::before,
*::after {
box-sizing: border-box;
}
body{
min-height: 100vh;
overflow: hidden;
display: grid;
place-content: center;
margin:0;
background-color: bisque;
font-size: 100px;
}
#snackbar {
visibility: hidden;
min-width: 250px;
margin-left: -125px;
background-color: #333;
color: #fff;
text-align: center;
border-radius: 2px;
padding: 16px;
position: fixed;
z-index: 1;
left: 10%;
bottom: 30px;
font-size: 17px;
}
#snackbar.show {
visibility: visible;
animation: fadeIn 0.5s, fadeOut 0.5s 1s forwards;
}
#keyframes fadeIn {
0%{
opacity:0;
}
100%{
opacity: 1;
}
}
#keyframes fadeOut {
0%{
opacity:1;
}
100%{
opacity: 0;
}
}
<link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css">
<ul>
<li>click me<i id="color" class="fas fa-heart"></i></li>
<li>not me<i class="fas fa-plus"></i></li>
<li>or me<i class="fas fa-expand"></i></li>
</ul>
I have added a button on my site which let's the users change to dark or light mode whenever they want. I added the button with a moon icon on it, but the problem is that I want that the moon icon changes to sun icon when the user is in dark mode. And changes to moon icon when user is in light mode.
function myfunction(e) {
console.log("you clicked");
document.documentElement.classList.toggle("dark-mode");
document.querySelectorAll(".inverted").forEach((result) => {
result.classList.toggle("invert");
});
}
const btn = document.querySelector('.btn')
btn.addEventListener('click', myfunction);
.dark-mode {
filter: invert(1) hue-rotate(180deg);
}
.invert {
filter: invert(1) hue-rotate(180deg);
}
<button class="btn"><img src='moon.png'></img></button>
The .inverted class in js is because I don't want the images to invert their colors.. so I gave all the images a class='inverted'
So, this is what I've done and someone please let me know how I should change the icon to moon and sun depending on the current mode (light or dark)
Thanks!
You could add the sun as another image to the button and change the visibility of the two images via your .dark-mode css class.
So whenever the .dark-mode class is present the moon gets hidden and the sun gets shown.
function myfunction(e) {
console.log("you clicked");
document.documentElement.classList.toggle("dark-mode");
document.querySelectorAll(".inverted").forEach((result) => {
result.classList.toggle("invert");
});
}
const btn = document.querySelector('.btn')
btn.addEventListener('click', myfunction);
.dark-mode {
filter: invert(1) hue-rotate(180deg);
}
.invert {
filter: invert(1) hue-rotate(180deg);
}
/* button handling */
.moon {
display: block;
}
.sun {
display: none;
}
.dark-mode .moon {
display: none;
}
.dark-mode .sun {
display: block;
}
<button class="btn">
<img class="moon" src="moon.png" alt="moon"></img>
<img class="sun" src="sun.png" alt="sun"></img>
</button>
You could go with the CSS approach as in #Fabian's answer. If you would like to go with JS, you could simply use a flag to indicate whether or not the user switched to dark mode, and dynamically set the icon based on it.
let isDarkMode = document.documentElement.classList.contains("dark-mode");
function myfunction(e) {
document.documentElement.classList.toggle("dark-mode");
document.querySelectorAll(".inverted").forEach((result) => {
result.classList.toggle("invert");
});
e.currentTarget.querySelector("img").src = isDarkMode ? "sun.png" : "moon.png";
}
You can use the below reference for the toggle button from light mode to dark mode and dark mode to light mode.
body {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.toggle-checkbox {
position: absolute;
opacity: 0;
cursor: pointer;
height: 0;
width: 0;
}
.toggle-slot {
position: relative;
height: 10em;
width: 20em;
border: 5px solid #e4e7ec;
border-radius: 10em;
background-color: white;
box-shadow: 0px 10px 25px #e4e7ec;
transition: background-color 250ms;
}
.toggle-checkbox:checked ~ .toggle-slot {
background-color: #374151;
}
.toggle-button {
transform: translate(11.75em, 1.75em);
position: absolute;
height: 6.5em;
width: 6.5em;
border-radius: 50%;
background-color: #ffeccf;
box-shadow: inset 0px 0px 0px 0.75em #ffbb52;
transition: background-color 250ms, border-color 250ms, transform 500ms cubic-bezier(.26,2,.46,.71);
}
.toggle-checkbox:checked ~ .toggle-slot .toggle-button {
background-color: #485367;
box-shadow: inset 0px 0px 0px 0.75em white;
transform: translate(1.75em, 1.75em);
}
.sun-icon {
position: absolute;
height: 6em;
width: 6em;
color: #ffbb52;
}
.sun-icon-wrapper {
position: absolute;
height: 6em;
width: 6em;
opacity: 1;
transform: translate(2em, 2em) rotate(15deg);
transform-origin: 50% 50%;
transition: opacity 150ms, transform 500ms cubic-bezier(.26,2,.46,.71);
}
.toggle-checkbox:checked ~ .toggle-slot .sun-icon-wrapper {
opacity: 0;
transform: translate(3em, 2em) rotate(0deg);
}
.moon-icon {
position: absolute;
height: 6em;
width: 6em;
color: white;
}
.moon-icon-wrapper {
position: absolute;
height: 6em;
width: 6em;
opacity: 0;
transform: translate(11em, 2em) rotate(0deg);
transform-origin: 50% 50%;
transition: opacity 150ms, transform 500ms cubic-bezier(.26,2.5,.46,.71);
}
.toggle-checkbox:checked ~ .toggle-slot .moon-icon-wrapper {
opacity: 1;
transform: translate(12em, 2em) rotate(-15deg);
}
<head>
<script src="https://code.iconify.design/1/1.0.4/iconify.min.js"> </script>
</head>
<label>
<input class='toggle-checkbox' type='checkbox'>
<div class='toggle-slot'>
<div class='sun-icon-wrapper'>
<div class="iconify sun-icon" data-icon="feather-sun" data-inline="false"></div>
</div>
<div class='toggle-button'></div>
<div class='moon-icon-wrapper'>
<div class="iconify moon-icon" data-icon="feather-moon" data-inline="false"></div>
</div>
</div>
</label>
function myfunction(e) {
const doc = document.documentElement
doc.classList.toggle("dark-mode");
document.querySelectorAll(".inverted").forEach((result) => {
result.classList.toggle("invert");
});
const img = e.currentTarget.querySelector('img')
const label = e.currentTarget.querySelector('span')
if (doc.classList.contains('dark-mode')) {
img.src = 'sun.png'
label.innerHTML = 'Light mode'
} else {
img.src = 'moon.png'
label.innerHTML = 'Dark mode'
}
}
const btn = document.querySelector('.btn')
btn.addEventListener('click', myfunction);
.dark-mode {
filter: invert(1) hue-rotate(180deg);
}
.invert {
filter: invert(1) hue-rotate(180deg);
}
'
<button class="btn">
<img src='moon.png' alt="" />
<span>Dark mode</span>
</button>
I am following a tutorial(https://www.youtube.com/watch?v=QTHRWGn_sJw&t=119s) and I am unable to do the transition. The music-info box must pop up when the play button is clicked. The music-info has the title and the progress bar. I am very new to JS, would appreciate any help. Thank you
HTML is as
<div class="music-container" id="music-container">
<div class="music-info">
<h4 id="title">Alone
</h4>
<div class="progress-container" id="progress-container">
<div class="progress" id="progress">
</div>
</div>
</div>
<audio src="~/music/Alone.mp3" id="audio"></audio>
<div class="img-container">
<img src="~/image/Alone.jpg" alt="music-cover" id="cover" />
</div>
<div class="navigation">
<button id="prev" class="action-btn">
<i class="fas fa-backward"></i>
</button>
<button id="play" class="action-btn action-btn-big">
<i class="fas fa-play"></i>
</button>
<button id="next" class="action-btn">
<i class="fas fa-forward"></i>
</button>
</div>
</div>
CSS for the transition is as
.music-info {
background-color: rgba(255,255,255,0.5);
border-radius: 15px 15px 0 0;
position: absolute;
top: 0;
left: 20px;
padding: 10px 10px 10px 60px;
width: calc(100% - 40%);
opacity: 0;
transform: translateY(0%);
transition: transform 0.3s ease-in, opacity 0.3s ease-in;
text-align: center;
}
.music-info h4{
margin :0;
}
.music-container .play .music-info{
opacity:1;
transform: translateY(-100%);
}
.progress-container{
background:white;
border-radius: 5px;
cursor: pointer;
margin: 10px 0;
height:4px;
width:100%;
}
.progress{
background-color:#fe8daa;
border-radius:5px;
height:100%;
width:0;
transition: width 0.1s linear;
}
JS is as
function playSong() {
musicContainer.classList.add('play')
playBtn.querySelector('i.fas').classList.remove('fa-play')
playBtn.querySelector('i.fas').classList.add('fa-pause')
audio.play();
}
function pauseSong() {
musicContainer.classList.remove('play')
playBtn.querySelector('i.fas').classList.add('fa-play')
playBtn.querySelector('i.fas').classList.remove('fa-pause')
audio.pause();
}
//get duration in current time
function updateProgress(e) {
const {duration, currentTime} = e.srcElement
const progressPercent = (currentTime / duration) * 100
progress.style.width = '${progressPercent}%'
}
//pass an event object e
function setProgress(e) {
const width = this.clientWidth
const clickX = e.offsetX
alert("hi");
//console.log(clickX)
const duration = audio.duration
audio.currentTime = (clickX / width) * duration
}
//Event listeners
//play
playBtn.addEventListener('click', () => {
const isPlaying = musicContainer.classList.contains('play')
if (isPlaying) {
pauseSong()
}
else {
playSong()
}
})
//change song
prevBtn.addEventListener('click', prevSong)
nextBtn.addEventListener('click', nextSong)
audio.addEventListener('timeupdate', updateProgress)
progressContainer.addEventListener('click' , setProgress)
I found the error . It was in the
.music-container .play .music-info{
opacity:1;
transform: translateY(-100%);
}
There should not be any space between the .music-container and .play class. It should be like this
.music-container.play .music-info{
opacity:1;
transform: translateY(-100%);
}
Also I would add that ${progress-container}% should have backticks , which was a new concept for me. Otherwise the progress-container won't work.
I'm creating a portfolio website and the way I'm navigating through projects is by using "status". So for instance, if you click/scroll once, project 1 will reveal. Click/scroll a second time, project 2 will reveal. So on so forth.
<body onwheel="switchprojects()"></body>
<div class="explore-box" onClick="switchprojects()"></div>
projectStatus = 1;
function switchprojects() {
if(projectStatus==1) {
$('#bona').removeClass('float');
$('#peak').addClass('float');
projectStatus = 2;
}
else if(projectStatus==2) {
$('#peak').removeClass('float');
$('#trap').addClass('float');
projectStatus = 3;
}
else if(projectStatus==3) {
$('#trap').removeClass('float');
$('#fp').addClass('float');
projectStatus = 4;
}
else if(projectStatus==4) {
$('#fp').removeClass('float');
$('#bona').addClass('float');
projectStatus = 1;
}
}
As you can see I have two separate elements, one for scrolling and one for clicking. It's working great so far, but I'm running into one issue—the status does not update between the two elements. If I scroll twice in the body for example, the same function on the clickable div won't update its status. Does anyone know how to fix this?
Thank you!
https://codepen.io/anon/pen/qozoKj Here's the codepen.
UPDATE: I'm not sure why, but when I uploaded my code to codepen, it seems to have updated the status of the clicks....but now every key on my keyboard activates the css change. I'm very confused.
The reason all the keys are triggering switchprojects() is because you have an onkeydown="switchprojects()" on the <body>.
The reason the clicks are not listened to is that the <div class="explore-box"> has no height or width set on it although its position: absolute. Mabey you should consider changing the click event to the <div class="section"> CodePen
Try something like
$(function(){
$('#bona').addClass('float');
});
projectStatus = 1;
function switchprojects() {
if(projectStatus==1) {
$('#bona').removeClass('float');
$('#peak').addClass('float');
projectStatus = 2;
}else if(projectStatus==2) {
$('#peak').removeClass('float');
$('#trap').addClass('float');
projectStatus = 3;
}else if(projectStatus==3) {
$('#trap').removeClass('float');
$('#fp').addClass('float');
projectStatus = 4;
}else if(projectStatus==4) {
$('#fp').removeClass('float');
$('#bona').addClass('float');
projectStatus = 1;
}
}
body {
margin: 0;
padding: 0;
overflow: hidden;
}
.section {
width: 100%;
height: 100vh;
position: relative;
}
h1 {
color: white;
font-family: 'league';
font-size: 8vw;
position: absolute;
text-align: center;
line-height: 100vh;
width: 100%;
font-weight: 100;
margin: 0;
padding: 0;
transition-timing-function: cubic-bezier(0.0, 0.3, 0.5, 1);
transition: 0s;
}
.float {
transform: translate(0)!important;
transition: transform 1s;
transition-timing-function: cubic-bezier(0.0, 0.3, 0.5, 1);
opacity: 1!important;
}
.explore-box {
position: absolute;
margin-left: 55%;
margin-top: 70vh;
}
.explore-line {
background-color: white;
width: 70px;
height: 1px;
position: relative;
float: left;
margin-top: 9pt;
margin-right: 7pt;
transition-timing-function: cubic-bezier(0.0, 0.3, 0.5, 1);
transition: 0.4s;
}
.explore-wrap {
overflow: hidden;
float: right;
}
.explore-wrap h2 {
color: white;
margin: 0;
font-size: 14pt;
transform: 1s ease;
}
<script
src="https://code.jquery.com/jquery-1.12.4.min.js"
integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ="
crossorigin="anonymous"></script>
<body style="background-color: #141219;" onwheel="switchprojects()">
<div class="section">
<h1 id="bona" style="transform: translateY(10%); opacity: 0;">BONA COFFEE</h1>
<h1 id="peak" style="transform: translateY(10%); opacity: 0;">PEAK EXPLORATIONS</h1>
<h1 id="trap" style="transform: translateY(10%); opacity: 0;">TRAP MAGAZINE</h1>
<h1 id="fp" style="transform: translateY(10%); opacity: 0;">FIELD & PANTRY</h1>
<div class="explore-box" onClick="switchprojects()">
<div class="explore-line"></div>
<div class="explore-wrap">
<h2>View</h2>
</div>
<br>
<div class="explore-wrap" style="position: absolute; right: 0;">
<h2>Project</h2>
</div>
</div>
</div>
</body>
As You say I have added the click event on View Projects instead of body
I am using JavaScript to toggle notification like below.
How can I add transition between display: block and display: none;
I don't want to add an external library like jQuery because I am only going to be using the toggle effect alone.
var btn = document.querySelector('button');
btn.addEventListener('click', function(){
var hint = document.getElementById('hint');
if(hint.style.display == 'none'){
hint.style.display = 'block';
}
else{
hint.style.display = 'none';
}
});
div#hint{
background: gold;
color: orangered;
padding: .5em;
font-weight: bold;
}
<div id='hint'>
<p>This is some hint on how to be safe in this community </p>
<p>This is another hint on how to be safe in this community </p>
</div>
<button> show hint </button>
I know I can use jQuery to achieve this like below.
$(document).ready(function(){
$('button').click(function(){
$('#hint').toggle('slow');
});
});
div#hint{
background: gold;
color: orangered;
padding: .5em;
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='hint'>
<p>This is some hint on how to be safe in this community </p>
<p>This is another hint on how to be safe in this community </p>
</div>
<button> show hint </button>
Can I make the button moves up and down gradually while the #hint is being toggle like in the jQuery example above? I don't want the button to jump from one position to another.
#vothaison's suggestion: CSS transitions
Technically, #vothaison wanted to use setInterval as opposed to setTimeout, but I don't see the need for that. It's just more work.
var hint = document.getElementById('hint');
var btn = document.getElementById('btn_show');
btn.addEventListener('click', function(){
var ctr = 1;
hint.className = hint.className !== 'show' ? 'show' : 'hide';
if (hint.className === 'show') {
hint.style.display = 'block';
window.setTimeout(function(){
hint.style.opacity = 1;
hint.style.transform = 'scale(1)';
},0);
}
if (hint.className === 'hide') {
hint.style.opacity = 0;
hint.style.transform = 'scale(0)';
window.setTimeout(function(){
hint.style.display = 'none';
},700); // timed to match animation-duration
}
});
#hint {
background: yellow;
color: red;
padding: 16px;
margin-bottom: 10px;
opacity: 0;
transform: scale(0);
transition: .6s ease opacity,.6s ease transform;
}
<div id="hint" style="display: none;">
<p>This is some hint on how to be safe in this community </p>
<p>This is another hint on how to be safe in this community </p>
</div>
<button id="btn_show"> Show hint </button>
Using CSS animations
var hint = document.getElementById('hint');
var btn = document.getElementById('btn_show');
btn.addEventListener('click', function(){
hint.className = hint.className !== 'show' ? 'show' : 'hide';
if (hint.className === 'show') {
setTimeout(function(){
hint.style.display = 'block';
},0); // timed to occur immediately
}
if (hint.className === 'hide') {
setTimeout(function(){
hint.style.display = 'none';
},700); // timed to match animation-duration
}
});
#-webkit-keyframes in {
0% { -webkit-transform: scale(0) rotate(12deg); opacity: 0; visibility: hidden; }
100% { -webkit-transform: scale(1) rotate(0); opacity: 1; visibility: visible; }
}
#keyframes in {
0% { transform: scale(0) rotate(12deg); opacity: 0; visibility: hidden; }
100% { transform: scale(1) rotate(0); opacity: 1; visibility: visible; }
}
#-webkit-keyframes out {
0% { -webkit-transform: scale(1) rotate(0); opacity: 1; visibility: visible; }
100% { -webkit-transform: scale(0) rotate(-12deg); opacity: 0; visibility: hidden; }
}
#keyframes out {
0% { transform: scale(1) rotate(0); opacity: 1; visibility: visible; }
100% { transform: scale(0) rotate(-12deg); opacity: 0; visibility: hidden; }
}
#hint {
background: yellow;
color: red;
padding: 16px;
margin-bottom: 10px;
}
#hint.show {
-webkit-animation: in 700ms ease both;
animation: in 700ms ease both;
}
#hint.hide {
-webkit-animation: out 700ms ease both;
animation: out 700ms ease both;
}
<div id="hint" style="display: none;">
<p>This is some hint on how to be safe in this community </p>
<p>This is another hint on how to be safe in this community </p>
</div>
<button id="btn_show"> Show hint </button>
Using vanilla JavaScript
There are many, many ways to do this sort of thing with vanilla JavaScript, so here's a quick sketch of one way:
// you may need to polyfill requestAnimationFrame
var hint = document.getElementById('hint');
var btn = document.getElementById('btn_show');
btn.addEventListener('click', function(){
var ctr = 0;
hint.className = hint.className !== 'show' ? 'show' : 'hide';
if (hint.className === 'show') {
window.setTimeout(function(){
hint.style.display = 'block';
fadein();
},0); // do this asap
}
if (hint.className === 'hide') {
fadeout();
window.setTimeout(function(){
hint.style.display = 'none';
},700); // time this to fit the animation
}
function fadein(){
hint.style.opacity = ctr !== 10 ? '0.'+ctr : 1;
hint.style.transform = ctr !== 10 ? 'scale('+('0.'+ctr)+')' : 'scale(1)';
ctr++;
if (ctr < 11)
requestAnimationFrame(fadein);
else
ctr = 0;
}
function fadeout(){
hint.style.opacity = 1 - ('0.'+ctr);
hint.style.transform = 'scale('+(1 - ('0.'+ctr))+')';
ctr++;
if (ctr < 10)
requestAnimationFrame(fadeout);
else
ctr = 0;
}
});
#hint {
background: yellow;
color: red;
padding: 16px;
margin-bottom: 10px;
opacity: 0;
}
<div id="hint" style="display: none;">
<p>This is some hint on how to be safe in this community </p>
<p>This is another hint on how to be safe in this community </p>
</div>
<button id="btn_show"> Show hint </button>
Say what you want about GreenSock, Velocity.js, jQuery, etc — they all trivialise this process of showing and hiding of things. Why not just borrow the show and hide functions from jQuery's source code?
see my example below:
var btn = document.querySelector('button');
var hint = document.getElementById('hint');
var height = hint.clientHeight;
var width = hint.clientWidth;
console.log(width + 'x' + height);
// initialize them (within hint.style)
hint.style.height = height + 'px';
hint.style.width = width + 'px';
btn.addEventListener('click', function(){
if(hint.style.visibility == 'hidden'){
hint.style.visibility = 'visible';
//hint.style.opacity = '1';
hint.style.height = height + 'px';
hint.style.width = width + 'px';
hint.style.padding = '.5em';
}
else{
hint.style.visibility = 'hidden';
//hint.style.opacity = '0';
hint.style.height = '0';
hint.style.width = '0';
hint.style.padding = '0';
}
});
div#hint{
background: gold;
color: orangered;
padding: .5em;
box-sizing: border-box;
overflow: hidden;
font-weight: bold;
transition: height 1s, width 1s, padding 1s, visibility 1s, opacity 0.5s ease-out;
}
<div id='hint'>
<p>This is some hint on how to be safe in this community </p>
<p>This is another hint on how to be safe in this community </p>
</div>
<button> show hint </button>
Hi I dont use display: block to display:none but changing the opacity, height and padding instead
please review this one:
var btn = document.querySelector('button');
btn.addEventListener('click', function() {
var hint = document.getElementById('hint');
if (hint.classList.contains('h-hide')) {
hint.classList.remove('h-hide');
} else {
hint.classList.add('h-hide');
}
});
div#hint {
display: block;
background: gold;
color: orangered;
padding: .5em;
font-weight: bold;
transition: .5s all linear;
opacity: 1;
overflow: hidden;
height: 100px;
}
#hint.h-hide {
padding: 0;
opacity: .25;
height: 0;
}
<div id='hint'>
<p>This is some hint on how to be safe in this community</p>
<p>This is another hint on how to be safe in this community</p>
</div>
<button>show hint</button>
the drawback for this approach is we have to keep tract of the div#hint height and change it using javascript if needed.
var btn = document.querySelector('button');
btn.addEventListener('click', function(){
var hint = document.getElementById('hint');
if(hint.style.visibility == 'hidden'){
hint.style.visibility = 'visible';
hint.style.opacity = '1';
}
else{
hint.style.visibility = 'hidden';
hint.style.opacity = '0';
}
});
div#hint{
background: gold;
color: orangered;
padding: .5em;
font-weight: bold;
transition: visibility 1s, opacity 0.5s linear;
}
<div id='hint'>
<p>This is some hint on how to be safe in this community </p>
<p>This is another hint on how to be safe in this community </p>
</div>
<button> show hint </button>
I think using visibility over display is better option
Without using css3 transition, you can use js setInterval to change some css property of the div, such as:
Change opacity from 0 to 1
Change height from 0 to full height
Change width from 0 to full width
Initially, you should have display: none; opacity: 0; height: 0; width: 0'
Then you have to change display: none to display: block; before you use setInterval to change other properties.
(I guess you know how to hide the div)
You can also use setTimeout(), with a trick of recursive.
Try something like this:
var btn = document.querySelector('button');
btn.addEventListener('click', function(){
var hint = document.getElementById('hint');
hint.classList.toggle("hide");
});
.hint{
background: gold;
color: orangered;
padding: .5em;
font-weight: bold;
visibility: visible;
opacity: 1;
max-height: 500px;
transition: visibility 0s, opacity 0.3s, max-height 0.6s linear;
}
.hide {
visibility: hidden;
opacity: 0;
max-height: 0px;
transition: max-height 0.3s, opacity 0.3s, visibility 0.3s linear;
}
<div id='hint' class="hint">
<p>This is some hint on how to be safe in this community </p>
<p>This is another hint on how to be safe in this community </p>
</div>
<button> show hint </button>
I have also tried to do this
please have a look if it can help you
var btn = document.querySelector('button');
var hint = document.getElementById('hint');
hint.style.opacity = 1;
hint.style.transition = "opacity 1s";
btn.addEventListener('click', function(){
if(hint.style.opacity == 0 || hint.style.opacity==''){
hint.style.opacity = 1;
}
else{
hint.style.opacity = 0;
}
});
let redBox = document.getElementById('redBox');
let blueBox = document.getElementById('blueBox');
let [redButton, blueButton] = document.querySelectorAll('button'); //Destructuring
redButton.addEventListener('click', () => {
smoothDisplayNone(redBox);
});
blueButton.addEventListener('click', () => {
smoothDisplayNone(blueBox);
});
//By using smoothDisplayNone() function, you can add this effect to whatever element you want.
function smoothDisplayNone(selectedElement){
if(!selectedElement.classList.contains('animationDisplayNone')){
selectedElement.classList.add('animationDisplayNone');
selectedElement.classList.remove('animationDisplayBlock');
}
else{
selectedElement.classList.remove('animationDisplayNone');
selectedElement.classList.add('animationDisplayBlock');
}
}
#redBox{
width: 200px;
height: 200px;
background-color: red;
}
#blueBox{
width: 200px;
height: 200px;
background-color: blue;
}
.animationDisplayNone{
animation: smoothDisplayNone 0.5s linear forwards;
}
.animationDisplayBlock{
animation: smoothDisplayBlock 0.5s linear forwards;
}
/*You should set the width and height according to the size of your element*/
#keyframes smoothDisplayBlock{
0% { opacity: 0; width: 0px; height: 0px; }
25% { opacity: 0.25; }
50% { opacity: 0.50; }
75% { opacity: 0.75; }
100% { opacity: 1; width: 200px; height: 200px; }
}
#keyframes smoothDisplayNone {
0% { opacity: 1; width: 200px; height: 200px; }
25% { opacity: 0.75; }
50% { opacity: 0.50; }
75% { opacity: 0.25; }
100% { opacity: 0; width: 0px; height: 0px; }
}
<div id="redBox"></div>
<div id="blueBox"></div>
<button type="button" style="margin-top:10px;">Red</button>
<button type="button" style="margin-top:10px;">Blue</button>
The code looks long at first glance but it is actually very simple to understand. I used the power of css animation to create a smooth effect.
You can use smoothDisplayNone() function easily.