Javascript 带有类列表的代码在IE中不起作用?

Javascript 带有类列表的代码在IE中不起作用?,javascript,internet-explorer,Javascript,Internet Explorer,我正在使用下面的代码,但在IE中失败了。 信息是: 无法获取属性“add”的值:对象为null或未定义 我想这只是一个IE支持问题。你如何让下面的代码在IE中工作 有什么想法吗 var img = new Image(); img.src = '/image/file.png'; img.title = 'this is a title'; img.classList.add("profilePic"); var div = document.createElement("div"); div.

我正在使用下面的代码,但在IE中失败了。 信息是:

无法获取属性“add”的值:对象为null或未定义

我想这只是一个IE支持问题。你如何让下面的代码在IE中工作

有什么想法吗

var img = new Image();
img.src = '/image/file.png';
img.title = 'this is a title';
img.classList.add("profilePic");
var div = document.createElement("div");
div.classList.add("picWindow");
div.appendChild(img);
content.appendChild(div);
IE9及更低版本不支持该属性。不过IE10+支持它。 使用className+=。。相反注意:不要忽略空格:类名应添加在以空格分隔的列表中

var img = new Image();
img.src = '/image/file.png';
img.title = 'this is a title';
img.className += " profilePic"; // Add profilePic class to the image

var div = document.createElement("div");
div.className += " picWindow";  // Add picWindow class to the div
div.appendChild(img);
content.appendChild(div);
IE<9中不支持类列表。使用或像其他人提到的那样使用polyfill,IE9及更早版本不支持classList。除了上面Alex的备选方案外,还有两个PolyFill,其目的是作为替代品,也就是说,只要在你的页面中包含这些,IE就可以使用著名的“最后的话!”

看看这个

Object.defineProperty(Element.prototype, 'classList', {
    get: function() {
        var self = this, bValue = self.className.split(" ")

        bValue.add = function (){
            var b;
            for(i in arguments){
                b = true;
                for (var j = 0; j<bValue.length;j++)
                    if (bValue[j] == arguments[i]){
                        b = false
                        break
                    }
                if(b)
                    self.className += (self.className?" ":"")+arguments[i]
            }
        }
        bValue.remove = function(){
            self.className = ""
            for(i in arguments)
                for (var j = 0; j<bValue.length;j++)
                    if(bValue[j] != arguments[i])
                        self.className += (self.className?" " :"")+bValue[j]
        }
        bValue.toggle = function(x){
            var b;
            if(x){
                self.className = ""
                b = false;
                for (var j = 0; j<bValue.length;j++)
                    if(bValue[j] != x){
                        self.className += (self.className?" " :"")+bValue[j]
                        b = false
                    } else b = true
                if(!b)
                    self.className += (self.className?" ":"")+x
            } else throw new TypeError("Failed to execute 'toggle': 1 argument required")
            return !b;
        }

        return bValue; 
    },
    enumerable: false
})

就这些

在IE 10&11中,类列表属性是在HTMLElement.prototype上定义的

    /**
 * Method that checks whether cls is present in element object.
 * @param  {Object} ele DOM element which needs to be checked
 * @param  {Object} cls Classname is tested
 * @return {Boolean} True if cls is present, false otherwise.
 */
function hasClass(ele, cls) {
    return ele.getAttribute('class').indexOf(cls) > -1;
}

/**
 * Method that adds a class to given element.
 * @param  {Object} ele DOM element where class needs to be added
 * @param  {Object} cls Classname which is to be added
 * @return {null} nothing is returned.
 */
function addClass(ele, cls) {
    if (ele.classList) {
        ele.classList.add(cls);
    } else if (!hasClass(ele, cls)) {
        ele.setAttribute('class', ele.getAttribute('class') + ' ' + cls);
    }
}

/**
 * Method that does a check to ensure that class is removed from element.
 * @param  {Object} ele DOM element where class needs to be removed
 * @param  {Object} cls Classname which is to be removed
 * @return {null} Null nothing is returned.
 */
function removeClass(ele, cls) {
    if (ele.classList) {
        ele.classList.remove(cls);
    } else if (hasClass(ele, cls)) {
        ele.setAttribute('class', ele.getAttribute('class').replace(cls, ' '));
    }
}
为了让它在SVG元素上工作,应该在Element.prototype上定义该属性,就像在其他浏览器上一样

一个非常小的修复方法是将确切的propertyDescriptor从HtmleElement.prototype复制到Element.prototype:

if (!Object.getOwnPropertyDescriptor(Element.prototype,'classList')){
    if (HTMLElement&&Object.getOwnPropertyDescriptor(HTMLElement.prototype,'classList')){
        Object.defineProperty(Element.prototype,'classList',Object.getOwnPropertyDescriptor(HTMLElement.prototype,'classList'));
    }
}
我们需要复制描述符,因为Element.prototype.classList=HtmleElement.prototype.classList将抛出无效的调用对象 第一个检查可防止覆盖本机支持的浏览器上的属性。 第二个检查是防止在9之前的IE版本上出现错误,其中HTMLElement尚未实现,而在IE9上未实现classList。 对于IE 8和9,请使用以下代码,我还为Array.prototype.indexOf包含了一个缩小的polyfill,因为IE 8不支持它本机的polyfill源:


在Explorer 11中,classList.add仅适用于单个值

Element.classList.add("classOne", "classTwo");
在这种情况下,资源管理器只添加第一个类,而忽略第二个类。因此,我们需要做:

Element.classList.add("classOne");
Element.classList.add("classTwo");


IE没有类列表,因此它是空的或未定义的。你想不想使用jQuery?@Zero21xxx不介意,但这需要我重写上面的所有代码,以使用jQuery对象而不是标准JS。我写了一些。@alex你的博客文章可以更新一下。首先,最后一个链接MDN是错误的,querySelector应该是classList。其次,.remove方法包含一个不必要的RegExp,正如您所承认的,它的使用引入了一个bug。因为您已经使用了前置空格和后缀空格,一个简单的.replace'+className+''就足够了。此外,有效类名的备注不应该包含任何特殊的正则表达式字符。是不正确的,有关详细信息,请参见HTML4@MikeChristensenclassName属性始终存在。它初始化为空字符串。为便于代码维护,建议使用+=添加类名。在严格模式下,这会产生错误,因为类名是只读的。@Jasonaler这不太可能,DOM元素的className属性是读写的。classList上仍有IE11 bug,它不支持SVG元素上的类列表。jQuery也不能将类添加到SVG元素,因此,如果您想操作SVG,上面的解决方案似乎是唯一可行的方法。无论是谁否决了这一点:在发布答案时,这是正确的,只有IE9开始支持它,我猜它被否决了,因为这个问题没有要求jQuery。有一些解决问题的方法不需要使用整个Javascript库。。正当让我们将100KB库添加到类列表中functionality@tereško它确实会说或类似的话,以防您还没有使用jQuery。请注意,接受的答案可能会添加两次相同的类名,因为它不会检查它是否已经存在。我使用的是IE 11,而类列表在chromeThat's strange中似乎不起作用-caniuse.com说它应该得到IE10+的支持。我建议在Twitter上询问@TheWebJustWorks,或者在@johnktejik上提交一个问题。如果你同时添加或删除多个类,那么它在IE11、Firefox 24和Chrome 24中都不起作用。“你就是这么做的吗?”布拉德亚当斯和。Caniuse和MDN也有报告。不过,所有这些问题都已在Microsoft Edge中修复!SVG元素仍然不支持classList,这些多边形填充完成了一项任务。我应该把上面的东西放在哪里?在或中,我将这段代码插入到了一个脚本块中,正好位于有问题的代码上方,效果非常好。谢谢。做得好,不幸的是,这并不是在所有情况下都适用于我,但我确实发现了这一点:第一个代码把它剪掉了,但缺少了两个结束括号。@superdweebie,谢谢注意。我已经修正了我的答案+1,但是:我让ele.getAttribute'class'在某些情况下返回null,如果class属性还没有设置的话一个简单的if语句解决了这个问题。
Element.classList.add("classOne", "classTwo");
Element.classList.add("classOne");
Element.classList.add("classTwo");