I am trying to create a foldable menu, through CSS and JS. Css works (almost) correctly (the menu folds and unfolds, even if the class is not correctly applied) but not the JS code, which should change the innerText of the <li> acting as a button from ">" to "<" and opposite.
I have been messing around with js code for a while (making sure that document.getElementById is not undefined), but neither element.innerText or element.innerHTML seem to work properly.
I have two questions:
When applying an animation, and having two classes, shouldn't respect both classes (I mean, the navbar should be red)? Should I add nav class AFTER the animation is done, or fill the navbar in red color through the animation?
Why does ignore InnerText/InnerHTML instructions?? I have debugged the code and definitely goes through that instruction and I cannot understand why the change is not done...
var navButton;
var navbar;
const init = ()=>{
navbar = document.getElementById("navbar");
navButton = document.getElementById("foldButton");
navButton.addEventListener('click', function(){
if(navbar.className==="init nav" || navbar.className==="fade-out-right nav"){
navButton.InnerText=`<p><</p>`;
toggleFold();
}
else{
navButton.InnerText=`<p>></p>`;
toggleFold();
}
});
}
const toggleFold = () => {
if(navbar.className==="init nav" || navbar.className==="fade-out-right nav"){
navbar.className="fade-in-left nav";
}else{
navbar.className="fade-out-right nav";
}
};
* {
margin: 0;
padding: 0;
}
html {
box-sizing: border-box;
font-size: 62.5%;
scroll-behavior: smooth;
}
/* Base styles */
.nav {
display: flex;
justify-content: flex-end;
position: fixed;
top: 0;
left: 0;
width: 4%;
background: red;
box-shadow: 0 2px 0 rgba(0, 0, 0, 0.4);
z-index: 10;
}
.nav-list {
display: flex;
margin-right: 2rem;
list-style: none;
}
.nav-list li {
display: block;
font-size: 2.2rem;
padding: 2rem;
}
.nav-list a{
color:black
}
.nav-list a:hover {
background: blue;
}
.fade-in-left {
animation-name: fade-in-left;
animation-duration: 2s;
animation-timing-function: ease;
animation-fill-mode: forwards;
}
#keyframes fade-in-left {
from {
opacity: 1;
transform: translateX(-4%);
}
to {
opacity: 1;
transform: translateX(305px);
}
}
.fade-out-right {
animation-name: fade-out-right;
animation-duration: 2s;
animation-timing-function: ease;
animation-fill-mode: forwards;
}
#keyframes fade-out-right {
from {
opacity: 1;
transform: translateX(305px);
}
to {
opacity: 1;
transform: translateX(-4%);
}
}
<body onload="init()">
<nav id="navbar" class="init nav">
<ul class='nav-list'>
<li><a href='#welcome-section'>About</a></li>
<li><a href='#projects'>Work</a></li>
<li><a href='#contact'>Contact</a></li>
<li id="foldButton"><p>></p></li>
</ul>
</nav>
</body>
Thank you for helping me out.
Apart from my low IQ for the bad typo, whenever the color is not filled when using an animation, use internal container instead (in my case, I filled ul instead of navbar).
I'm using below script to show loading gif while the file is ready to download and then Once it is done , it hides after couple of seconds.
But I Only want to dowanload the file once, but when I click the link it download the same file twice. I found the code somewhere in forums, so I really don't know how to prevent it from running the url twice.
$(".file a").on("click",function(e){
var originalHtml=$(this).html();
$(this).html('<div class="load-container load8"><div class="loader">Loading...</div></div>'); // do your UI thing here
e.preventDefault();
var destination = this.href;
var clickedLink=$(this);
setTimeout(function() {
clickedLink.html(originalHtml);
window.location = destination;
},2500);
$('<iframe>').hide().appendTo('body').load(function() {
window.location =sagar;
}).attr('sagar', sagar);
});
.loader,
.loader:before,
.loader:after {
border-radius: 50%;
width: 2.5em;
height: 2.5em;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
-webkit-animation: load7 1.8s infinite ease-in-out;
animation: load7 1.8s infinite ease-in-out;
}
.loader {
color: darkblue;
font-size: 10px;
margin: 80px auto;
position: relative;
text-indent: -9999em;
-webkit-transform: translateZ(0);
-ms-transform: translateZ(0);
transform: translateZ(0);
-webkit-animation-delay: -0.16s;
animation-delay: -0.16s;
}
.loader:before,
.loader:after {
content: '';
position: absolute;
top: 0;
}
.loader:before {
left: -3.5em;
-webkit-animation-delay: -0.32s;
animation-delay: -0.32s;
}
.loader:after {
left: 3.5em;
}
#-webkit-keyframes load7 {
0%,
80%,
100% {
box-shadow: 0 2.5em 0 -1.3em;
}
40% {
box-shadow: 0 2.5em 0 0;
}
}
#keyframes load7 {
0%,
80%,
100% {
box-shadow: 0 2.5em 0 -1.3em;
}
40% {
box-shadow: 0 2.5em 0 0;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body style="color: black; background-color: #EFF6E4;font-family: myFirstFont; ">
<ol class="tree">
<li>
<label for="folder1">First Semester</label> <input type="checkbox" id="folder1" />
<ol>
<li>
<label for="subfolder11">Classical Mechanics </label> <input type="checkbox" id="subfolder11" />
<ol>
<li class="file">Solutions_to_Problems_in_Goldstein)</li>
<li class="file">Goldstein Solution Chapter 8 Soln</li>
<li class="file">Goldstein Chapter 9 Soln</li>
<li class="file">Numericals Jacobi Angle ( Hints )</li>
<li class="file">Angle Jacobi Numericals ( Complete Solution)</li>
</ol>
</li>
</ol>
</li>
</ol>
</body>
Any help would be really appreciated.
It seems you are calling window.location = destination; (which is triggering the browser to download the file) twice, inside that setTimeout function and after a hidden iframe is loaded, which I think is the correct place.
Just stop calling setTimeout like below:
$(".file a").on("click",function(e){
var originalHtml=$(this).html();
$(this).html('<div class="load-container load8"><div class="loader">Loading...</div></div>'); // do your UI thing here
e.preventDefault();
var destination = this.href;
var clickedLink=$(this);
$('<iframe>').hide().appendTo('body').load(function() {
window.location = destination;
clickedLink.html(originalHtml);
}).attr('src', destination);
});
I have problem with finding the right position of click. I want to make google material design - ripple effect on clicked button. Circle need to be on button not somewhere else. So when you click on button white circle is showing somewhere else not above the wanted button. Where is the mistake i made?
$(function () {
var btnClick, bWidth, bHeight, x, y, posX, posY,d;
$(".btn").click(function (e) {
e.preventDefault();
posX = $(this).offset().left;
posY = $(this).offset().top;
bWidth = $(this).outerWidth();
bHeight = $(this).outerHeight();
d = Math.max(bWidth, bHeight);
$(".btn-over").remove();
if ($(this).find(".btn-over").length === 0) {
$(this).prepend("<span class='btn-over'></span>");
}
// btnClick = $(this).children(".btn-over");
// btnClick.removeClass("animation");
// if (!btnClick.height() && !btnClick.width()) {
// d = Math.max($(this).outerWidth(), $(this).outerHeight());
// btnClick.css({
// height: d,
// width: d
// });
// }
x = e.pageX - posX - bWidth / 2;
y = e.pageY - posY - bHeight /2;
$(".btn-over").css({
width: d,
height: d,
top: y + 'px',
left: x + 'px'
}).addClass("animation");
});
});
nav {
height: 3rem;
background-color: #424242;
color: #fff; }
.menu {
list-style: none;
float: right; }
.menu li {
display: inline-block; }
.btn-sigup {
box-shadow: none;
background-color: #4CAF50; }
.btn-sigup:hover {
background-color: #66BB6A;
box-shadow: none; }
.btn-login {
box-shadow: none;
background-color: transparent; }
.btn-login:hover {
box-shadow: none;
background-color: transparent; }
.btn-over {
display: inline-block;
position: absolute;
background: rgba(255, 255, 255, 0.3);
border-radius: 100%;
-webkit-transform: scale(0);
-moz-transform: scale(0);
-o-transform: scale(0);
transform: scale(0); }
.animation {
-webkit-animation: ripple 0.65s linear;
-moz-animation: ripple 0.65s linear;
-ms-animation: ripple 0.65s linear;
-o-animation: ripple 0.65s linear;
animation: ripple 0.65s linear; }
#-webkit-keyframes ripple {
100% {
opacity: 0;
-webkit-transform: scale(2.5); } }
#-moz-keyframes ripple {
100% {
opacity: 0;
-moz-transform: scale(2.5); } }
#-o-keyframes ripple {
100% {
opacity: 0;
-o-transform: scale(2.5); } }
#keyframes ripple {
100% {
opacity: 0;
transform: scale(2.5); } }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<header>
<nav>
<ul class="menu">
<li>
<button class="btn btn-login">LOG IN</button>
</li>
<li>
<button class="btn btn-sigup">SING UP</button>
</li>
</ul>
</nav>
</header>
There's nothing wrong with your JavaScript, you just need to set the position of the buttons to relative so that the positioning of the .btn-over span is contained within them. You should also consider setting the overflow of the buttons to hidden so that the "ripple" doesn't spill out of them.
$(function(){
var btnClick,bWidth,bHeight,x,y,posX,posY,d;
$(".btn").click(function(e){
e.preventDefault();
posX=$(this).offset().left;
posY=$(this).offset().top;
bWidth=$(this).outerWidth();
bHeight=$(this).outerHeight();
d=Math.max(bWidth,bHeight);
$(".btn-over").remove();
if($(this).find(".btn-over").length===0)
$(this).prepend("<span class=\"btn-over\"></span>");
x=e.pageX-posX-bWidth/2;
y=e.pageY-posY-bHeight/2;
$(".btn-over").css({
width:d+"px",
height:d+"px",
top:y+"px",
left:x+"px"
}).addClass("animation");
});
});
nav{
background-color:#424242;
color:#fff;
height:3rem;
}
.menu{
float:right;
list-style:none;
}
.menu li{
display:inline-block;
}
.btn-sigup{
background-color:#4CAF50;
overflow:hidden;
position:relative;
}
.btn-sigup:hover{
background-color:#66BB6A;
}
.btn-login{
background-color:transparent;
overflow:hidden;
position:relative;
}
.btn-over{
background:rgba(255, 255, 255, 0.3);
border-radius:50%;
display:inline-block;
position:absolute;
transform:scale(0);
}
.animation{
animation:ripple .65s linear;
}
#keyframes ripple{
to{
opacity:0;
transform:scale(2.5);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>
<nav>
<ul class="menu">
<li>
<button class="btn btn-login">LOG IN</button>
</li>
<li>
<button class="btn btn-sigup">SING UP</button>
</li>
</ul>
</nav>
</header>
And here' an alternative implementation, with some extra features, that you can use on any element you wish. To implement it, you'll need to copy the JavaSript and the important stuff from the CSS and then you just give any element you want to apply this effect to a data-ripple-color attribute, which takes a value of any valid CSS color.
To apply this effect to an element every time it is clicked without waiting for the previous animation to complete add a data-ripple-multiple attribute to it with a value of true. See the button element below for an example.
(function(){
if(document.querySelector("[data-ripple-color]")){
var span=document.createElement("span");
span.classList.add("ripple");
document.addEventListener("click",function(event){
var target=event.target,color,data,multi,node,style;
while(!target.dataset.rippleColor&&target!==document.body)
target=target.parentNode;
data=target.dataset;
multi=data.rippleMultiple;
if((color=data.rippleColor)&&(multi||!data.rippleWait)){
if(!multi)data.rippleWait="true";
target.appendChild(node=span.cloneNode(0));
style=node.style;
style.background=color;
style.height=style.width=Math.min(target.offsetHeight,target.offsetWidth)+"px";
style.left=event.pageX-target.offsetLeft+"px";
style.top=event.pageY-target.offsetTop+"px";
setTimeout(function(){
target.removeChild(node);
if(!multi)delete data.rippleWait;
},750);
}
},0);
}
})();
/* Housekeeping */#import url(https://fonts.googleapis.com/css?family=Roboto:400,300,500,700,900);*,*::before,*::after{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;background-clip:padding-box;border:0;border-radius:0;box-sizing:border-box;color:rgba(0,0,0,.87);font-family:Roboto,arial,sans-serif;font-size:14px;-webkit-font-smoothing:antialiased;font-style:normal;font-weight:500;line-height:1.2em;list-style:none;margin:0;outline:0;padding:0;-webkit-tap-highlight-color:rgba(0,0,0,0);text-align:left;text-decoration:none;text-indent:0;text-rendering:auto;transition-duration:.2s;transition-property:none;transition-timing-function:cubic-bezier(.4,0,.2,1);}*>*{font-size:inherit;font-style:inherit;font-weight:inherit;}*>*,*::before,*::after{color:inherit;font-family:inherit;line-height:inherit;}
/* The important stuff */
[data-ripple-color]{
overflow:hidden;
position:relative;
}
.ripple{
animation:ripple 1s cubic-bezier(.4,0,.2,1);
border-radius:50%;
display:block;
opacity:0;
position:absolute;
}
#keyframes ripple{
from{
transform:translate(-50%,-50%) scale(1);
opacity:.54;
}to{
transform:translate(-50%,-50%) scale(54);
opacity:0;
}
}
/* Fiddle styles */
a[data-ripple-color],button[data-ripple-color]{
border-radius:3px;
cursor:pointer;
display:block;
font-size:24px;
font-weight:500;
line-height:40px;
margin:0 auto 8px;
padding:8px;
text-align:center;
width:200px;
}
a[data-ripple-color]{
background:#F44336;
color:#fff;
}
button[data-ripple-color]{
background:#3f51b5;
color:#fff;
font-size:24px;
line-height:40px;
padding:8px;
text-align:center;
text-transform:uppercase;
width:200px;
}
figure[data-ripple-color]{
border-radius:3px;
margin:0 auto 8px;
width:200px;
}
p[data-ripple-color]{
line-height:20px;
margin:0 8px 8px;
padding:8px;
}
<button data-ripple-color="#fff" data-ripple-multiple="true">Button</button>
<a data-ripple-color="#303f9f">Link</a>
<figure data-ripple-color="rgb(0,0,0)"><img src="http://placehold.it/200x200.png/e0e0e0?text=Image+%0A+Parent"></figure>
<p data-ripple-color="#616161">Paragrpah</p>
Basically I am working on website similar to http://keepearthquakesweird.com/.
I am not good in jQuery except the basic stuff but have created the layout in html5 and css3. The problem I am having is if you see on the website after clicking the enter link it takes you to a grid.I have created exact grid and able to pull up various div content when user clicks on various links by the following approach (you can see my code below) using css3 + jquery. So the question is that is there a better approach for pulling up the divs when user click on the link. the main question is I need the next previous button as in the website mentioned when you click any alphabet, so you can navigate through the description divs.
Looking for some honest advice and solution :)
$('a#alpha').click(function(e) {
e.preventDefault();
var id = $(this).attr('data-id');
$("#container > div").each(function() {
if ($(this).attr('data-id') == id) {
$(this).toggleClass('show-content');
}
});
});
$("a#cls").click(function() {
$("#container > div").each(function() {
if ($(this).hasClass('show-content')) {
$(this).removeClass('show-content');
}
})
})
#container div {
width: 100%;
min-height: 100%;
position: absolute;
top: 0;
transform: translateY(100%);
-webkit-transform: -webkit-translateY(100%);
-moz-transform: -moz-translateY(100%);
-o-transform: -o-translateY(100%);
transition: .4s ease-in all;
-webkit-transition: .4s ease-in all;
-moz-transition: .4s ease-in all;
z-index: 6;
opacity: 1;
}
.closeBtn {
position: fixed;
top: 20px;
right: 20px;
font-size: 30px;
color: #fff;
}
#content-1 {
background: #333;
}
#content-2 {
background: #ff0;
}
#content-3 {
background: #f00;
}
.show-content {
opacity: 1 !important;
z-index: 5 !important;
transform: translateY(0%) !important;
-webkit-transform: -webkit-translateY(0%) !important;
-moz-transform: -moz-translateY(0%) !important;
-o-transform: -o-translateY(0%) !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>
Link to pull div
</li>
<li>
Link to pull div
</li>
<li>
Link to pull div
</li>
</ul>
<div id="container">
<div id="content-1" data-id="01">
X
<h1>TITLE</h1>
</div>
<div id="content-2" data-id="02">
X
<h1>TITLE</h1>
</div>
<div id="content-3" data-id="03">
X
<h1>TITLE</h1>
</div>
</div>
i am trying to make "memory game" using html5, CSS3 and JS. I have completed the view and model part of this game and now trying to make the Controller. What i want is call a function i.e. flip in JS and want that function to perform transition instead of using hover effect of CSS3. Basically i am trying to follow this approach. I checked that flipping in css3 using hover as can be seen in sass code below, but for the game, the user decides where to click. For simplicity, i have concised the code in html5 since it repeats for all other divs.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>I Don't Know</title>
<link rel="stylesheet" href="trapStyle.css">
</head>
<body>
<div class = "container" >
<div class="sub1" >
<div class="front" id="card1" onclick="flip(card1)">card1</div>
<div class="back" id="card1_1">what the hell?</div>
</div> <--sub1 Ends-->
<div class="sub1">
<div class="front" id="card2" onclick="flip(this)">card2</div>
<div class="back" id="card2_2">what the hell?
</div> <--sub1 Ends-->
</div> <-- container Ends -->
<script src ="script.js"></script>
</body>
</html>
and the SASS code for css
.container {
position: absolute;
left: 115px;
width: 1150px;
height: 700px;
background-color: silver;
/* SUB-CONTAINER to stack two cards */
.sub1 {
width: 200px; height: 200px;
float:left; margin: 5px;
.front {
position:absolute; width: 200px; height: 200px;
background-color: #498010;
transform: perspective( 600px) rotateY(0deg);
backface-visibility: hidden;
transition: transform 0.5s linear 0s;
}
.back {
position: absolute; width: 200px; height: 200px;
float:left; background-color: #689;
transform: perspective( 600px) rotateY(180deg);
backface-visibility: hidden;
transition: transform 0.5s linear 0s;
}
}
.sub1:hover > .front {
/* transform: perspective(600px) rotateY(-180deg); */
}
.sub1:hover > .back {
/* transform: perspective(600px) rotateY(0deg); */
}
}
and JavaScript
function flip(front) {
document.getElementById("front").style.transition = opacity 0.5s linear 0s;
document.getElementById("front").style.opacity = 0;
}
Note: the link, above, is trying to pass id to JS function where the transition takes place. Exactly same is being done here, just to get input from user instead of just hovering, but nothing happens! I copy/pasted the link code in my editor and smooth transitions are performed but when it comes of my code, nothing! Could you tell me where is my flaw?
Change your CSS from the hover state to a class, for iunstance change .sub1:hover to .hovered:
.container .hovered > .front {
transform: perspective(600px) rotateY(-180deg); }
.container .hovered > .back {
transform: perspective(600px) rotateY(0deg); }
And now, on click, add this class to the element clicked:
$(".sub1").click(function() {
$(this).addClass ('hovered');
})
fiddle
this function in javascript would be
function change(element) {
element.className = element.className + " hovered";
}
provided that you send the element in the function call
onclick="change(this)"
fiddle - function set only in the first div