Chrome की टीम ने हाल ही में एलान किया है कि हम डीओएम प्रॉपर्टी को प्रोटोटाइप चेन पर ले जा रहे हैं. यह बदलाव Chrome 43 में लागू किया गया है. यह बीटा वर्शन, अप्रैल 2015 के मध्य तक उपलब्ध था. इस बदलाव से, Chrome को Web IDL स्पेसिफ़िकेशन और IE और Firefox जैसे अन्य ब्राउज़र के लागू होने के तरीके के हिसाब से ज़्यादा बेहतर बनाया गया है. बदलाव: साफ़ तौर पर बताया गया है फ़िलहाल, WebKit पर आधारित पुराने ब्राउज़र, इस स्पेसिफ़िकेशन के साथ काम नहीं करते. हालांकि, Safari अब काम करता है.
इस नए व्यवहार से कई फ़ायदे मिलते हैं. इससे:
- स्पेसिफ़िकेशन का पालन करके, वेब पर सभी ब्राउज़र के साथ बेहतर तरीके से काम करता है. IE और Firefox पहले से ही ऐसा करते हैं.
- इसकी मदद से, हर डीओएम ऑब्जेक्ट पर लगातार और बेहतर तरीके से, गेट्टर/सेटर बनाए जा सकते हैं.
- डीओएम प्रोग्रामिंग को हैक करने की संभावना बढ़ जाती है. उदाहरण के लिए, इसकी मदद से पॉलीफ़िल लागू किए जा सकते हैं. इनकी मदद से, कुछ ब्राउज़र और JavaScript लाइब्रेरी में मौजूद फ़ंक्शन को बेहतर तरीके से एमुलेट किया जा सकता है. ये लाइब्रेरी, डीओएम एट्रिब्यूट के डिफ़ॉल्ट व्यवहार को बदल देती हैं.
उदाहरण के लिए, किसी काल्पनिक W3C स्पेसिफ़िकेशन में isSuperContentEditable
नाम की कुछ नई सुविधा शामिल है और Chrome ब्राउज़र इसे लागू नहीं करता. हालांकि, किसी लाइब्रेरी की मदद से इस सुविधा को "पूरा करने" या उसका अनुकरण करने की सुविधा उपलब्ध है. लाइब्रेरी डेवलपर के तौर पर, आपको बेहतर पॉलीफ़िल बनाने के लिए, prototype
का इस्तेमाल इस तरह करना होगा:
Object.defineProperty(HTMLDivElement.prototype, "isSuperContentEditable", {
get: function() { return true; },
set: function() { /* some logic to set it up */ },
});
इस बदलाव से पहले, Chrome में मौजूद अन्य डीओएम प्रॉपर्टी के साथ एक जैसी रखने के लिए, आपको हर इंस्टेंस पर नई प्रॉपर्टी बनानी पड़ती थी. यह पेज पर मौजूद हर HTMLDivElement
के लिए बहुत ही खराब तरीका होता.
ये बदलाव, वेब प्लैटफ़ॉर्म की परफ़ॉर्मेंस, स्टैंडर्ड, और एक जैसी सुविधाओं के लिए ज़रूरी हैं. हालांकि, इनसे डेवलपर को कुछ समस्याएं हो सकती हैं. अगर Chrome और WebKit के बीच लेगसी कम्पैटिबिलिटी की वजह से, आपको इस सुविधा पर भरोसा था, तो हमारा सुझाव है कि आप अपनी साइट की जांच करें और नीचे दिए गए बदलावों की खास जानकारी देखें.
बदलावों का सारांश
डीओएम ऑब्जेक्ट इंस्टेंस पर 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.getOwnPropertyDescriptor, अब एट्रिब्यूट के लिए प्रॉपर्टी डिस्क्रिप्टर नहीं दिखाएगा
अगर आपकी साइट को किसी 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 अब डीओएम एट्रिब्यूट को सीरियलाइज़ नहीं करेगा
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
तरीके से एट्रिब्यूट की मौजूदगी का पता लगाने का विकल्प चुना है या नहीं. ऐसा ज़्यादातर तब किया जाता है, जब साइट के मालिक ने सिर्फ़ पुराने वेबवॉकेट ब्राउज़र को टारगेट किया हो. डेवलपर ये काम कर सकते हैं:
- जिस साइट पर असर पड़ा है उसके बारे में, हमारे (Chrome के) समस्या ट्रैकर पर समस्या दर्ज करें
- WebKit रेडार पर समस्या दर्ज करें और https://bugs.webkit.org/show_bug.cgi?id=49739 का रेफ़रंस दें
आम तौर पर, मुझे इस बदलाव के बारे में जानना है
- साल 2010 का मूल बग: https://bugs.chromium.org/p/chromium/issues/detail?id=43394 - ध्यान दें: इस पर ज़्यादातर काम किया गया है.
- कमिट करने के लिए कोड की समीक्षा