【问题标题】:ClassList does not work in IE9. need alternative functionClassList 在 IE9 中不起作用。需要替代功能
【发布时间】:2016-07-26 12:18:10
【问题描述】:

我无法在 IE9 中运行“W3Schools Accordion with symbols”。 ClassList 在 IE9 中不起作用。它给出了以下错误

SCRIPT5007:无法获取属性“toggle”的值:对象为空或未定义

我不是程序员。我需要替代功能,这样我就不需要重新创建我的 1000 行静态 HTML 页面。

这是我需要在 IE9 中运行的完整代码

<!DOCTYPE html>
<html>
<head>
<style>
button.accordion {
    background-color: #eee;
    color: #444;
    cursor: pointer;
    padding: 18px;
    width: 100%;
    border: none;
    text-align: left;
    outline: none;
    font-size: 15px;
    transition: 0.4s;
}

button.accordion.active, button.accordion:hover {
    background-color: #ddd;
}

button.accordion:after {
    content: '\02795';
    font-size: 13px;
    color: #777;
    float: right;
    margin-left: 5px;
}

button.accordion.active:after {
    content: "\2796";
}

div.panel {
    padding: 0 18px;
    background-color: white;
    max-height: 0;
    overflow: hidden;
    transition: 0.6s ease-in-out;
    opacity: 0;
}

div.panel.show {
    opacity: 1;
    max-height: 500px;
}
</style>
</head>
<body>

<h2>Accordion with symbols</h2>
<p>In this example we have added a "plus" sign to each button. When the user clicks on the button, the "plus" sign is replaced with a "minus" sign.</p>
<button class="accordion">Section 1</button>
<div class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>

<button class="accordion">Section 2</button>
<div class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>

<button class="accordion">Section 3</button>
<div id="foo" class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>

<script>
var acc = document.getElementsByClassName("accordion");
var i;

for (i = 0; i < acc.length; i++) {
    acc[i].onclick = function(){
        this.classList.toggle("active");
        this.nextElementSibling.classList.toggle("show");
  }
}
</script>

</body>
</html>

【问题讨论】:

    标签: javascript jquery internet-explorer-9


    【解决方案1】:

    当您使用 jQuery 标记问题时,您可以使用 toggleClass(),如下所示:

    $(".accordion").click(function(){
        $(this).toggleClass("active").next().toggleClass("show");
    });
    

    $(function() {
      $(".accordion").click(function() {
        $(this).toggleClass("active").next().toggleClass("show");
      });
    });
    button.accordion {
      background-color: #eee;
      color: #444;
      cursor: pointer;
      padding: 18px;
      width: 100%;
      border: none;
      text-align: left;
      outline: none;
      font-size: 15px;
      transition: 0.4s;
    }
    button.accordion.active,
    button.accordion:hover {
      background-color: #ddd;
    }
    button.accordion:after {
      content: '\02795';
      font-size: 13px;
      color: #777;
      float: right;
      margin-left: 5px;
    }
    button.accordion.active:after {
      content: "\2796";
    }
    div.panel {
      padding: 0 18px;
      background-color: white;
      max-height: 0;
      overflow: hidden;
      transition: 0.6s ease-in-out;
      opacity: 0;
    }
    div.panel.show {
      opacity: 1;
      max-height: 500px;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <h2>Accordion with symbols</h2>
    <p>In this example we have added a "plus" sign to each button. When the user clicks on the button, the "plus" sign is replaced with a "minus" sign.</p>
    <button class="accordion">Section 1</button>
    <div class="panel">
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
    </div>
    
    <button class="accordion">Section 2</button>
    <div class="panel">
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
    </div>
    
    <button class="accordion">Section 3</button>
    <div id="foo" class="panel">
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
    </div>

    【讨论】:

      【解决方案2】:

      没有 jQuery,you can use the following polyfill

      适用于 IE 8+

      /* 
       * classList.js: Cross-browser full element.classList implementation.
       * 2014-07-23
       *
       * By Eli Grey, http://eligrey.com
       * Public Domain.
       * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
       */
      
      /*global self, document, DOMException */
      
      /*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js*/
      
      if ("document" in self) {
      
      // Full polyfill for browsers with no classList support
      if (!("classList" in document.createElement("_"))) {
      
      (function (view) {
      
      "use strict";
      
      if (!('Element' in view)) return;
      
      var
          classListProp = "classList"
        , protoProp = "prototype"
        , elemCtrProto = view.Element[protoProp]
        , objCtr = Object
        , strTrim = String[protoProp].trim || function () {
          return this.replace(/^\s+|\s+$/g, "");
        }
        , arrIndexOf = Array[protoProp].indexOf || function (item) {
          var
              i = 0
            , len = this.length
          ;
          for (; i < len; i++) {
            if (i in this && this[i] === item) {
              return i;
            }
          }
          return -1;
        }
        // Vendors: please allow content code to instantiate DOMExceptions
        , DOMEx = function (type, message) {
          this.name = type;
          this.code = DOMException[type];
          this.message = message;
        }
        , checkTokenAndGetIndex = function (classList, token) {
          if (token === "") {
            throw new DOMEx(
                "SYNTAX_ERR"
              , "An invalid or illegal string was specified"
            );
          }
          if (/\s/.test(token)) {
            throw new DOMEx(
                "INVALID_CHARACTER_ERR"
              , "String contains an invalid character"
            );
          }
          return arrIndexOf.call(classList, token);
        }
        , ClassList = function (elem) {
          var
              trimmedClasses = strTrim.call(elem.getAttribute("class") || "")
            , classes = trimmedClasses ? trimmedClasses.split(/\s+/) : []
            , i = 0
            , len = classes.length
          ;
          for (; i < len; i++) {
            this.push(classes[i]);
          }
          this._updateClassName = function () {
            elem.setAttribute("class", this.toString());
          };
        }
        , classListProto = ClassList[protoProp] = []
        , classListGetter = function () {
          return new ClassList(this);
        }
      ;
      // Most DOMException implementations don't allow calling DOMException's toString()
      // on non-DOMExceptions. Error's toString() is sufficient here.
      DOMEx[protoProp] = Error[protoProp];
      classListProto.item = function (i) {
        return this[i] || null;
      };
      classListProto.contains = function (token) {
        token += "";
        return checkTokenAndGetIndex(this, token) !== -1;
      };
      classListProto.add = function () {
        var
            tokens = arguments
          , i = 0
          , l = tokens.length
          , token
          , updated = false
        ;
        do {
          token = tokens[i] + "";
          if (checkTokenAndGetIndex(this, token) === -1) {
            this.push(token);
            updated = true;
          }
        }
        while (++i < l);
      
        if (updated) {
          this._updateClassName();
        }
      };
      classListProto.remove = function () {
        var
            tokens = arguments
          , i = 0
          , l = tokens.length
          , token
          , updated = false
          , index
        ;
        do {
          token = tokens[i] + "";
          index = checkTokenAndGetIndex(this, token);
          while (index !== -1) {
            this.splice(index, 1);
            updated = true;
            index = checkTokenAndGetIndex(this, token);
          }
        }
        while (++i < l);
      
        if (updated) {
          this._updateClassName();
        }
      };
      classListProto.toggle = function (token, force) {
        token += "";
      
        var
            result = this.contains(token)
          , method = result ?
            force !== true && "remove"
          :
            force !== false && "add"
        ;
      
        if (method) {
          this[method](token);
        }
      
        if (force === true || force === false) {
          return force;
        } else {
          return !result;
        }
      };
      classListProto.toString = function () {
        return this.join(" ");
      };
      
      if (objCtr.defineProperty) {
        var classListPropDesc = {
            get: classListGetter
          , enumerable: true
          , configurable: true
        };
        try {
          objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
        } catch (ex) { // IE 8 doesn't support enumerable:true
          if (ex.number === -0x7FF5EC54) {
            classListPropDesc.enumerable = false;
            objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
          }
        }
      } else if (objCtr[protoProp].__defineGetter__) {
        elemCtrProto.__defineGetter__(classListProp, classListGetter);
      }
      
      }(self));
      
      } else {
      // There is full or partial native classList support, so just check if we need
      // to normalize the add/remove and toggle APIs.
      
      (function () {
        "use strict";
      
        var testElement = document.createElement("_");
      
        testElement.classList.add("c1", "c2");
      
        // Polyfill for IE 10/11 and Firefox <26, where classList.add and
        // classList.remove exist but support only one argument at a time.
        if (!testElement.classList.contains("c2")) {
          var createMethod = function(method) {
            var original = DOMTokenList.prototype[method];
      
            DOMTokenList.prototype[method] = function(token) {
              var i, len = arguments.length;
      
              for (i = 0; i < len; i++) {
                token = arguments[i];
                original.call(this, token);
              }
            };
          };
          createMethod('add');
          createMethod('remove');
        }
      
        testElement.classList.toggle("c3", false);
      
        // Polyfill for IE 10 and Firefox <24, where classList.toggle does not
        // support the second argument.
        if (testElement.classList.contains("c3")) {
          var _toggle = DOMTokenList.prototype.toggle;
      
          DOMTokenList.prototype.toggle = function(token, force) {
            if (1 in arguments && !this.contains(token) === !force) {
              return force;
            } else {
              return _toggle.call(this, token);
            }
          };
      
        }
      
        testElement = null;
      }());
      
      }
      
      }
      

      【讨论】:

        【解决方案3】:

        或者不使用 jQuery,您可以在第 1 次点击时添加所需的类,并在第 2 次点击时删除这些类。本质上是切换。

        这是使用模运算符 (%) 实现的,它为您提供要除的 2 个数字的余数 - 以确定计数 (i) 是奇数还是偶数。

        类似:

        for (i = 0; i < acc.length; i++) {
        acc[i].onclick = function () {
            if (i % 2 == 0) {
                this.classList.addClass("active");
                this.nextElementSibling.addClass("show");
            } else {
                this.classList.removeClass("active");
                this.nextElementSibling.removeClass("show");
            }
        
           }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多