Add fade-in effect in nested accordion - javascript

I am new to jquery. I have a custom Accordion in which i'll like to add in a fade-in effect to the text when a particular header title is clicked. I tried many different ways but it did not get the results I want.
Here are my accordion codes :
HTML
<div class="container">
<!--Enter accordion here-->
<ul id="cbp-ntaccordion" class="cbp-ntaccordion" style="margin-top: -92px; font-family: 'FUTURA MEDIUM'; font-weight: 300; line-height:1.5;">
<li>
<h3 class="cbp-nttrigger">ArtZone’s 10th Anniversary Art Exhibition 2015</h3>
<div class="cbp-ntcontent bodytext">
<div class="myannualcontent">
<img src="images/Arts-House-Image.jpg" alt="" align="left" style=" margin-left: 2px; width: 19%; margin-bottom: 20px;
margin-top: 20px; margin-right: 35px;"/>
<p style="text-align: justify; padding-top: 20px; margin-left: 10px;">
Header text here <br /><br />
Join us once more as we delve into the world of our students’ creative journey express beautifully on paper. Under the guidance of our dedicated teachers, our students hereby present to you the fruits of their labour in their very distinctive way. <br /><br />
</p>
<div>
</div>
</li>
</ul>
CSS
.cbp-ntaccordion > li > .cbp-nttrigger:before {
font-size: 75%;
}
.cbp-ntaccordion > li > .cbp-nttrigger:before {
content: "\36";
}
.cbp-ntaccordion > li > .cbp-nttrigger:hover:before {
content: "\35";
color: inherit;
}
.cbp-ntaccordion > li.cbp-ntopen > .cbp-nttrigger:before,
.no-js .cbp-ntaccordion > li > .cbp-nttrigger:before {
content: "\34";
color: inherit;
}
.cbp-ntsubaccordion > li > .cbp-nttrigger:before {
content: "\32";
}
.cbp-ntsubaccordion > li > .cbp-nttrigger:hover:before {
content: "\33";
color: inherit;
}
.cbp-ntsubaccordion > li.cbp-ntopen > .cbp-nttrigger:before,
.no-js .cbp-ntsubaccordion > li > .cbp-nttrigger:before {
content: "\31";
color: inherit;
}
/* Initial height is zero */
.cbp-ntaccordion .cbp-ntcontent {
height: 0;
overflow: hidden;
}
/* When its open, set height to auto */
.cbp-ntaccordion .cbp-ntopen > .cbp-ntcontent,
.cbp-ntsubaccordion .cbp-ntopen > .cbp-ntcontent,
.no-js .cbp-ntaccordion .cbp-ntcontent {
-webkit-transition: opacity 500ms ease-in-out;
-moz-transition: opacity 500ms ease-in-out;
-ms-transition: opacity 500ms ease-in-out;
-o-transition: opacity 500ms ease-in-out;
transition: opacity 500ms ease-in-out;
height: auto;
}
/* Example for media query */
#media screen and (max-width: 32em) {
.cbp-ntaccordion {
font-size: 70%;
}
}
Javascript
<script>
$( function() {
/*
- how to call the plugin:
$( selector ).cbpNTAccordion( [options] );
- destroy:
$( selector ).cbpNTAccordion( 'destroy' );
*/
$('#cbp-ntaccordion').cbpNTAccordion();
// $("cbp-ntopen").click(function () {
/** $("#cbp-ntcontent").fadeToggle("slow",
"linear").find(".close").on("click", function() {
$(this).parents("#cbp-ntcontent").fadeIn("slow");
return false;
});
}); **/
/** on click on any of the titles then run this codes
$("#cbp-ntaccordion").fadeToggle("slow", "linear").find(".close").on("click", function() {
$(this).parents("#cbp-ntaccordion").fadeOut("slow");
return false;
});
*/
} );
</script>

I didn't understand what you expect exactly. but assume you want this.if it is not tell me what you want.
This is your html
<h3 class="dofade">ArtZone’s 10th Anniversary Art Exhibition 2015</h3>
<p class="mefade" style="display:none;">This is what you want to show</p>
This is your css
if you are using external style, in your css file
.mefade{
display:none;
}
This is your javascript
if you are using internal js
<script type="text/javascript">
$(document).ready(function(){
$(".dofade").click(function(){
$(.mefade).fadeIn(3000);//3000 meant within this ms time it shows
});
});
</script>
if you use external js add this code
$(document).ready(function(){
$(".dofade").click(function(){
$(.mefade).fadeIn(3000);//3000 meant within this ms time it shows
});
});

Related

Fade into light mode when toggle is clicked?

In the top left corner of this page, I have a "Light/Dark mode" toggle. When 'Light mode' is clicked, it fades into dark mode nicely no problem. But once it's in Dark mode, and you click 'light mode', it doesn't fade in nicely and I can't seem to get it to work.
What would I need to add to my code to get it to fade nicely in to light mode?
<!DOCTYPE html>
<html id= "mode" lang="en-au">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title> Test </title>
<head>
<link rel = "icon" type = "image/png" href = "https://ibb.co/bRc1Qqq">
<link rel = "apple-touch-icon" type = "image/png" href = "https://ibb.co/bRc1Qqq"/>
<!-- Square Windows tiles -->
<meta name="msapplication-square70x70logo" content="https://ibb.co/bRc1Qqq"></meta>
<meta name="msapplication-square150x150logo" content="https://ibb.co/bRc1Qqq"></meta>
<meta name="msapplication-square310x310logo" content="https://ibb.co/bRc1Qqq"></meta>
<!-- Rectangular Windows tile -->
<meta name="msapplication-wide310x150logo" content="https://ibb.co/bRc1Qqq"></meta>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Gugi|Raleway|Abril+Fatface|Unica+One|Press+Start+2P|Bungee">
<!-- Makes stuff fadein on pageload-->
<script>
window.onload = function()
{document.body.className += " loaded";
document.querySelector("body").style.opacity = 1;
}
</script>
<style>
html {
height: 100%;
background-color:#b8b8b8;
}
body {
text-decoration: none;
font-family: "Raleway";
border-radius: 7px;
/* color-scheme: light dark; */
}
h1, ul {
padding-top: 5%;
}
body, .fadein {
opacity: 0;
-moz-transition: opacity 3s;
-webkit-transition: opacity 3s;
-o-transition: opacity 3s;
transition: opacity 3;
}
body.loaded .fadein {
opacity: 1;
}
.container {
max-width: 800px;
margin: 0 auto;
}
.header {
display: flex;
align-items: center;
justify-content: space-between;
}
.header h1 {
margin: 0;
}
.tabs {
list-style: none;
margin: 0;
padding: 0;
display: flex;
}
.tabs li {
flex-grow: 1;
text-align: center;
padding: 0.5%;
}
.tabs a {
display: block;
padding: 10px;
color: #333;
text-decoration: none;
border-radius: 7px;
}
.tabs a:hover,
.tabs a.active {
background-color: #ddd;
}
.main {
padding: 20px;
}
/* Hides all sections by default
.section {
display: none;
}
*/
.section.active {
display: block;
}
.dark-mode {
background-color: #020C17;
color: #ffffff;
transition: background-color 0.5s ease-in-out, color 0.5s ease-in-out;
}
.dark-mode ul a{
background-color: #020C17;
color: #ffffff;
}
.dark-mode ul a:hover,
.dark-mode ul a.active {
background-color: #081334;
color: #ddd;
}
#dark-mode-button {
color: #ddd;
padding: 10px;
border-radius: 7px;
cursor: pointer;
transition: background-color 0.5s ease-in-out, color 0.5s ease-in-out;
position: fixed;
}
</style>
<!-- makes scrolling smooth when using anchor -->
<script>
document.querySelector('a').addEventListener('click', function(e) {
e.preventDefault();
var target = document.querySelector(this.getAttribute('href'));
var offset = target.offsetTop;
window.scrollTo({
top: offset,
behavior: 'smooth'
});
});
</script>
<!-- The HTML for the website -->
<body>
<div id="dark-mode-button"><p id="mango" class="btn-toggle">Dark mode</p></div>
<div class="fadein">
<div class="container">
<!-- The header with the title and tabs -->
<div class="header">
<h1>Testing</h1>
<ul class="tabs">
<li><a href="#section1" >About</a></li>
<li>Projects</li>
<li>Test</li>
</ul>
</div>
<!-- The main content of the website, with the sections -->
<div class="main">
<div id="section1">
<h2>About</h2>
<p>This is the content of section 1.</p>
</div>
<div class="section" id="section2">
<h2>Projects</h2>
<p>This is the content of section 2.</p>
</div>
<div class="section" id="section3">
<h2>Test</h2>
<p>This is the content of section 3.</p>
</div>
</div>
</div>
</div>
</body>
<script>
// Get the elements for the tabs and sections
const tabs = document.querySelectorAll('.tabs a');
const sections = document.querySelectorAll('.section');
// Add a click event listener to each tab
tabs.forEach(tab => {
tab.addEventListener('click', event => {
event.preventDefault(); // prevent the default link behavior
// Remove the active class from all tabs and sections
tabs.forEach(tab => tab.classList.remove('active'));
sections.forEach(section => section.classList.remove('active'));
// Add the active class to the clicked tab and corresponding section
tab.classList.add('active');
document.querySelector(tab.getAttribute('href')).classList.add('active');
});
});
</script>
<!-- JavaScript code to handle the button click and switch between modes. also uses button id and the body element -->
<script>
// Get the button and add a click event listener to it
const button = document.getElementById('dark-mode-button');
button.addEventListener('click', () => {
// Get the current body element and toggle the "dark-mode" class
const body = document.getElementById("mode");
body.classList.toggle('dark-mode');
});
</script>
<script>
/* Fetch the buttom element */
const mode = document.getElementById('mango');
/* Add click event listener where we will provide logic that updates the button text */
mode.addEventListener('click', function() {
/* Update the text of the button to toggle beween "More" and "Less" when clicked */
if(mode.innerText.toLowerCase() === 'dark mode') {
mode.innerText = 'Light mode';
}
else {
mode.innerText = 'Dark mode';
}
});
</script>
You need to apply the tranition effect to the elements affected by your dark theme, not the dark-mode class itself. You did it right for the #dark-mode-button though.
Solution for your code: add a transition (transition: all 0.5s ease-in-out) on html{} and .tabs a {}, and you can remove the transition effect on the dark-mode class. Fiddle: https://jsfiddle.net/40y5axcd/
Note: you applied a white text color to the whole html for dark mode, hence your main content text isn't visible on a white background. I left it as is, since it wasn't a part of your question.
Going forward you're better off using an utility class with the transition effect and apply it to all elements affected by the dark mode, especially if you continue to add elements to your page and want to change the transition duration. You rather only have to change one class, then having to go through every element and change the duration.

Why does text "jump" when the element containing it, is animated with CSS?

const dropdown = document.getElementById('dropdown')
let isDropdownActive = false
function toggleDropdown() {
if(!isDropdownActive) {
isDropdownActive = true
dropdown.style.display = "block"
dropdown.classList.add('animate', 'animate-scale-in')
} else {
dropdown.style.display = "none"
isDropdownActive = false
}
}
html {
font-size: 14px;
}
.absolute {
position: absolute;
}
.animate {
animation-fill-mode: both;
animation-duration: 0.4s;
}
.animate-scale-in {
animation-name: animScaleIn;
}
#keyframes animScaleIn {
from {
transform: scale(0);
}
to {
transform: scale(1);
}
}
<div style="position: relative">
<button
style="padding: 0.625rem 1rem"
onclick="toggleDropdown()"
>
Open Dropdown
</button>
<div
id="dropdown"
class="absolute"
style="background-color: red; display: none"
>
<ul>
<li style="padding: 0.75rem 1rem;">
<span class="text-subtitle text-gray5"> ITEMS </span>
</li>
</ul>
</div>
</div>
As you can see I have a button when clicked a dropdown menu will appear. However at the end of animation inside the menu you can see how the text "ITEMS" jumps to the top a little. If I remove html {font-size: 14px} or set the html font size to 16px there's no stuttering. Also if I remove the padding there's no stuttering too. Please help me with this.
The stuttering in slow-mo:
Since You are using position absolute, You need to add the x axis and y axis
Position: absolute;
top: 100%;
left: 0;
here is the demo:
const dropdown = document.getElementById('dropdown')
function toggleDropdown() {
if(!dropdown.classList.contains('animate')) {
dropdown.classList.add('animate')
} else {
dropdown.classList.remove('animate');
}
}
*{
box-sizong: border-box;
padding: 0;
margin: 0;
}
html {
font-size: 14px;
padding: 20px;
}
[id=dropdown]{
Position: absolute;
top: 100%;
left: 0;
background-color: red;
transform: scale(0);
transform-style: preserve-3d;
will-change: transform;
}
.absolute {
position: absolute;
}
.animate {
animation-fill-mode: both;
animation-duration: 0.4s;
animation-name: animScaleIn;
}
.text-subtitle{display: block}
#keyframes animScaleIn {
to { transform: scale(1); }
}
<div style="position: relative; display: block">
<button style="padding: 0.625rem 1rem"
onclick="toggleDropdown()"
>
Open Dropdown
</button>
<div id="dropdown">
<ul>
<li style="padding: 0.75rem 1rem;">
<span class="text-subtitle text-gray5"> ITEMS </span>
</li>
</ul>
</div>
</div>
The "bump" coincides with the element hitting scale=1 precisely, which leads me to assume that this is something to do with how Chromium optimizes rendering for unscaled elements.
Setting the target scale to be ever-so-slightly-less-than-1 (to prevent that optimization) helps:
const dropdown = document.getElementById('dropdown')
let isDropdownActive = false
function toggleDropdown() {
if(!isDropdownActive) {
isDropdownActive = true
dropdown.style.display = "block"
dropdown.classList.add('animate', 'animate-scale-in')
} else {
dropdown.style.display = "none"
isDropdownActive = false
}
}
html {
font-size: 14px;
}
.absolute {
position: absolute;
}
.animate {
animation-fill-mode: both;
animation-duration: 0.4s;
}
.animate-scale-in {
animation-name: animScaleIn;
}
#keyframes animScaleIn {
from {
transform: scale(0);
}
to {
transform: scale(0.9999999);
}
}
<div style="position: relative">
<button
style="padding: 0.625rem 1rem"
onclick="toggleDropdown()"
>
Open Dropdown
</button>
<div
id="dropdown"
class="absolute"
style="background-color: red; display: none"
>
<ul>
<li style="padding: 0.75rem 1rem;">
<span class="text-subtitle text-gray5"> ITEMS </span>
</li>
</ul>
</div>
</div>
I am afraid you're at the end of the road with your design -- A Web browser, in practice, does not guarantee you pixel perfect rendering. In theory, this might have been the case, since there is no provision in any specification to necessarily produce different glyph sizes for a given font size rule, or padding numbers, for that matter.
In practice, however, Web browsers have, do and will continue to render your hypertext at their own discretion with regard to accuracy achieved, potentially slightly differently from one another, due to a number of variables you have no straightforward (if any) control over.
For instance, testing your code on my Firefox 87 on Windows 10, there is no "jankiness" whatsoever.
You will need to accept the "jankiness" or revise your design to the extent where the problem disappears on its own or where you employ a different UI solution to achieve your goal.
You can look at the details HTML element and see if it may help you solve the problem without all the scripting involved on your part.

Javascript - Text to Appear With Delay (Ease-In)

I'm trying to make it so that the text on the landing page appears with a slight delay....first, the first line should appear, then the second. They should both ease-in as they appear. Here's a screenshot of the section:
So "Welcome" should appear first, then "To the Bullshit Collection". I tried following the suggestions in this treehouse article. When following the method suggested by Lauren, "Welcome" never appears.
https://jsfiddle.net/fjvLwmrq/
And when following the method suggested by Rob, }//]]> appears (with no delay) instead of "Welcome".
https://jsfiddle.net/a49rxo19/
Here is my HTML:
<div class="parallax-window" data-parallax="scroll" data-image-src="/wp-content/themes/TheBullshitCollection/Images/white-background.jpg">
<div class="welcome-div">
<h3 class="welcome">Welcome</h3>
</div>
<div class="to-the-bullshit-collection-div">
<h3 class="to-the-bullshit-collection">To the Bullshit Collection</h3>
</div>
<section id="section5" class="demo">
<span></span>Scroll
</section>
</div>
CSS:
.parallax-window {
height: 100vh;
}
.welcome {
text-align:center;
font-family: Beautiful ES;
font-size: 185px;
font-weight: lighter;
}
.to-the-bullshit-collection {
text-align:center;
font-family: Beautiful ES;
font-size: 185px;
font-weight: lighter;
}
#section5 {
text-align:center;
}
#section5 a {
padding-top: 70px;
font-family: PT Sans Narrow;
text-transform: Uppercase;
text-decoration: none;
font-weight: bold;
color: #000000;
}
And JavaScript:
//javascript functions
(function ($, root, undefined) {
$(function () {
'use strict';
// DOM ready, take it away
});
})(jQuery, this);
//landing page text delay
function showWelcomeDiv() {
document.getElementById("welcome-div").style.display = "inline";
}
//this calls the function above, 3000 milliseconds is 3 seconds, adjust
here to make it a longer interval
setTimeout("showBuyNow()", 1000);
Any idea what's going wrong? Thanks!
Don't you feel this method to be simpler ?
/*WindowOnload Fade-In*/
#keyframes chainReaction {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
/*div p {
animation: chainReaction 2s;
opacity: 0;
animation-fill-mode: forwards;
}*/
.parallax-window .welcome-page-div {
animation: chainReaction 3s;
opacity: 0;
animation-fill-mode: forwards;
text-align: center;
font-family: Beautiful ES;
font-size: 30px;
font-weight: lighter;
}
.parallax-window .welcome-page-div:nth-child(1) {
animation-delay: .3s;
}
.parallax-window .welcome-page-div:nth-child(2) {
animation-delay: 1s;
}
/*WindowOnload Fade-In*/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parallax-window" data-parallax="scroll" data-image-src="/wp-content/themes/TheBullshitCollection/Images/white-background.jpg">
<div class="welcome-page-div">
<h3>Welcome</h3>
</div>
<div class="welcome-page-div">
<h3>To the Bullshit Collection</h3>
</div>
<section id="section5" class="demo">
<span></span>Scroll
</section>
</div>
You can use this jQuery add-on function. Demo here.
Just import after jQuery:
<script src="https://cdn.jsdelivr.net/gh/jrquick17/jquery-delay-text/delay-text.js"></script>
And then use a jQuery selector to target your elements containing the text:
$('h3').delayText({ sequential: true });

How do I set jQuery accordion default to unopened? And toggle open/closed?

So I've got a page with a ton of accordions and when the first initially loads every single accordion by default is opened until I click on one. Then all of them close but that one and it then works fine from there.
HTML
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<div id="ss_menu">
<a class="ss_button">Accordion 1</a>
<div class="ss_content">
Content 1
</div>
</div>
<div id="ss_menu">
<a class="ss_button">Accordion 2</a>
<div class="ss_content">
Content 2
</div>
</div>
<div id="ss_menu">
<a class="ss_button">Accordion 3</a>
<div class="ss_content">
Content 3
</div>
</div>
CSS
/* Accordion controls */
#ss_menu {
border: 1px solid #ccc;
}
.ss_button {
cursor: pointer;
color: black;
}
.ss_content {
padding: 5px 10px;
text-decoration: none;
color: #666;
font-family: arial, verdana, tahoma;
font-size: 10px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
transition: all 0.5s;
-webkit-transition: all 0.5s;
-moz-transition: all 0.5s;
}
JS
jQuery(function() {
jQuery('.ss_button').on('click',function() {
jQuery('.ss_content').slideUp('fast');
jQuery(this).next('.ss_content').slideDown('fast');
});
});
And the related Codepen: http://codepen.io/jacob_johnson/pen/zvdQGO
So my questions are:
1. How can I set them all closed by default on page load?
2. How can I toggle the one active one off by clicking the activate button again?
Any help would be appreciated.
Solution to question 1
Add display: none to my content element.
Set display:none in the CSS to start and change the code to be smarter on what it is hiding.
jQuery('.ss_button').on('click',function() {
var content = jQuery(this).next('.ss_content');
jQuery('.ss_content').not(content).slideUp('fast');
content.toggleSlide('fast');
});
To do it using the code you have, you need a document.ready function which will close the content:
$(document).ready(function() {
$('.ss_content').hide();
$('.ss_button').on('click',function() {
$('.ss_content').slideUp('fast');
$(this).next('.ss_content').slideDown('fast');
});
});
However, this will lead to your content being visible for a second while the page loads. The better way of doing this is with a CSS class:
$(document).ready(function() {
$('.ss_button').on('click',function() {
var menu = $(this).closest('.ss_menu');
if (menu.hasClass('open')) {
$('.ss_menu.open').removeClass('open');
menu.addClass('open');
}
else {
menu.removeClass('open');
}
});
});
Then in your CSS, you set everything to a default state of closed, but animate it to open when its parent has an open class:
.ss_menu {
overflow:hidden;
}
.ss_menu.open .ss_content {
opacity:1;
max-height:1000px; /*set this to a height much bigger than you expect*/
}
.ss_content {
max-height:0;
opacity:0;
transition:all 0.2s ease-out; /*or whatever transition you want*/
}
P.S. you can't have more than one item in a page with the same id - I have assumed this was a mistake, and used ss_menu as a class instead of an ID selector.

js hide/unhide with css formatting

I have the following js script which (on its own it works fine really):
<style>
<!--
.hide { display: none; }
.unhide {
display: block;
text-decoration: none;
color: black;
}
-->
</style>
<script type="text/javascript">
function unhide(divID) {
var item = document.getElementById(divID);
if (item) {
item.className=(item.className=='hide')?'unhide':'hide';
}
}
</script>
</head>
<body>
<div id="col2">
<a href="javascript:unhide('content1');">
Title of Content</a>
</div>
<div id="col2">
<div id="content1" class="hide">
Body of content
</div>
</div>
Left alone, this produces output, at least. But I want to format this according to this css code:
a.unhide li {
background: #fff;
font: 20px century schoolbook, serif;
}
a.unhide li:hover {
background: #ddd;
text-decoration:underline;
padding: 3px 8px;
display: table-row;
line-height: 500%;
transition: background .25s ease-in-out;
-moz-transition: background .25s ease-in-out;
-webkit-transition: background .25s ease-in-out;
}
.hide {
font: 20 px century schoolbook, serif;
color: black;
text-decoration: none;
}
So how can I possibly "pair" all this? I've posted elsewhere and people have been stumped. Please help. I can induce changes into just about every aspect BUT the "unhide" portion of the js script. It does not cooperate with me ;( Basically I want a #ddd hover effect over the "unhide" link and all content to be in century schoolbook. Please help. Thank you.
Your problem might be that you have double IDs. IDs cannot be duplicate, they have to be unique. You can give them a class instead.
Try this instead:
HTML
<div>
<a href="javascript:unhide('content1');">
Title of Content
</a>
</div>
<div>
<div class="content1 hide">Body of content</div>
</div>
Javascript
function unhide(divID) {
var item = document.getElementsByClassName(divID)[0];
console.log(item);
console.log(item.className == divID + ' hide');
if (item) {
item.className = (item.className == divID + ' hide') ? divID + ' unhide' : divID + ' hide';
}
}
Demo here
In your CSS you are applying the hover to a a.unhide li:hover {. Is that what you want? I see no li in your code and the content1 in your code is a div not a a.

Categories