أعلن فريق Chrome مؤخرًا أنّنا بصدد نقل سمات DOM إلى سلسلة النماذج الأولية. وقد تم تنفيذ هذا التغيير في Chrome 43 (الإصدار التجريبي اعتبارًا من منتصف نيسان (أبريل) 2015)، ما يجعل Chrome أكثر توافقًا مع مواصفات Web IDL وعمليات التنفيذ في المتصفّحات الأخرى، مثل IE وFirefox. تعديل: توضيح لا تتوافق حاليًا المتصفحات القديمة المستندة إلى WebKit مع المواصفات، ولكنّ Safari متوافق معها الآن.
يُعدّ السلوك الجديد إيجابيًا من عدّة جوانب. إذ إنه:
- تحسين التوافق على الويب (يُجري Internet Explorer وFirefox ذلك حاليًا) من خلال الامتثال للمواصفات
- يسمح لك بإنشاء أدوات جلب/ضبط بشكل منتظم وفعّال في كل عنصر DOM.
- زيادة إمكانية اختراق برمجة DOM على سبيل المثال، سيتيح لك تنفيذ وحدات polyfill التي تتيح لك محاكاة الوظائف المفقودة في بعض المتصفّحات ومكتبات JavaScript التي تلغي سلوكيات سمات DOM التلقائية بكفاءة.
على سبيل المثال، تتضمّن مواصفة افتراضية من W3C بعض الوظائف الجديدة التي تُسمى isSuperContentEditable
ولا ينفّذها متصفّح Chrome، ولكن من الممكن "تضمين polyfill" أو محاكاة الميزة باستخدام مكتبة. بصفتك مطوّر المكتبة، ستحتاج بطبيعة الحال إلى استخدام prototype
على النحو التالي لإنشاء polyfill فعّال:
Object.defineProperty(HTMLDivElement.prototype, "isSuperContentEditable", {
get: function() { return true; },
set: function() { /* some logic to set it up */ },
});
قبل هذا التغيير، كان عليك إنشاء السمة الجديدة في كل مثيل، وذلك من أجل الاتساق مع سمات DOM الأخرى في Chrome، ما كان سيؤدي إلى انخفاض الكفاءة بشكل كبير في كل HTMLDivElement
على الصفحة.
هذه التغييرات مهمة للحفاظ على اتساق المنصة على الويب وتحسين أدائها وجعلها موحّدة، إلا أنّها قد تتسبب في بعض المشاكل للمطوّرين. إذا كنت تعتمد على هذا السلوك بسبب التوافق القديم بين Chrome وWebKit، ننصحك بالتحقّق من موقعك الإلكتروني والاطّلاع على ملخّص التغييرات أدناه.
ملخّص التغييرات
سيؤدي استخدام hasOwnProperty
على مثيل كائن DOM إلى عرض false
الآن.
يستخدم المطوّرون أحيانًا hasOwnProperty
للتحقّق من توفّر سمة على عنصر. لن يعمل هذا الإجراء بعد الآن وفقًا للمواصفات لأنّ سمات DOM أصبحت الآن جزءًا من سلسلة النماذج الأولية، ولا يتحقّق hasOwnProperty
إلا من العناصر الحالية لمعرفة ما إذا كانت السمة محدّدة فيها.
قبل الإصدار 42 من Chrome وما قبله، كان يتم عرض true
.
> div = document.createElement("div");
> div.hasOwnProperty("isContentEditable");
true
في الإصدار 43 من Chrome فصاعدًا، سيتم عرض القيمة 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 بعد الآن وصفًا للسمة للسمات.
إذا كان موقعك الإلكتروني بحاجة إلى الحصول على وصف السمة لسمة في عنصر نموذج عناصر في المستند (DOM)، عليك الآن اتّباع سلسلة النماذج الأولية.
إذا أردت الحصول على وصف الموقع في الإصدار 42 من Chrome والإصدارات الأقدم، عليك اتّباع الخطوات التالية:
> Object.getOwnPropertyDescriptor(div, "isContentEditable");
Object {value: "", writable: true, enumerable: true, configurable: true}
سيعرض الإصدار 43 من Chrome والإصدارات الأحدث القيمة 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
سمات DOM المتوفّرة في النموذج الأوّلي. على سبيل المثال، يمكن أن يؤثر ذلك في موقعك الإلكتروني إذا كنت تحاول تسلسل عنصر مثل PushSubscription للإشعارات الفورية.
في الإصدار 42 من Chrome والإصدارات الأقدم، كان من الممكن تنفيذ ما يلي:
> JSON.stringify(subscription);
{
"endpoint": "https://something",
"subscriptionId": "SomeID"
}
بدءًا من الإصدار 43 من Chrome، لن يتم تسلسل السمات المحدّدة في النموذج الأولي، وسيتم عرض عنصر فارغ.
> 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);
}
في الإصدار 42 من Chrome والإصدارات الأقدم، كانت الدالة ستستمر في تنفيذها بصمت، على الرغم من أنّ القيمة isContentEditable
لن تتغيّر.
// Chrome 42 and earlier behavior
> foo();
false // isContentEditable
false // isContentEditable (after writing to read-only property)
في الإصدار 43 من Chrome والإصدارات الأحدث، سيتم طرح استثناء.
// 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 كمرجع.
يهمّني بشكل عام متابعة هذا التغيير
- الخطأ الأصلي من عام 2010: https://bugs.chromium.org/p/chromium/issues/detail?id=43394 - ملاحظة: تم حلّ معظم المشاكل المتعلّقة به.
- مراجعة الرمز البرمجي للّقطة