将 Jquery slidetoggle 代码转换为 Javascript

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29949331/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 11:22:57  来源:igfitidea点击:

Convert Jquery slidetoggle code to Javascript

javascriptjquery

提问by K2R

How can I convert the jQuery slidetoggle() function into Javascript?

如何将 jQuery slidetoggle() 函数转换为 Javascript?

 var $context = getContext(context);

        $($context).on('click', '.m_menu', function () {
            $('.w_nav').slideToggle();
        });

回答by Samurai

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:

嗯,这不是将 jQuery 代码转换为 javascript,而是在普通的 javascript 中进行。它可以通过不同的方式实现。以下是我想到的两个:

HTML:

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 setIntervalto increase/decrease the height.

1. 使用javascript's setInterval:
有一个布尔值来跟踪我们是否需要slideUp 或slideDown(切换)并使用setInterval来增加/减少高度。

jsfiddle DEMO

jsfiddle演示

Javascript:

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.

2. 使用CSS3 过渡
从 CSS3 过渡中获得帮助,配合 javascript 使用,这将使实现幻灯片效果变得更加容易。然后我们只需要在 javascript 中更改高度,其余的就完成了。

jsfiddle DEMO

jsfiddle演示

CSS:

CSS:

#mdiv {
    /* other styles */
    -webkit-transition: all 1s ease-in-out;
    transition: all 1s ease-in-out;
}

Javascript:

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:

编辑:
如果我们希望起始高度为 0,那么我们需要进行一些更改:

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

jsfiddle演示

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.

编辑 #2
正如 Sandro 指出的那样,上下文实际上并没有被隐藏,所以更新了小提琴并添加overflow-y: hidden;和更改了文本颜色以提高可见性。由于 open 是一种保留字,因此也将 open 更改为 slideOpen。

回答by chebaby

To reimplement (convert) jquery slideToggle()to vanilla javascript, you need to reimplement jquery slideUp()and slideDown()as well.

要将 jquery slideToggle()重新实现(转换)为 vanilla javascript,您还需要重新实现 jquery slideUp()slideDown()

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: #ddd;
    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>

回答by Carlos Terrazas

A solution more simple in vanilla i leave it here html->

一个更简单的香草解决方案我把它留在这里 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

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

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

这段代码没有slideUp 和SlideDown,它有。使用一次