DOM एट्रिब्यूट अब प्रोटोटाइप चेन में शामिल हैं

पॉल किनलन
पॉल किनलन

Chrome टीम ने हाल ही में एलान किया था कि हम डीओएम प्रॉपर्टी को प्रोटोटाइप चेन में ले जा रहे हैं. Chrome 43 - (अप्रैल 2015 के मध्य से बीटा वर्शन) में लागू किया गया यह बदलाव - Chrome को Web IDL स्पेसिफ़िकेशन और अन्य ब्राउज़र जैसे कि IE और Firefox के साथ और ज़्यादा काम करता है. बदलाव करें: साफ़ तौर पर बताया गया वेबकिट पर आधारित पुराने ब्राउज़र, फ़िलहाल इस स्पेसिफ़िकेशन के साथ काम नहीं करते हैं. हालांकि, अब Safari को लागू कर दिया जाएगा.

नया व्यवहार कई मायनों में सकारात्मक है. इससे:

  • निर्देशों के अनुपालन के ज़रिए पूरे वेब (IE और Firefox में यह पहले से ही करते हैं) के साथ काम करने की क्षमता को बेहतर बनाता है.
  • आपको हर DOM ऑब्जेक्ट पर, लगातार और बेहतर तरीके से गैटर/सेटर बनाने की सुविधा देता है.
  • DOM प्रोग्रामिंग की हैक करने की क्षमता बढ़ाता है. उदाहरण के लिए, इस नीति से आपको ऐसे पॉलीफ़िल लागू करने में मदद मिलेगी जो कुछ ब्राउज़र और JavaScript लाइब्रेरी में छूटी हुई सुविधाओं को बेहतर तरीके से एम्युलेट करने में मदद करते हैं. ये ऐसी सुविधाएं होती हैं जो डिफ़ॉल्ट DOM एट्रिब्यूट के व्यवहार को ओवरराइड करती हैं.

उदाहरण के लिए, एक काल्पनिक W3C स्पेसिफ़िकेशन में isSuperContentEditable नाम की कुछ नई सुविधाएं शामिल हैं. Chrome ब्राउज़र इसे लागू नहीं करता है. हालांकि, इस सुविधा को लाइब्रेरी की मदद से "पॉलीफ़िल" किया जा सकता है या एम्युलेट किया जा सकता है. लाइब्रेरी डेवलपर के तौर पर, आप इस तरह prototype का इस्तेमाल सामान्य रूप से करना चाहेंगे, ताकि एक बेहतर पॉलीफ़िल बनाया जा सके:

Object.defineProperty(HTMLDivElement.prototype, "isSuperContentEditable", {
    get: function() { return true; },
    set: function() { /* some logic to set it up */ },
});

इस बदलाव से पहले - Chrome में अन्य DOM प्रॉपर्टी के साथ एक जैसा अनुभव देने के लिए, आपको हर इंस्टेंस पर एक नई प्रॉपर्टी बनानी पड़ती थी. इसलिए, पेज पर हर HTMLDivElement के लिए यह प्रॉपर्टी काफ़ी असरदार नहीं होती.

ये बदलाव वेब प्लैटफ़ॉर्म में समानता, परफ़ॉर्मेंस, और स्टैंडर्ड तय करने के लिए ज़रूरी हैं. फिर भी, इनकी वजह से डेवलपर को कुछ समस्याएं हो सकती हैं. अगर Chrome और WebKit के लेगसी साथ काम करने की वजह से इस पर भरोसा किया जा रहा था, तो हमारी सलाह है कि आप अपनी साइट देखें. साथ ही, इन बदलावों की खास जानकारी नीचे देखें.

बदलावों का सारांश

किसी DOM ऑब्जेक्ट इंस्टेंस पर hasOwnProperty का इस्तेमाल करने से, अब false दिखाया जाएगा

कभी-कभी डेवलपर, किसी ऑब्जेक्ट पर प्रॉपर्टी की मौजूदगी का पता लगाने के लिए, hasOwnProperty का इस्तेमाल करेंगे. अब यह खास जानकारी के हिसाब से काम नहीं करेगा, क्योंकि DOM एट्रिब्यूट अब प्रोटोटाइप चेन का हिस्सा हैं और hasOwnProperty सिर्फ़ मौजूदा ऑब्जेक्ट की जांच करता है, ताकि यह पता लगाया जा सके कि उसे उस पर परिभाषित किया गया है या नहीं.

Chrome 42 से पहले और इसे शामिल करने पर, ये सुविधाएं true मिलेंगी.

> div = document.createElement("div");
> div.hasOwnProperty("isContentEditable");

true

Chrome 43 के बाद के वर्शन में false दिखेगा.

> div = document.createElement("div");
> div.hasOwnProperty("isContentEditable");

false

इसका मतलब है कि अगर आपको यह देखना है कि isContentEditable एलिमेंट पर उपलब्ध है या नहीं, तो आपको HTMLElement ऑब्जेक्ट पर प्रोटोटाइप की जांच करनी होगी. उदाहरण के लिए, HTMLDivElement को HTMLElement से इनहेरिट किया जाता है, जो isContentEditable प्रॉपर्टी की जानकारी देता है.

> HTMLElement.prototype.hasOwnProperty("isContentEditable");

true

आप hasOwnProperty का इस्तेमाल करने के लिए लॉक नहीं हैं. हम in ऑपरेंड का बहुत आसान इस्तेमाल करने का सुझाव देते हैं, क्योंकि यह पूरी प्रोटोटाइप चेन की प्रॉपर्टी की जांच करेगा.

if("isContentEditable" in div) {
    // We have support!!
}

डीओएम ऑब्जेक्ट इंस्टेंस पर Object.get रिज़ॉर्ट का डिस्क्रिप्टर अब एट्रिब्यूट के लिए प्रॉपर्टी डिस्क्रिप्टर नहीं दिखाएगा

अगर आपकी साइट को किसी DOM ऑब्जेक्ट पर किसी एट्रिब्यूट के लिए प्रॉपर्टी डिस्क्रिप्टर चाहिए, तो अब आपको प्रोटोटाइप चेन को फ़ॉलो करना होगा.

अगर आपको Chrome 42 और उससे पहले के वर्शन में प्रॉपर्टी का ब्यौरा चाहिए होता, तो:

> Object.getOwnPropertyDescriptor(div, "isContentEditable");

Object {value: "", writable: true, enumerable: true, configurable: true}

इस स्थिति में, Chrome 43 के बाद का वर्शन undefined दिखाएगा.

> Object.getOwnPropertyDescriptor(div, "isContentEditable");

undefined

इसका मतलब है कि अब isContentEditable प्रॉपर्टी के लिए प्रॉपर्टी डिस्क्रिप्टर पाने के लिए, आपको नीचे दिए गए तरीके से प्रोटोटाइप चेन का पालन करना होगा:

> Object.getOwnPropertyDescriptor(HTMLElement.prototype, "isContentEditable");

Object {get: function, set: function, enumerable: false, configurable: false}

JSON.stringify अब DOM एट्रिब्यूट को सीरियलाइज़ नहीं करेगा

JSON.stringify, प्रोटोटाइप पर मौजूद डीओएम प्रॉपर्टी को क्रम से नहीं लगाता है. उदाहरण के लिए, अगर पुश नोटिफ़िकेशन की PushSubscription जैसे किसी ऑब्जेक्ट को क्रम से लगाने की कोशिश की जा रही है, तो इसका असर आपकी साइट पर पड़ सकता है.

Chrome 42 और उससे पहले के वर्शन में ये सुविधाएं काम कर सकती थीं:

> JSON.stringify(subscription);

{
    "endpoint": "https://something",
    "subscriptionId": "SomeID"
}

Chrome 43 के बाद के वर्शन में, उन प्रॉपर्टी को क्रम से नहीं लगाया जाएगा जो प्रोटोटाइप पर बताई गई हैं. ऐसा करने पर, आपको कोई खाली ऑब्जेक्ट मिलेगा.

> JSON.stringify(subscription);

{}

आपको क्रम तय करने का अपना तरीका उपलब्ध कराना होगा. उदाहरण के लिए, ये काम किए जा सकते हैं:

function stringifyDOMObject(object)
{
    function deepCopy(src) {
        if (typeof src != "object")
            return src;
        var dst = Array.isArray(src) ? [] : {};
        for (var property in src) {
            dst[property] = deepCopy(src[property]);
        }
        return dst;
    }
    return JSON.stringify(deepCopy(object));
}
var s = stringifyDOMObject(domObject);

रीड-ओनली प्रॉपर्टी को सख्त मोड में लिखने पर गड़बड़ी होगी

स्ट्रिक्ट मोड का इस्तेमाल करने पर, रीड-ओनली प्रॉपर्टी में लिखने पर अपवाद माना जाता है. उदाहरण के लिए, नीचे दी गई जानकारी देखें:

function foo() {
    "use strict";
    var d = document.createElement("div");
    console.log(d.isContentEditable);
    d.isContentEditable = 1;
    console.log(d.isContentEditable);
}

Chrome 42 और उससे पहले के वर्शन के लिए यह फ़ंक्शन बिना किसी कार्रवाई के जारी रह सकता था और बिना किसी सूचना के इस फ़ंक्शन का इस्तेमाल कर सकता था. हालांकि, isContentEditable को बदला नहीं जा सकता था.

// Chrome 42 and earlier behavior
> foo();

false // isContentEditable
false // isContentEditable (after writing to read-only property)

अब Chrome 43 और उसके बाद के वर्शन में एक अपवाद लागू होगा.

// Chrome 43 and onwards behavior
> foo();

false
Uncaught TypeError: Cannot set property isContentEditable of #<HTMLElement> which has only a getter

मुझे एक समस्या है, मुझे क्या करना चाहिए?

निर्देशों का पालन करें या नीचे टिप्पणी करके, हमें बताएं.

मैंने एक समस्या वाली साइट देखी है, मुझे क्या करना चाहिए?

यह एक अच्छा सवाल है. साइटों में ज़्यादातर समस्याएं इस बात पर आधारित होंगी कि साइट ने getOwnProperty तरीके से, 'मौजूदगी का पता लगाने की सुविधा' को चुना है. ऐसा अक्सर तब किया जाता है, जब साइट के मालिक ने सिर्फ़ पुराने WebKit ब्राउज़र को टारगेट किया हो. डेवलपर ये काम कर सकता है:

  • हमारे (Chrome के) समस्या ट्रैकर पर प्रभावित साइट के बारे में समस्या दर्ज करें
  • WebKit रडार पर कोई समस्या दर्ज करें और https://bugs.webkit.org/show_bug.cgi?id=49739 का संदर्भ दें

आम तौर पर, इस बदलाव को फ़ॉलो करने में मेरी दिलचस्पी होती है