超轻的expand-collapse javascript解决方案?

时间:2012-02-16 00:35:21

标签: javascript toggle

当我点击“切换”文字时,如何打开/关闭内容div?

<div class="toggle col">TOGGLE

  <div class="content-to-toggle">
    content
  </div>
</div>

是否有比这个更轻的版本:

document.addEventListener('click', function(e){
  if(e.target.className.indexOf('toggle') !== -1)
    e.target.className = e.target.className.replace(/\bexp\b|\bcol\b/, function(m){ return m == 'col' ? 'exp' : 'col'; });
});

2 个答案:

答案 0 :(得分:4)

该功能有一些缺陷:

  1. addEventListener 将在IE 8及更低版本
  2. 等浏览器中失败
  3. e.target将在IE 8及更低版本
  4. 等浏览器中失败
  5. indexOf('toggle')会在类值的任何位置匹配toggle,最好使用regualr exprssion,例如:/(^ | \ s)toggle(\ s | $)/
  6. replace(/\bexp\b|\bcol\b/使用分词作为分隔符,但类值用空格分隔,而不是分隔符(如连字符)
  7. 最后,“ligther”是什么意思?更少的代码?快点?使用更少的资源?

    修改

    该函数的更好版本将使用:

    1. 一种附加侦听器的跨浏览器方法(有许多通用的 addListener 函数)
    2. 确定是否应切换类值的通用方法(简单的 hasClass 函数)
    3. 删除一个类值并添加另一个(简单 removeClass addClass 函数)的通用方法
    4. 如果元素没有任何一个类,它应该有一个分支来说明该做什么 - 它应该默认为一个还是另一个或什么都不做?

      所以这是一个例子:

      <title>Toggling Example</title>
      
      <style type="text/css">
        .exp {background-color: #666666;}
        .col {background-color: #bbbbbb;}
      </style>
      
      <script type="text/javascript">
      
      // Generic container for utility functions
      var util ={};
      
      util.trim = function(s) {
        return s.replace(/(^\s+)|(\s+$)/g,'').replace(/\s+/g,' ');
      }
      
      // Generic container for DOM functions
      util.dom = {};
      
      util.dom.hasClass = function(el, cName) {
          var re = new RegExp('(^|\\s+)' + cName + '(\\s+|$)');
          return el && re.test(el.className);
      };
      
      util.dom.addClass = function(el, cName) {
          if (!util.dom.hasClass(el, cName)) {
              el.className = util.trim(el.className + ' ' + cName);
          }
      };
      
      util.dom.removeClass = function(el, cName) {
          if (util.dom.hasClass(el, cName)) {
              var re = new RegExp('(^|\\s+)' + cName + '(\\s+|$)','g');
              el.className = util.trim(el.className.replace(re, ''));
          }
      }
      
      // Generic container for DOM event functions
      util.event = {};
      
      util.event.addListener = function(el, evt, fn) {
        if (el.addEventListener) {
          el.addEventListener(evt, fn, false);
        } else if (el.attachEvent) {
          el.attachEvent('on' + evt, fn);
        }
      }
      
      function toggleClass(el, c0, c1) {
      
        // Replace c0 with c1
        if (util.dom.hasClass(el, c0)) {
          util.dom.removeClass(el, c0);
          util.dom.addClass(el, c1);
      
        // Replace c1 with c0
        } else if (util.dom.hasClass(el, c1)) {
          util.dom.removeClass(el, c1);
          util.dom.addClass(el, c0);
      
        // If doesn't have either class, add c0
        } else {
          util.dom.addClass(el, c0);
        }
      }
      
      // Is this "light" enough?
      window.onload = function() {
        util.event.addListener(document.body, 'click', function(e) {
          var e = e || window.event;
          var el = e.target || e.srcElement;
          toggleClass(el, 'exp', 'col');
        });
      }
      
      </script>
      
      <div>foo bar</div>
      

      编辑2

      “少代码”绝不是做任何事情的好理由,尽管这是一个合理的目标,它不会混淆或降低清晰度。无论如何,这是原版的“更好”版本:

      document.addEventListener('click', function(e){
         var el = e.target, cn = el.className;
         if(/(^|\s)toggle(\s|$)/.test(cn))
           el.className = cn.replace(/(^|\s)exp|col(\s|$)/, function(m){ return m == 'col' ? 'exp' : 'col';});
      });
      

      效率更高,并为类名值使用标准分隔符。

答案 1 :(得分:1)

我更喜欢

document.addEventListener('click', function(e) {
    var cl = e.target.classList;
    if (cl.contains('toggle')) {
         cl.toggle("exp");
         cl.toggle("col");
    }
});

但许多浏览器都不支持它: - (