How can I convert the jQuery slidetoggle() function into Javascript?
var $context = getContext(context);
$($context).on(\'click\', \'.m_menu\', f
You Just need Vanilla Js to accomplish what you need, by the way Here is the laziest way
//i hope this will solve your issue
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=0.1,shrink-to-fit=no">
<link type="text/css" href="/css" rel="stylesheet">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<title>slideToggle</title>
<style>
.toggle-navigation{
transition: all .3s ease-in-out !important;
margin:100px auto;
}
.toggle-content{
transition: all .3s ease-in-out !important;
}
</style>
</head>
<body>
<div class="toggle navigation bg-primary w-25" id="toggle-nav" onclick = "toggleNavigation();">
<p class="text-white text-center font-weight-bold">Click To Expand</p>
<div class="toggle-content" id="toggle-content">
<p class="text-white font-weight-bold text-justify">
Lorem Ipsum Dolor Sit Amet , Lorem Ipsum Dolor Sit Amet
Lorem Ipsum Dolor Sit Amet , Lorem Ipsum Dolor Sit Amet
Lorem Ipsum Dolor Sit Amet , Lorem Ipsum Dolor Sit Amet
Lorem Ipsum Dolor Sit Amet , Lorem Ipsum Dolor Sit Amet
Lorem Ipsum Dolor Sit Amet , Lorem Ipsum Dolor Sit Amet
</p>
</div>
</div>
<script>
let toggleNav = document.getElementById('toggle-nav');
navHeight = toggleNav.offsetHeight;
content= document.getElementById('toggle-content');
contentHeight = content.offsetTop - content.offsetTop;
content.style.height = contentHeight;
toggle = true ;
function toggleNavigation(){
if(toggle){
content.style.height = navHeight;
}else{
content.style.height = contentHeight;
}
toggle = !toggle;
}
</script>
</body>
</html>
To reimplement (convert) jquery slideToggle() to vanilla javascript, you need to reimplement jquery slideUp() and slideDown() as well.
var DOMAnimations = {
/**
* SlideUp
*
* @param {HTMLElement} element
* @param {Number} duration
* @returns {Promise<boolean>}
*/
slideUp: function (element, duration = 500) {
return new Promise(function (resolve, reject) {
element.style.height = element.offsetHeight + 'px';
element.style.transitionProperty = `height, margin, padding`;
element.style.transitionDuration = duration + 'ms';
element.offsetHeight;
element.style.overflow = 'hidden';
element.style.height = 0;
element.style.paddingTop = 0;
element.style.paddingBottom = 0;
element.style.marginTop = 0;
element.style.marginBottom = 0;
window.setTimeout(function () {
element.style.display = 'none';
element.style.removeProperty('height');
element.style.removeProperty('padding-top');
element.style.removeProperty('padding-bottom');
element.style.removeProperty('margin-top');
element.style.removeProperty('margin-bottom');
element.style.removeProperty('overflow');
element.style.removeProperty('transition-duration');
element.style.removeProperty('transition-property');
resolve(false);
}, duration)
})
},
/**
* SlideDown
*
* @param {HTMLElement} element
* @param {Number} duration
* @returns {Promise<boolean>}
*/
slideDown: function (element, duration = 500) {
return new Promise(function (resolve, reject) {
element.style.removeProperty('display');
let display = window.getComputedStyle(element).display;
if (display === 'none')
display = 'block';
element.style.display = display;
let height = element.offsetHeight;
element.style.overflow = 'hidden';
element.style.height = 0;
element.style.paddingTop = 0;
element.style.paddingBottom = 0;
element.style.marginTop = 0;
element.style.marginBottom = 0;
element.offsetHeight;
element.style.transitionProperty = `height, margin, padding`;
element.style.transitionDuration = duration + 'ms';
element.style.height = height + 'px';
element.style.removeProperty('padding-top');
element.style.removeProperty('padding-bottom');
element.style.removeProperty('margin-top');
element.style.removeProperty('margin-bottom');
window.setTimeout(function () {
element.style.removeProperty('height');
element.style.removeProperty('overflow');
element.style.removeProperty('transition-duration');
element.style.removeProperty('transition-property');
}, duration)
})
},
/**
* SlideToggle
*
* @param {HTMLElement} element
* @param {Number} duration
* @returns {Promise<boolean>}
*/
slideToggle: function (element, duration = 500) {
if (window.getComputedStyle(element).display === 'none') {
return this.slideDown(element, duration);
} else {
return this.slideUp(element, duration);
}
}
}
// ------------------------------------------------------
document.addEventListener("DOMContentLoaded", function() {
var button = document.getElementById('slideToggle');
var cardElement = document.getElementById('firstCard');
button.addEventListener('click', function(event) {
event.preventDefault();
DOMAnimations.slideToggle(cardElement);
});
});
* {
box-sizing: border-box;
}
/* Add a gray background color with some padding */
body {
font-family: Arial;
padding: 20px;
background: #f1f1f1;
}
/* Header/Blog Title */
.header {
padding: 10px;
font-size: 24px;
text-align: center;
background: white;
}
/* Create two unequal columns that floats next to each other */
/* Left column */
.leftcolumn {
float: left;
width: 100%;
}
/* Fake image */
.fakeimg {
background-color: #aaa;
width: 100%;
padding: 20px;
}
/* Add a card effect for articles */
.card {
position:relative;
background-color: white;
padding: 20px;
margin-top: 20px;
}
#slideToggle {
background-color: #f9f5f5;
color: black;
border: 2px solid #a9b5a9;
padding: 5px;
margin-top:20px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
cursor: pointer;
font-weight: bold;
border-radius: 5px;
}
/* Clear floats after the columns */
.row:after {
content: "";
display: table;
clear: both;
}
/* Footer */
.footer {
padding: 20px;
text-align: center;
background: #ffffd;
margin-top: 20px;
}
/* Responsive layout - when the screen is less than 800px wide, make the two columns stack on top of each other instead of next to each other */
@media screen and (max-width: 800px) {
.leftcolumn, .rightcolumn {
width: 100%;
padding: 0;
}
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div class="header">
<h2>Blog Name</h2>
</div>
<div class="row">
<div class="leftcolumn">
<button id="slideToggle">slideToggle</button>
<div class="card" id="firstCard">
<h2>FIRST TITLE HEADING</h2>
<h5>Title description, Dec 7, 2018</h5>
<div class="fakeimg" style="height:200px;">Image</div>
<p>Some text..</p>
<p>Sunt in culpa qui officia deserunt mollit anim id est laborum consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco.</p>
</div>
<div class="card">
<h2>SECOND TITLE HEADING</h2>
<h5>Title description, Dec 7, 2018</h5>
<div class="fakeimg" style="height:200px;">Image</div>
<p>Some text..</p>
<p>Sunt in culpa qui officia deserunt mollit anim id est laborum consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco.</p>
</div>
</div>
</div>
<div class="footer">
<h2>Footer</h2>
</div>
</body>
</html>
I am giving a lightweight answer. You can think of it as a skeleton example, and you can play with it, style it later, according to your preferences.
Before you begin, I would like to clarify that I'm not converting
jQuery
slideToggle()
function into one inJavaScript
All I'm doing is, trying to replicate that function in the simplest possible form!
Create a button/(any other element), which you can link with an eventListener
.
Create an element, which you want to toggle/slide/whatever you want to call it!
Go ahead with your javaScript
, and create a conditional setInterval()
for a function linked with that eventListener
.
You can give your suggestions in the comment section.
var animxB = 0;
var anim2B = 0;
document.getElementById("animB").addEventListener("click", performB);
function performB() {
anim2B++;
anim3B = anim2B % 2;
var fram1B = setInterval(framB, 1);
function framB() {
if (anim3B == 1) {
animxB++;
document.getElementById("divB").style.width = animxB + "px";
document.getElementById("divB").style.height = animxB + "px";
if (animxB >= 200) {
clearInterval(fram1B);
document.getElementById("animB").innerHTML = "Click(-)";
}
}
if (anim3B == 0) {
animxB--;
document.getElementById("divB").style.width = animxB + "px";
document.getElementById("divB").style.height = animxB + "px";
if (animxB <= 0) {
clearInterval(fram1B);
document.getElementById("animB").innerHTML = "Click(+)";
}
}
}
}
<!DOCTYPE html>
<html>
<head></head>
<body>
<button id="animB" style="font-weight:bold; color:brown;">Click(+)</button>
<div id="divB" style="width:0; height:0; overflow:auto; color:gray; font-family:sans-serif; font-size:13px;">
<path d="M10 10 v80 h80 v-80 h-80" fill="gray" stroke="black" stroke-width="1" /> <path d="M40 10 v20" stroke="blue" stroke-width="0.5" /> <path d="M10 30 h30" stroke="red" stroke-width="0.5" /> <circle cx="40" cy="30" r="2" fill="purple" stroke="purple" stroke-width="1" />
</div>
</body>
</html>
A solution more simple in vanilla i leave it here html->
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="css.css" />
<script src="js.js"></script>
<title>Document</title>
</head>
<body>
<div class="menu">
<div class="dropdown">Menu</div>
<div class="menu_main">
<div class="menu__item">Item 1</div>
<div class="menu__item">Item 2</div>
<div class="menu__item">Item 3</div>
</div>
</div>
<div>
text behind of menu
</div>
</body>
</html>
CSS
* {
box-sizing: border-box;
}
.menu {
display: block;
position: relative;
background-color: rgba(255, 0, 0, 0.3);
width: 150px;
height: 40px;
font-family: monospace;
}
.dropdown {
background-color: #4caf50;
box-shadow: inset 2px 2px 30px 10px lime;
display: block;
cursor: pointer;
text-align: center;
padding: 7px 35px;
color: white;
position: relative;
width: 100%;
height: 100%;
font-size: 1.5em;
font-weight: 900;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
}
.menu_main {
position: absolute;
height: 0%; /* 300 */
width: 100%;
overflow: hidden;
transition: height 1250ms;
background-color: rgba(0, 255, 0, 0.2);
}
.menu__item {
font-size: 1.4em;
text-align: center;
font-weight: 900;
line-height: 40px;
height: 34%;
background-color: rgb(189, 243, 201);
}
JS
document.addEventListener("DOMContentLoaded", function () {
const boton = document.getElementsByClassName("dropdown")[0];
boton.addEventListener(
"click",
function (e) {
if (
window
.getComputedStyle(e.target.nextElementSibling, null)
.getPropertyValue("height") == "0px"
) {
e.target.nextElementSibling.style.height = "300%";
} else {
e.target.nextElementSibling.style.height = "0%";
}
},
false
);
});
this code does not have slideUp and SlideDown, it has all together. to use it once
Well this is not converting the jQuery code to javascript, but rather doing it in plain javascript. It can be achieved in different ways. Here are two that comes to my mind:
HTML:
<button id="mbtn" onclick="slideToggle()">SlideToggle</button>
<div id="mdiv">Some context</div>
1. Using javascript's setInterval
:
Having a boolean value to keep track of whether we need to slideUp or slideDown (toggle) and using setInterval
to increase/decrease the height.
jsfiddle DEMO
Javascript:
var slideOpen = true;
var heightChecked = false;
var initHeight = 0;
var intval = null;
function slideToggle() {
window.clearInterval(intval);
var mdiv = document.getElementById('mdiv');
if(!heightChecked) {
initHeight = mdiv.offsetHeight;
heightChecked = true;
}
if(slideOpen) {
var h = initHeight;
slideOpen = false;
intval = setInterval(function(){
h--;
mdiv.style.height = h + 'px';
if(h <= 0)
window.clearInterval(intval);
}, 1
);
}
else {
var h = 0;
slideOpen = true;
intval = setInterval(function(){
h++;
mdiv.style.height = h + 'px';
if(h >= initHeight)
window.clearInterval(intval);
}, 1
);
}
}
2. Using CSS3 transition:
Getting help from CSS3 transition to go along with javascript which will make it a lot easier to achieve the slide effect. Then we'll only need to change the height in javascript and the rest is done.
jsfiddle DEMO
CSS:
#mdiv {
/* other styles */
-webkit-transition: all 1s ease-in-out;
transition: all 1s ease-in-out;
}
Javascript:
var slideOpen = true;
var heightChecked = false;
var initHeight = 0;
function slideToggle() {
var mdiv = document.getElementById('mdiv');
if(!heightChecked) {
initHeight = mdiv.offsetHeight;
heightChecked = true;
}
if(slideOpen) {
slideOpen = false;
mdiv.style.height = '0px';
}
else {
slideOpen = true;
mdiv.style.height = initHeight + 'px';
}
}
EDIT:
If we want the starting height to be 0, then we'll need a few changes:
var slideOpen = false;
//var heightChecked = false;
var initHeight = 120; //height of the element when it's fully open
And we need to comment this bit out:
/*
if(!heightChecked) {
initHeight = mdiv.offsetHeight;
heightChecked = true;
}
*/
jsfiddle DEMO
EDIT #2
As Sandro pointed out, context wasn't actually getting hidden so updated the fiddles and added overflow-y: hidden;
and changed the text color for visibility.
Also changed open to slideOpen since open is sort of a reserved word.