【问题标题】:Toggle sidebar div with another div using CSS/Javascript使用 CSS/Javascript 将侧边栏 div 与另一个 div 切换
【发布时间】:2013-01-05 04:48:10
【问题描述】:

这是我的情况:

所以我试图通过单击另一个 div 来切换侧边栏。它是一个 100% 高度的侧边栏,固定在视口的右侧。本质上,我试图在 50px 宽的切换 div 和 250px 宽的侧边栏 div 周围包裹一个 300px 的 div,并且我想使用负边距右像素值隐藏侧边栏部分。使用 .toggle:active 选择器(当单击切换 div 时会发生这种情况),我想通过将边距右像素值设置回 0px 来显示侧边栏部分。

到目前为止的代码:

<div class="wrapper">
  <a href="#">
    <div class="toggle">Toggle</div>
  </a>
  <div class="cart">Cart</div>
</div>

到目前为止的 CSS:

.wrapper {
  position:fixed;
  width:300px;
  height:100%;
  background-color:orange;
  top:0;
  right:0;
  margin-right:-250px;
}
.toggle {
  position:relative;
  display:block;
  width:50px;
  height:100%;
  background-color:grey;
  float:left;
}
.toggle:active .wrapper {
  margin-right:0px;
}
.cart {
  position: relative;
  width:250px;
  height:100%;
  background-color:red;
  float:right;
}

Here's the jsfiddle!

这是我的问题:

当使用 .toggle:active 时,我如何定位 .wrapper 来更改 css 属性?另外,如何指定侧边栏何时可见,何时不可见?

我是 Javascript 新手,但由于回调函数,我似乎需要它来执行此操作。如果 CSS-only 是可能的,我会倾向于那个解决方案。请注意,我想使用 margin-right 以便稍后我可以选择使用 CSS 过渡来动画我的元素左右滑动。

【问题讨论】:

    标签: javascript css toggle


    【解决方案1】:

    纯 CSS 解决方案

    演示:http://jsfiddle.net/Victornpb/yJYJC/30/

    就用这个吧:

    /* Closed */
    .wrapper{
        margin-right:-250px; 
    }
    
    /* Opened */
    .wrapper:hover{
        margin-right:0px;
    }
    

    Javascript 解决方案

    演示:http://jsfiddle.net/Victornpb/yJYJC/6/

    JS:

    var wrapper = document.getElementsByClassName('wrapper')[0];
    var toggle = document.getElementsByClassName('toggle')[0];
    
    window.onload=function(){
    
        toggle.onclick=function(){
            wrapper.classList.toggle('opened'); 
        }
    
    }
    

    CSS:

    .wrapper{
        position:fixed;
        width:300px;
        height:100%;
        background-color:orange;
        top:0;
        right:0;
        margin-right:-250px;
    }
    .wrapper.opened{
        margin-right:0px;
    }
    

    【讨论】:

    【解决方案2】:

    纯 CSS 解决方案 (DEMO):

    <div class="wrapper">    
      <label for="toggle">
         Toggle
      </label>    
      <input id="toggle" type="checkbox" />
      <div class="cart">Cart</div>
    </div>
    

    (隐藏的复选框用于确定切换状态)

    #toggle {    
      display:none; /* hide checkbox */
    }
    
    /* the label associated with the checkbox (trigger) */
    label{
      display:block;
    }
    
    /* move the div adjacent to the input (.cart) inside the visible area */
    /* when the input is checked */
    #toggle:checked ~ .cart{
      right:0;
    }
    
    /* the div that's being toggled */
    .cart {
      position: absolute;
      width: 250px;
      height: 100%;
      right: -250px;
    }
    

    【讨论】:

    【解决方案3】:

    :active 仅适用于链接(即&lt;a&gt; 标签),因此它不能用于.toggle,因为它是&lt;div&gt;。即使你把它放在链接上,我认为它不会做你想做的事,也没有办法“瞄准”父母。 像这样在 &lt;div&gt; 周围有一个 &lt;a&gt; 也很奇怪,你不应该需要它。

    所以,你需要 javascript,是的。但是您不能真正针对 javascript 中的类。您有两种解决方案:

    1. 如果您可以将id 添加到包装器中,您可以在javascript 中创建一个函数来切换侧边栏的状态:

      <div class="wrapper" id="myId">
          <a href="#">
              <div class="toggle"
                   onclick="document.getElementById('myId').style.marginRight = (document.getElementById('myId').style.marginRight == '0') ? '-250px' : '0';">Toggle</div>
          </a>
          <div class="cart">Cart</div>
      </div>
      

      注意:(document.getElementById('myId').style.marginRight == '0') ? '-250px' : '0' 部分测试margin-right 是否为 0,如果是,则将其更改为 -250px,反之亦然。我在这里所做的可能不是最好的方法,但我想把它限制在简短的范围内,这样你就可以这样使用它,如果你不太了解 javascript。当您更好地了解它时,您将能够改进它。 此外,您必须将onclick 放在您拥有的每个.toggle div 上...您可以使用事件处理程序,但我很确定您不知道这是什么意思,这可能不是一个好主意只需复制粘贴即可。您始终可以使用第二点,因为它使事情相对容易理解。

    2. 如果你真的想要class(或者需要重复很多次),你将不得不使用jQuery, a javascript library,通过添加这个(最好在&lt;head&gt;中):

      <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.0.min.js"></script>
      

      然后你可以添加这个(最好还是在头部):

      <script type="text/javascript">
          $(document).ready( function()
          {
              var cart_visible = false;
      
              $('.toggle').on('click', function()
              {
                  if ( cart_visible )
                      $('.wrapper').css('margin-right', '-250px');
                  else
                      $('.wrapper').css('margin-right', '0');
      
                  cart_visible = !cart_visible;
              });
          });
      </script>
      

      这一次我使用布尔值(以truefalse 作为值)来检查购物车是否可见,并在每次点击时同时更改值margin-right。这和以前做的一样,只是在 -250px 和 0 之间切换,但你不需要把它放在你可能创建的每个 .toggle 中,它适用于一个类。虽然它让你使用 jQuery(虽然我认为这不是一个真正的问题)

    我真的不明白你为什么要改变margin-right虽然......如果你只是想让它消失,你可以使用display: none;,或者如果你真的想改变位置,你可以使用right(在这种情况下)。

    【讨论】:

    • 嗯,没错,我忘记了。不过,display: none 仍然可以用于此目的。我会编辑那个..
    【解决方案4】:

    仅 CSS,两个具有不同行为的侧边栏

    两种不同的仅CSS动画侧边栏:

    1. 灵感来自@vitim.us,使用悬停进行显示/隐藏
    2. 灵感来自@niceass,使用隐藏的复选框单击显示/隐藏

    特点:

    • 流畅的动画
    • 侧边栏上的垂直文本(打开时旋转)
    • 显示侧边栏时调整正文大小
    • 用于主体和侧边栏的清洁盒
    • 可滚动的侧边栏内容(显示他的滚动条)。

    hover(从 @vitim.us's answer 派生)有一些改进

    如果没有完全敲定,有办法

    • Open cart / Your cart 垂直
    • 通过在 CSS 中使用 no-breakable space,在 Open/Yourcart 之间抑制 换行
    • 在显示侧边栏时动态调整主要内容的大小。

    body {
        font-family: sans;
        font-weight: normal;
        font-size: 10pt;
    }
    .main {
        width: calc( 100% - 3em );
        transition: width ease 1300ms;
    }
    .wrapper:hover ~ .main {
        width: calc( 100% - 17em );
    }
    h1 {
        font-weight: bold;
        font-size: 1.3 em;
    }
    h2 {
        font-weight: bold;
        font-size: 1.15 em;
    }
    .wrapper{
        position:fixed;
        width: 16em;
        height:100%;
        background-color:orange;
        top:0;
        right:0;
        margin-right:-14em;
        /* Makes opening smoothly */
        transition: margin-right ease 1300ms;
        -moz-transition: margin-right ease 1300ms;
        -webkit-transition: margin-right ease 1300ms;
        -o-transition: margin-right ease 1300ms;
    }
    .inner {
        position: relative;
        width: 100%;
        float: left;
        display: inline-block;
        transform: rotate(90deg)  translate(-3em,0em);
        transition: transform ease 1300ms;
    }
    
    /* opened */
    .wrapper.opened,
    .wrapper:hover{
        margin-right:0px;
    }
    
    .toggle {
      position:relative;
        display:block;
        width:2em;
        height:100%;
        background-color:#CCC;
        float:left;
        font-weight: bold;
        text-align: center;
        padding-top: 50%;
        transition: background-color ease 1300ms;
        transition: color ease 1300ms;
    }
    
    /* toggle style when wrapper is hovered */
    .wrapper:hover .toggle{
        background-color: #555;
        color: white;
    }
    .wrapper:hover .toggle .inner{
        transform: rotate(270deg);
    }
    /* Warn: there is NBSP, not spaces, after Open/Your */
    .wrapper:not(:hover) .toggle .inner:before{
        content:"Open";
    }
    .wrapper:hover .toggle .inner:before{
        content:"Your";
    }
    
    .cart {
        position: relative;
        width:13.5em;
        height:100%;
        background-color:rgba(255,255,255,.4);
        float:right;
        padding: .2em;
        overflow: scroll;
    }
    <div class="wrapper">
        <div class="toggle"><div class="inner">&nbsp;cart</div></div>
        <div class="cart">
            <h2>Cart</h2>
            <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.
           </p>
        </div>
    </div>
    <div class="main">
    <h1>Little <i>no-js</i> css side-bar demo</h1>
    <p>This little demo let you see how a side-bar could be done without being using javascript...</p>
     <h2>Lorem Ipsum</h2>   <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.</p>
    <p>Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
       </p>
    
    </div>

    toggle:checked(来自@niceass's answer

    同样的改进,但使用了一个不可见的复选框,因此您必须点击侧边栏的(文本)才能打开它们。

    (这个答案链接到What does "for" attribute do in HTML tag?

    body {
        font-family: sans;
        font-weight: normal;
        font-size: 10pt;
    }
    #toggle { display:none; }
    .main {
        width: calc( 100% - 3em );
        transition: width ease 1300ms;
    }
    #toggle:checked ~ .main {
        width: calc( 100% - 17em );
    }
    h1 {
        font-weight: bold;
        font-size: 1.3 em;
    }
    h2 {
        font-weight: bold;
        font-size: 1.15 em;
    }
    .wrapper{
        position:fixed;
        width: 16em;
        height:100%;
        background-color:orange;
        top:0;
        right:0;
        margin-right:-14em;
        /* Makes opening smoothly */
        transition: margin-right ease 1300ms;
        -moz-transition: margin-right ease 1300ms;
        -webkit-transition: margin-right ease 1300ms;
        -o-transition: margin-right ease 1300ms;
    }
    #toggle:checked ~ .wrapper {
        margin-right: 0pt;
    }
    #but {
        position: relative;
        width: 100%;
        float: left;
        display: inline-block;
        transform: rotate(270deg)  translate(-3em,0em);
        transition: transform ease 1300ms;
    }
    /* opened */
    #zone {
      position:relative;
        display:block;
        width:2em;
        height:100%;
        background-color:#CCC;
        float:left;
        font-weight: bold;
        text-align: center;
        padding-top: 50%;
        transition: background-color ease 1300ms;
        transition: color ease 1300ms;
    }
    
    /* toggle style when wrapper is hovered */
    #toggle:checked ~ .wrapper #zone {
        background-color: #555;
        color: white;
    }
    #toggle:checked ~ .wrapper #zone #but {
        color: white;
        transform: rotate(90deg);
    }
    #toggle:not(checked) ~ .wrapper #zone #but:before {
        content:"Open ";    /* non break space &#160; */
    }
    #toggle:checked ~ .wrapper #zone #but:before{
        content:"☒ Your ";
    }
    #toggle:not(checked) ~ .wrapper #zone #but:after {
        content:" ☐";        /* figure space &#8199; */
    }
    #toggle:checked ~ .wrapper #zone #but:after {
        content:"";
    }
    .cart {
        position: relative;
        width:13.5em;
        height:100%;
        background-color:rgba(255,255,255,.4);
        float:right;
        padding: .2em;
        overflow: scroll;
    }
    <input id="toggle" type="checkbox" />  
    <div class="wrapper">
        <div id="zone"><label for="toggle" id="but">chart</label></div>
        <div class="cart">
            <h2>Cart</h2>
          <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.
           </p>
        </div>
    </div>
    <div class="main">
    <h1>Little <i>no-js</i> css side-bar demo</h1>
    <p>This little demo let you see how a side-bar could be done without being using javascript...</p>
     <h2>Lorem Ipsum</h2>   <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.</p>
    <p>Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
       </p>
    
    </div>

    【讨论】:

    • 请注意,css calc 被认为是不好的做法,因为它会增加大量开销。
    • 是的!今天,我一直在鞭打虫子! cart 现在可以scrollable了,方法是将overflow:scroll 属性添加到 div cart。
    • @Vitim.us 我同意,不幸的是,这是正确计算侧边栏位置的唯一方法,因为 div 旋转了 90 度。
    【解决方案5】:

    我建议为此使用 jQuery。它很简单,出错的机会也更少。

    $('.toggle').click(function() {
        $('.cart').toggle();
    });
    

    http://api.jquery.com/toggle/

    【讨论】:

    • 这很好用,但我修改了它以满足我的需要(带有回调)。 The jsfiddle谢谢!
    • 我不喜欢使用整个臃肿的库来做这样一个基本的事情,因为你可以使用纯 js 或只使用 css 轻松地做到这一点。恕我直言
    • @Vitim.us 我同意你的看法。这很愚蠢,但我个人喜欢将 jQuery 用于此类事情。我在想,如果他有类似这样的其他功能,那么他也可以将它们切换到 jQuery,但是,如果这是唯一的实例,那么 js 或 CSS 会更好。
    猜你喜欢
    • 2011-07-31
    • 2015-09-05
    • 2011-02-12
    • 2014-01-26
    • 1970-01-01
    • 2021-09-29
    • 2011-07-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多