How can I simplify my js code for css animation? - javascript

I made CSS animations and buttons to play the animations and use add and remove classes to play each motion. I didn't use a toggle because if I use a toggle, it mixes with other buttons.
I've seen many CSS animations that didn't use js at all.
Is there any way to reduce my js code and simplify it?
Here is the code-
playbtn.addEventListener("click", function (e) {
e.preventDefault;
ball.style.display = "block";
bowl.style.display = "none";
ball.classList.remove("ball-move");
ball.offsetWidth = ball.offsetWidth;
ball.classList.add("ball-move");
document.getElementById('dFace').className = '';
dFace.offsetWidth = dFace.offsetWidth;
dFace.classList.add("p-head-move");
document.getElementById('ear').className = '';
ear.offsetWidth = ear.offsetWidth;
ear.classList.add("lean");
document.getElementById("mouthid").className = '';
mouth.offsetWidth = mouth.offsetWidth;
mouth.classList.add("mouth-move");
}, false);

I think you have to read about Animation play state api, that will reduce your code.
Doc Link!

1, From your code, I assume that bowl, ball, dFace, ear and mouth are all HTMElement that have already assigned with a value from document.getElementById. So, you may not have to get the HTMLElement again in this functions.
2, You may not need to assign the value for offsetWidth as it is a read-only property as described in https://www.w3schools.com/jsref/prop_element_offsetwidth.asp. You can remove those lines.
You might be missing () for e.preventDefault
I will suggest the followings:
playbtn.addEventListener("click", function (e) {
e.preventDefault();
ball.style.display = "block";
bowl.style.display = "none";
ball.classList.remove("ball-move");
ball.classList.add("ball-move");
dFace.className = '';
dFace.classList.add("p-head-move");
ear.className = '';
ear.classList.add("lean");
mouth.className = '';
mouth.classList.add("mouth-move");
}, false);
Also, the action on dFace, ear and mouth are similar, so you may wrap it in a function call restartAnimation to further reduce duplications of your code.
const restartAnimation = (ele, className) => {
ele.className = '';
ele.classList.add(className);
}
playbtn.addEventListener("click", function (e) {
e.preventDefault();
ball.style.display = "block";
bowl.style.display = "none";
ball.classList.remove("ball-move");
ball.classList.add("ball-move");
restartAnimation(dFace, "p-head-move")
restartAnimation(ear, "lean")
restartAnimation(mouth, "mouth-move")
}, false);

You should include your CSS in your post as well! But I think you could avoid the restartAnimation instances you have by using animation-iteration-count: infinite; (if you are trying to make your animations loop, for example) in the CSS selector for the animated parts. I would recommend looking into the CSS animation documentation here as it's very clear! Good luck!

Related

How to set a JS variable from a CSS style

I've made a bunch of JavaScript functions to show, hide and populate various elements on a zooming menu. All seem to working except for one which I need the function to only run if a CSS setting is a specific value (width of 195%). I am very new to JavaScript so there may be more than one issue here.
<script>
function zoomShowF2() {
var widthNow = document.getElementById('svg1').style.width;
if widthNow = '195%' {
document.getElementById('zoomTitle').style.display = 'flex';
else
document.getElementById('zoomTitle').style.display = 'none';
}}</script>
You need to use comparison operators write the if statement as follows
if (widthNow == '195%') {
as the single = is assigning the value not comparing it
There are a few issues with your syntax:
function zoomShowF2() {
var widthNow = document.getElementById('svg1').style.width;
if (widthNow === '195%') {
document.getElementById('zoomTitle').style.display = 'flex';
} else {
document.getElementById('zoomTitle').style.display = 'none';
}
}
Thanks everyone. It works now with a combination of the changes suggested. I assume my curly braces are all in 'tidy' positions?
EDIT. I've adjusted the curly brace positions to as per Ed's layout.
Thanks all!
Your code does not called when the element changes it size or width. You must put all your code inside window.onresize event.
var displayOutput = document.getElementById("display-option");
function reportWindowSize() {
displayOutput.text = document.getElementById("element-to-check").style.width;
}
window.onresize = reportWindowSize;
<p id="element-to-check">Resize the browser window to fire the <code>resize</code> event.</p>
<p>Display: <span id="display-option"></span></p>

How to make div disappear after clicking the button? [duplicate]

This question already has answers here:
Show/Hide Requires a Double-click
(2 answers)
Closed 2 years ago.
Like in the topic. After clicking empty gear (norm) I want to make it change to filled (hov) and show up div (show), but it doesn't work.
Before using ifs everything was working, so there must be something wrong with them.
js:
function list() {
if (document.getElementById('hov').style.display === 'none') {
document.getElementById('norm').style.display = 'none';
document.getElementById('hov').style.display = 'flex';
document.getElementById('show').style.display = 'grid';
}
if (document.getElementById('hov').style.display === 'flex') {
document.getElementById('norm').style.display = 'flex';
document.getElementById('hov').style.display = 'none';
document.getElementById('show').style.display = 'none';
}
}
html:
<button class="men" onclick="list()"><img id="norm" src="img/gearw.png" height="28px"><img id="hov" src="img/gearwhover.png" height="28px"></button>
Did you write link to JQuery?
write <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> into the end of the body, but before body. If it doesn't work, sorry( I can't give another advice
I think you have a bit of a misunderstanding of what display does (you can read up on it here: https://www.w3schools.com/cssref/pr_class_display.asp). Setting it to none won't make it invisible. Instead, you could use visibility.
For example:
function list() {
var norm = document.getElementById("norm");
var hov = document.getElementById("hov");
if (hov.style.visibility === "hidden") {
norm.style.visibility = "hidden";
hov .style.visibility = "visible";
} else if (hov.style.visibility === "visible") {
norm.style.visibility = "visible";
hov .style.visibility = "hidden";
}
}
<button class = "men" onclick = "list()">
<img id = "norm" src = "img/gearw.png" height = "28px">
<img id = "hov" src = "img/gearwhover.png" height = "28px" style = "visibility: hidden">
</button>
Other than that, your code seems very weird (your JS talks about a "show" element that's not in your HTML document?), and its not quite clear from the question what you're trying to accomplish. There probably is a much more elegant way to do what you want, but without telling us, we can't know.
If I were to guess, I'd say that you were trying to make the image on the button change when the user hovers over it, in which case you'd probably be better off using CSS for that, but again I can't know for sure.
Anyways, I wish you the best of luck in your project!

javascript/htmlDOM display element while hiding the others

So I have written this clickDisplay function that displays certain elements on click, it works fine, yes, but obviously I needed a feature that would hide all the other elements, because they are supposed to be displayed in the same field, so right now they kind stack on top of eachother
this is what I came up with, but it sorta doesn't work and I don't know why
const pages = ['watch','chars','seasons','songs']
function clickHide(element){
document.getElementById(element).style.display = 'none';
}
function clickDisplay(element){
document.getElementById(element).style.display = 'block';
for(let x = 0 ; x < pages.length ; x++){
if (pages[x]!=element){clickHide(pages[x]);}
}
}
While it sounds like you solved your own problem, I started putting together code before you posted, so I'll throw it up here for you. :)
const pages = ['watch', 'chars', 'seasons', 'songs']
function clickHide (el) {
pages.forEach((pel) => {
setElement(pel, pel === el ? 'none' : 'block')
})
}
function setElement(el, attr) {
document.getElementById(el).style.display = attr
}
with the html having this:
onclick="clickHide('watch')" // or 'chars' 'seasons' or 'songs'
Oh wait, I don't know why but this suddenly works now. I only changed the placeholder text and refreshed the page
But I'm sure that this still is a stupid solution

turning CSS on / off globally

My goal is to have a button (controlled by a javascript function) that would toggle the entire CSS on the website on and off. I thought this was a common practice and was surprised when I couldn't find a complete solution here or on the web.
Here is what I got.
$("#button").click(function() {
var css = (document.styleSheets[0].enabled = true);
if (css == true)
{
document.styleSheets[0].disabled = true;
css = (document.styleSheets[0].enabled = false);
}
else if (css == false)
{
document.styleSheets[0].disabled = false;
}
});
A simple Jquery function that targets the button by ID and performs an if test. I could've ommited the variable, but this way I am able to check the value easily in console.log. I am able to turn the CSS off, but not back on. The program doesn't even get to the else condition.
I am aware that the else if is not really appropriate, but with just else (and even just with another if condition) the function doesn't run at all.
Second option that I thought of, and which might be much easier is just dynamically changing the contents of the link href attribute, where the path to the css file is given.
But I am struggling to target the href element with Javascript.
This is a simple Boolean toggle so write it as a simple toggle
$("#button").click(function() {
var sheet = document.styleSheets[0];
sheet.disabled = !sheet.disabled;
});
As for why your code isn't working as is,
var css = (document.styleSheets[0].enabled = true);
// same as
var css;
document.styleSheets[0].enabled = true;
css = true;
which means
if (css == true)
// same as
if (true == true)
which always holds so you'll always follow this code path
Well, for one you need to loop through all of the stylesheets.
Also, you can save some lines of code by using a counter, then on each button click increment the counter and use the % modulo operator to turn that into a 1 or a 0, which you can then coerce a boolean from using !!.
var count = 0;
var sheets = document.styleSheets;
$("#button").click(function() {
for(var i in Object.keys(sheets)) sheets[i].disabled = !!(++count % 2);
});
.demo {
background: #888;
color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="demo">Some Text</div>
<button id="button">Click It</button>
Your problem is that you are doing an assignment when you should be doing an equality check.
You have
var css = (document.styleSheets[0].enabled = true);
But you are really trying to do an equality check, i.e.,
var css = (document.styleSheets[0].enabled == true);
Notice the extra =. The single = does an assignment, so your current code is equivalent to this:
document.styleSheets[0].enabled = true
var css = document.styleSheets[0].enabled; // i.e., true
Because you set enabled to true, your if (css == true) condition is always satisfied, so your code always turns the CSS off and never turns it back on.
The fix, as Paul S. wrote in his answer, is just to toggle the value of document.styleSheets[0].disabled, as in:
$("#button").click(function() {
document.styleSheets[0].disabled = !document.styleSheets[0].disabled;
});
There's no need to set and track a new property enabled.
The issue seems to be that you are doing assignment, and not comparison, on this line:
var css = (document.styleSheets[0].enabled = true);
It should be
var css = (document.styleSheets[0].enabled == true);
Probably simpler, since you have a jquery tag on the question, to just do:
$stylesheets = $('link[rel="stylesheet"]');
$("#button").click(function() {
$stylesheets.attr('disabled', !$stylesheets.attr('disabled'));
});
If you want to modify every href in your DOM,
just use
$('a[href*=]').each(function () {
var $this = $(this);
$this.attr('href', $this.attr('href').replace();
});

HTML / JS Simplification

I'm having a hell of a time working on a dropdown menu for a client. I think my code is way too complex for what it is. I need a resolution/alternative way to perform the given objective.
<font id="l1b" size="4" color="black" style="cursor:pointer; color:black;"
onclick="showSubMenu('cat2');
document.getElementById('cat1').style.display = 'none';
document.getElementById('cat3').style.display = 'none';
document.getElementById('cat4').style.display = 'none';
document.getElementById('pa1').style.display = 'none';
document.getElementById('pb1').style.display = 'none';
document.getElementById('pc1').style.display = 'none';
document.getElementById('pd1').style.display = 'none';
document.getElementById('pa2').style.display = 'none';
document.getElementById('pb2').style.display = 'none';
document.getElementById('pc2').style.display = 'none';
document.getElementById('pd2').style.display = 'none';
document.getElementById('da2a').style.display = 'none';
document.getElementById('da2b').style.display = 'none';
document.getElementById('da2c').style.display = 'none';
document.getElementById('da2d').style.display = 'none';
document.getElementById('da2e').style.display = 'none';
document.getElementById('da2f').style.display = 'none';
document.getElementById('da2g').style.display = 'none';
document.getElementById('da2h').style.display = 'none';">Tea Bags<img src="arrow.png" style="position:relative; left:8px; top:3px;"></font>
Here's a pic of the concept: http://robstest.mydnd.com/helppic.php
First person to help gets 10 brownie points! :D
To illustrate the benefits of using a library such as jQuery to make your life easier:
Pure JavaScript
var elementList = ['cat1', 'cat2', 'cat3', 'cat4', 'pa1', ... , 'da2h'];
function showSubMenu(el) {
for (var i = 0; i < elementList.length; i++) {
if (elementList[i] != el) {
document.getElementById(elementList[i]).style.display = 'none';
}
}
}
jQuery
var elementList = ['cat1', 'cat2', 'cat3', 'cat4', 'pa1', ... , 'da2h'];
function showSubMenu(el) {
$.each(elementList, function() {
if (this != el) {
$('#' + this).css({display: "none"});
}
}
}
This tutorial might also be helpful: http://www.html-5-tutorial.com/
Here is a link to a JQuery dropdown tutorial that does something similar to what you want:
http://css-tricks.com/simple-jquery-dropdowns/
... you can also download the files and modify them to your needs.
It would be a good exercise for you to play around with and learn while you are making your project.
(Plus you may want to look at some other implementations of dropdowns to get an idea of best practices - the UI you have mocked up looks a little confusing for an end user)
Get the child elements and loop through them, setting the display for each. Stuff this into a function such as yourfunction(parentDiv), and apply to the on-click event after a semi-colon.
I would type up this code, but right now I don't have enough material to work with.
Use jQuery to do something like this:
$(function() {
$("#l1b").children().each(function() {
$(this).hide();
});
});

Categories

Resources