Tengo una sección en mi sitio web que contiene todo el contenido, pero quiero que una "barra lateral" con contenido oculto aparezca suavemente desde la izquierda con solo presionar un botón externo.

Las transiciones CSS pueden manejar la suavidad sin problemas, y jQuery toggle() puede cambiar entre clases para mover el div oculto dentro y fuera de la pantalla.

¿Cómo puedo obtener el mismo efecto sin usar jQuery?

29
KittenCodings 28 ago. 2014 a las 12:14

7 respuestas

La mejor respuesta

Puede implementarlo solo con CSS3:

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

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

Y la parte CSS:

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

label {
    cursor: pointer;
}

#showblock {
    display: none;
}

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

La magia es el selector oculto checkbox y :checked en CSS.

Demostración jsFiddle de trabajo .

35
dashtinejad 28 ago. 2014 a las 08:25
// 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')
})
0
Nikhil 15 nov. 2016 a las 08:16

Puede alternar clases utilizando el classList.toggle() función:

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
});

Eso debería hacer todo lo que necesita: si tiene más de un activador, recomendaría usar document.querySelectorAll(selector) en su lugar.

27
TylerH 24 ene. 2020 a las 14:36
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
Greck 28 ago. 2014 a las 08:42

Puede obtener cualquier elemento por id con javascript (sin jquery) y la clase es un atributo: element.className, así que tenga esto como una función:

ACTUALIZACIÓN: Como esto se está volviendo algo popular, actualicé la función para mejorarla.

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();
}
5
Dávid Molnár 16 may. 2017 a las 06:53

SOLO HTML

Puedes usar <summary>. El siguiente código no tiene ninguna dependencia. Sin JavaScript, CSS en absoluto, solo 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>

Para obtener más detalles, vaya a documentos oficiales de MDN.

0
MiaeKim 1 feb. 2019 a las 22:15

No probé pero el código a continuación debería funcionar.

<script>

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

</script>
0
Nuriddin Kudratov 1 feb. 2019 a las 23:22