क्लासिस्ट के साथ कोड IE में काम नहीं करता है?


83

मैं निम्नलिखित कोड का उपयोग कर रहा हूं, लेकिन IE में यह विफल हो रहा है। संदेश है:

संपत्ति का मूल्य 'जोड़' पाने में असमर्थ: ऑब्जेक्ट अशक्त या अपरिभाषित है "

मुझे लगता है कि यह सिर्फ एक 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);

5
IE में क्लासिस्ट नहीं है, इसलिए यह अशक्त या अपरिभाषित है
Esailija

2
क्या आप jQuery का उपयोग करना चाहते हैं या नहीं?
arb

1
@ Zero21xxx इसे बुरा मत मानिए, लेकिन मुझे जेएस की वस्तुओं के मानक जेएस के बजाय उपयोग करने के लिए उपरोक्त सभी कोड को फिर से लिखना होगा।
वेस्ले


1
@alex आपका ब्लॉग पोस्ट अपडेट के साथ कर सकता है। सबसे पहले, अंतिम लिंक (MDN) गलत है, querySelectorहोना चाहिए classList। दूसरा, .removeविधि में एक अनावश्यक RegExp है, जिसका उपयोग -as आपने स्वीकार किया है- एक बग का परिचय देता है। क्योंकि आप पहले से ही पूर्व और प्रत्यय रिक्त स्थान पर हैं, एक साधारण .replace(' ' + className + ' ', ' ')पर्याप्त है (इसके अलावा, टिप्पणी "एक मान्य वर्गनाम में कोई विशेष regex वर्ण नहीं होना चाहिए।" गलत है, देखें युक्ति (HTML4 के लिए भी सच है))
Rob W

जवाबों:


92

classListसंपत्ति 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);

3
@MikeChristensen classNameविशेषता हमेशा मौजूद रहती है। इसे एक खाली स्ट्रिंग पर आरंभीकृत किया जाता है। आसान कोड रखरखाव के लिए, +=वर्ग नामों को जोड़ने की सलाह दी जाती है।
डब्ल्यू पर रॉ डब्ल्यू डब्ल्यू

2
सख्त मोड में यह एक त्रुटि उत्पन्न करता है क्योंकि क्लासनेम केवल पढ़ा जाता है।
जेसन एलर

1
@ जैसनऑलर जो अत्यधिक संभावना नहीं है, classNameएक डोम तत्व की संपत्ति पठन-लेखन है।
डब्ल्यू पर रोब डब्ल्यू

47
IE11 अभी भी क्लासिस्ट पर बग है, यह एसवीजी तत्व पर क्लासलिस्ट का समर्थन नहीं करता है।
कोडेनेज़ेरो

1
और jQuery एसवीजी तत्वों के लिए कक्षाएं नहीं जोड़ सकता है और साथ ही ऊपर से समाधान केवल संभव चीज की तरह दिखता है यदि आप एसवीजी में हेरफेर करना चाहते हैं।
सेंथे

26

जैसा कि othes द्वारा उल्लेख किया गया है, classListIE9 और पुराने द्वारा समर्थित नहीं है। ऊपर एलेक्स के विकल्प के साथ-साथ, पॉलीफ़िल के एक जोड़े हैं जो एक ड्रॉप-इन रिप्लेसमेंट होने का लक्ष्य रखते हैं, यानी बस इन्हें अपने पेज में शामिल करें और IE को बस काम करना चाहिए (प्रसिद्ध अंतिम शब्द!)।

https://github.com/eligrey/classList.js/blob/master/classList.js

https://gist.github.com/devongovett/1381839


11
मैं IE 11 का उपयोग कर रहा हूं और क्लासिस्ट काम नहीं कर रहा है (क्रोम में काम करता है)
जॉन ktejik

1
यह अजीब है - caniuse.com का कहना है कि इसे IE10 + से समर्थित होना चाहिए। मेरा सुझाव है कि ट्विटर पर @TheWebJustWorks पूछें या webcompat.com पर एक मुद्दा दर्ज करें
tagawa

3
@johnktejik यदि आप एक साथ कई कक्षाएं जोड़ते या हटाते हैं, तो यह IE11, Firefox 24- और Chrome 24- में काम नहीं करेगा। क्या आप वही कर रहे थे?
22

1
@BradAdams यहाँ और यहाँ । कैन्य्यूज़ और एमडीएन की भी रिपोर्ट है। उन सभी मुद्दों को Microsoft Edge में तय किया गया है, हालाँकि!
mnsth

2
क्लासिस्ट को अभी भी एसवीजी तत्वों का समर्थन नहीं है, ये पॉलीफ़िल चाल करते हैं
शॉपलिफ़्टर.डॉ।

10
    /**
 * 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, ' '));
    }
}

2
+1, हालाँकि: मैं ele.getAttribute('class')कुछ मामलों में अशक्त हो गया था (हो सकता है कि यदि वर्ग विशेषता अभी तक सेट नहीं हुई है?) - एक सरल अगर कथन ने इसे हल किया।
जेपी

8

इसकी जांच करें

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

और क्लासिस्ट काम करेगा!

document.getElementsByTagName("div")[0].classList
["aclass"]

document.getElementsByTagName("div")[0].classList.add("myclass")

document.getElementsByTagName("div")[0].className
"aclass myclass"

बस इतना ही!


मैं एक noob हूँ। मैं ऊपर कहां रखूं? <स्क्रिप्ट में> या <शैली> में?
Fandango68

मैंने इस कोड को आपत्तिजनक कोड के ठीक ऊपर एक स्क्रिप्ट ब्लॉक में डाला - बहुत अच्छा काम करता है। धन्यवाद।
लूटना

1
अच्छा काम, दुर्भाग्य से यह मेरे लिए सभी मामलों में काम नहीं करता है, मुझे यह एक बार मिला था: github.com/remy/polyfills/blob/…
मिचेल

7

IE 10 और 11 में, क्लासिस्ट संपत्ति को HTMLElement.prototype पर परिभाषित किया गया है।

एसवीजी-तत्वों पर काम करने के लिए इसे प्राप्त करने के लिए, संपत्ति को Element.prototype पर परिभाषित किया जाना चाहिए, जैसे कि यह अन्य ब्राउज़रों पर किया गया है।

एक बहुत छोटा फिक्स HTMLElement.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 = HTMLElement.prototype.classListफेंक देंगेInvalid calling object
  • पहला चेक ब्राउज़र पर संपत्ति को अधिलेखित करने से रोकता है जो समर्थन मूल रूप से है।
  • दूसरा चेक 9 से पहले IE संस्करणों पर त्रुटियों को रोकता है, जहां HTMLElement अभी तक लागू नहीं किया गया है, और IE9 पर जहां क्लासिस्ट लागू नहीं है।

IE 8 और 9 के लिए, निम्न कोड का उपयोग करें, मैंने Array.prototype.indexOf के लिए एक (minified) पॉलीफ़िल भी शामिल किया है, क्योंकि IE 8 मूल रूप से इसका समर्थन नहीं करता है (polyfill source: Array.prototype.indexOf

//Polyfill Array.prototype.indexOf
Array.prototype.indexOf||(Array.prototype.indexOf=function (value,startIndex){'use strict';if (this==null)throw new TypeError('array.prototype.indexOf called on null or undefined');var o=Object(this),l=o.length>>>0;if(l===0)return -1;var n=startIndex|0,k=Math.max(n>=0?n:l-Math.abs(n),0)-1;function sameOrNaN(a,b){return a===b||(typeof a==='number'&&typeof b==='number'&&isNaN(a)&&isNaN(b))}while(++k<l)if(k in o&&sameOrNaN(o[k],value))return k;return -1});

// adds classList support (as Array) to Element.prototype for IE8-9
Object.defineProperty(Element.prototype,'classList',{
    get:function(){
        var element=this,domTokenList=(element.getAttribute('class')||'').replace(/^\s+|\s$/g,'').split(/\s+/g);
        if (domTokenList[0]==='') domTokenList.splice(0,1);
        function setClass(){
            if (domTokenList.length > 0) element.setAttribute('class', domTokenList.join(' ');
            else element.removeAttribute('class');
        }
        domTokenList.toggle=function(className,force){
            if (force!==undefined){
                if (force) domTokenList.add(className);
                else domTokenList.remove(className);
            }
            else {
                if (domTokenList.indexOf(className)!==-1) domTokenList.splice(domTokenList.indexOf(className),1);
                else domTokenList.push(className);
            }
            setClass();
        };
        domTokenList.add=function(){
            var args=[].slice.call(arguments)
            for (var i=0,l=args.length;i<l;i++){
                if (domTokenList.indexOf(args[i])===-1) domTokenList.push(args[i])
            };
            setClass();
        };
        domTokenList.remove=function(){
            var args=[].slice.call(arguments)
            for (var i=0,l=args.length;i<l;i++){
                if (domTokenList.indexOf(args[i])!==-1) domTokenList.splice(domTokenList.indexOf(args[i]),1);
            };
            setClass();
        };
        domTokenList.item=function(i){
            return domTokenList[i];
        };
        domTokenList.contains=function(className){
            return domTokenList.indexOf(className)!==-1;
        };
        domTokenList.replace=function(oldClass,newClass){
            if (domTokenList.indexOf(oldClass)!==-1) domTokenList.splice(domTokenList.indexOf(oldClass),1,newClass);
            setClass();
        };
        domTokenList.value = (element.getAttribute('class')||'');
        return domTokenList;
    }
});

पहले कोड ने इसे अच्छा लिया, लेकिन दो समापन कोष्ठक गायब थे )
23 नवंबर को सुपरडेवेबी

@superdweebie, ध्यान देने के लिए धन्यवाद। मैंने अपना उत्तर तय कर लिया है
केविन ड्रॉस्ट

3

एक्सप्लोरर 11 में classList.add केवल एकल मानों के साथ काम करता है।

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

इस मामले में एक्सप्लोरर केवल प्रथम श्रेणी जोड़ता है और दूसरे को अनदेखा करता है। तो करने की जरूरत है:

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

0

classListIE <9. में समर्थित नहीं है । https://developer.mozilla.org/en-US/docs/Web/API/Element/classList पर jQuery.addClass या पॉलीफ़िल का उपयोग करें।


1
जिस किसी ने भी इसे अस्वीकार किया था: यह सच था जब जवाब पोस्ट किया गया था, और केवल IE 9 ने इसका समर्थन करना शुरू कर दिया
जुआन मेंडेस

2
मुझे लगता है कि यह ख़तरा था क्योंकि यह सवाल jQuery के लिए नहीं पूछा गया था। समस्याओं के आसपास ऐसे तरीके हैं जो संपूर्ण जावास्क्रिप्ट लाइब्रेरी का उपयोग नहीं करते हैं।
विंसेंट मैकनब

4
-1: हाँ .. सही है ... 100KB लाइब्रेरी को बुरी तरह से मिमिक classListकार्यक्षमता से जोड़ने की सुविधा देता है
tereško

1
यदि आप पहले से ही jQuery का उपयोग नहीं कर रहे हैं तो @ tereško यह "या ऐसा कुछ" कहता है। ध्यान दें कि स्वीकृत उत्तर एक ही वर्ग के नाम को दो बार जोड़ सकता है क्योंकि यह जाँच नहीं कर रहा है कि क्या यह पहले से मौजूद है।
जुआन मेंडेस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.