在不使用jQuery的情况下切换HTML元素的类

34

我在网站上有一个包含所有内容的部分,但我想要一个“侧边栏”,可以在按下外部按钮时从左侧平滑地显示隐藏内容。

CSS转换可以很好地处理平滑性问题,而且可以使用jQuery toggle() 切换类来移动隐藏的 div 进出屏幕。

如何在不使用jQuery的情况下实现相同的效果?

7个回答

40
你可以使用classList.toggle()函数来切换类:
var element = document.getElementById('sidebar');
var trigger = document.getElementById('js-toggle-sidebar'); // or whatever triggers the toggle

trigger.addEventListener('click', function(e) {
    e.preventDefault();
    element.classList.toggle('sidebar-active'); // or whatever your active class is
});

如果您有多个触发器,我建议使用document.querySelectorAll(selector),这样就可以满足您的所有需求了。


37

你可以仅通过CSS3来实现它:

<label for="showblock">Show Block</label>
<input type="checkbox" id="showblock" />

<div id="block">
    Hello World
</div>

并且CSS部分:

#block {
    background: yellow;
    height: 0;
    overflow: hidden;
    transition: height 300ms linear;
}

label {
    cursor: pointer;
}

#showblock {
    display: none;
}

#showblock:checked + #block {
    height: 40px;
}

魔法是在CSS中隐藏的 checkbox :checked选择器。

工作中的jsFiddle演示


这只能用标签(label)吗?我想要用图像(img)代替。 - ZackOfAllTrades
@ZackOfAllTrades 将你的 img 放在 label 标签内。 - dashtinejad

7

仅使用HTML

您可以使用<summary>。以下代码没有任何依赖项。完全不需要JavaScript、CSS,仅使用HTML。

<div class="bd-example">
  <details open="">
    <summary>Some details</summary>
    <p>More info about the details.</p>
  </details>

  <details>
    <summary>Even more details</summary>
    <p>Here are even more details about the details.</p>
  </details>
</div>

更详细信息请访问MDN官方文档


2
我不确定这个能否使用CSS样式制作成侧边栏,因为我从未尝试过。即使可以,也绝对不是语义化的。感谢您提出一个不常用的HTML元素。我不会给负评。 - Nilpo

6

您可以使用 JavaScript(不使用 jQuery)通过 id 获取任何元素,并且 class 是一个属性: element.className 因此,将其作为函数:

更新: 由于这已经变得有些流行,我更新了函数以使其更好。

function toggleClass(element, toggleClass){
   var currentClass = element.className || '';
   var newClass;
   if(currentClass.split(' ').indexOf(toggleClass) > -1){ //has class
      newClass = currentClass.replace(new RegExp('\\b'+toggleClass+'\\b','g'), '')
   }else{
      newClass = currentClass + ' ' + toggleClass;
   }
   element.className = newClass.trim();
}

1
非常好的答案!请将函数内的第一行更改为 var currentClass = element.className || '' 以处理空的 class 属性 :) - ymz
如果元素没有class属性,element.className将是一个空字符串。 - Victor Radu

0
function init() {

    animateCSS(document.getElementById("slide"), 250, {
        left: function (timePercent, frame) {

            var endPoint = 128,
                startPoint = 0,
                pathLength = endPoint - startPoint,
                base = 64,                          //slope of the curve
                currentPos = Math.floor(startPoint + (Math.pow(base, timePercent) - 1) / (base - 1) * pathLength);

            return currentPos + "px";
        }
    }, function (element) {
        element.style.left = "128px";
    });

};
var JobType = function () {
    if (!(this instanceof JobType)) {
        return new JobType(arguments[0]);
    };
    var arg = arguments[0];
    this.fn = arg["fn"];
    this.delay = arg["delay"];
    this.startTime = arg["startTime"];
    this.comment = arg["comment"];
    this.elapsed = 0;
};
function JobManager() {
    if (!(this instanceof JobManager)) {
        return new JobManager();
    };
    var instance;
    JobManager = function () {
        return instance;
    };
    JobManager.prototype = this;
    instance = new JobManager();
    instance.constructor = JobManager;
    var jobQueue = [];
    var startedFlag = false;
    var inProcess = false;
    var currentJob = null;
    var timerID = -1;
    var start = function () {
        if (jobQueue.length) {
            startedFlag = true;
            currentJob = jobQueue.shift();
            var startOver = currentJob.delay - ((new Date()).getTime() - currentJob.startTime);
            timerID = setTimeout(function () {
                inProcess = true;
                currentJob.fn();
                if (jobQueue.length) {
                    try {
                        while ((jobQueue[0].delay - ((new Date()).getTime() - currentJob.startTime)) <= 0) {
                            currentJob = jobQueue.shift();
                            currentJob.fn();
                        };
                    }
                    catch (e) { };
                }
                inProcess = false;
                start();
            }, (startOver > 0 ? startOver : 0));
        }
        else {
            startedFlag = false;
            timerID = -1;
        };
    };
    instance.add = function (newJob) {
        if (newJob instanceof JobType) {
            stopCurrent();
            var jobQueueLength = jobQueue.length;
            if (!jobQueueLength) {

                jobQueue.push(newJob);
            }
            else {
                var currentTime = (new Date()).getTime(),
                    insertedFlag = false;
                for (var i = 0; i < jobQueueLength; i++) {
                    var tempJob = jobQueue[i],
                        tempJobElapsed = currentTime - tempJob["startTime"],
                        tempJobDelay = tempJob["delay"] - tempJobElapsed;
                    tempJob["elapsed"] = tempJobElapsed;
                    if (newJob["delay"] <= tempJobDelay) {
                        if (!insertedFlag) {
                            jobQueue.splice(i, 0, newJob);
                            insertedFlag = true;
                        }
                    };
                    if (i === (jobQueueLength - 1)) {
                        if (!insertedFlag) {
                            jobQueue.push(newJob);
                            insertedFlag = true;
                        }
                    }
                };
            };
            if ((!startedFlag) && (!inProcess)) {
                start();
            };
            return true;
        }
        else {
            return false;
        };
    };
    var stopCurrent = function () {
        if (timerID >= 0) {
            if (!inProcess) {
                clearTimeout(timerID);
                timerID = -1;
                if (currentJob) {
                    jobQueue.unshift(currentJob);
                };
            };
            startedFlag = false;
        };
    };
    return instance;
};
function animateCSS(element, duration, animation, whendone) {
    var frame = 0,
        elapsedTime = 0,
        timePercent = 0,
        startTime = new Date().getTime(),
        endTime = startTime + duration,
        fps = 0,
        averageRenderTime = 1000,
        normalRenderTime = 1000 / 25,
        myJobManager = JobManager();
    var inQueue = myJobManager.add(JobType({
        "fn": displayNextFrame,
        "delay": 0,
        "startTime": (new Date).getTime(),
        "comment": "start new animation"
    }));
    function playFrame() {
        for (var cssprop in animation) {
            try {
                element.style[cssprop] = animation[cssprop].call(element, timePercent, frame);
            } catch (e) { }
        };
    };
    function displayNextFrame() {
        elapsedTime = (new Date().getTime()) - startTime;
        timePercent = elapsedTime / duration;
        if (elapsedTime >= duration) {
            playFrame();
            if (whendone) {
                whendone(element);
            };
            return;
        };

        playFrame();
        frame++;
        averageRenderTime = elapsedTime / frame;
        fps = 1000 / averageRenderTime;
        inQueue = myJobManager.add(JobType({
            "fn": displayNextFrame,
            "delay": (fps < 15 ? 0 : normalRenderTime - averageRenderTime),
            "startTime": (new Date).getTime(),
            "comment": frame
        }));
    }
};
(function () {
    if (this.addEventListener) {
        this.addEventListener("load", init, false)
    }
    else {
        window.onload = init;
    }
}());

0
// By Plain Javascript
// this code will work on most of browsers. 
function hasClass(ele, clsName) {
    var el = ele.className;
    el = el.split(' ');
    if(el.indexOf(clsName) > -1){
        var cIndex = el.indexOf(clsName);
        el.splice(cIndex, 1);
        ele.className = " ";
        el.forEach(function(item, index){
          ele.className += " " + item;
        })
    }
    else {
        el.push(clsName);
        ele.className = " ";
        el.forEach(function(item, index){
          ele.className += " " + item;
        })
    }
}

var btn =  document.getElementById('btn');
var ele = document.getElementById('temp');

btn.addEventListener('click', function(){
    hasClass(ele, 'active')
})

-1

我没有测试,但是下面的代码应该可以工作。

<script>

function toggleClass(){
      var element = document.getElementById("a");
      element.classList.toggle("b");
    }
    document.getElementById("c").addEventListener('click', toggleClass )

</script>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接