Chrome ekibi kısa süre önce DOM özelliklerini prototip zincirine taşıdığımızı duyurdu. Chrome 43'te (Nisan 2015'in ortası itibarıyla Beta) uygulanan bu değişiklik, Chrome'un Web IDL Özellikleri'nin yanı sıra IE ve Firefox gibi diğer tarayıcıların uygulamalarıyla daha uyumlu hale gelmesini sağlamaktadır. Düzenleme: netleştirildi Eski WebKit tabanlı tarayıcılar şu anda bu özellikle uyumlu değildir, ancak Safari şu anda uyumludur.
Bu yeni davranış birçok açıdan olumlu. Otomatik etiketleme:
- Özelliklere uyum sağlayarak web genelinde uyumluluğu artırır (IE ve Firefox bunu zaten yapar).
- Her DOM Nesnesi için tutarlı ve verimli bir şekilde alıcı/belirleyici oluşturmanızı sağlar.
- DOM programlamasının saldırıya uğrama ihtimalini artırır. Örneğin, varsayılan DOM özelliği davranışlarını geçersiz kılan bazı tarayıcılarda ve JavaScript kitaplıklarında eksik olan işlevleri verimli bir şekilde emüle etmenizi sağlayan çoklu dolgular uygulayabilmenizi sağlar.
Örneğin, varsayıma dayalı bir W3C spesifikasyonu, isSuperContentEditable
adlı bazı yeni işlevler içerir ve Chrome Tarayıcı bu özellikleri uygulamaz, ancak özelliği bir kitaplıkla "çoklu doldurma" veya emülasyonla kullanmak mümkündür. Kitaplık geliştiricisi olarak, verimli bir çoklu dolgu oluşturmak için aşağıdaki gibi prototype
kullanmanız gerekir:
Object.defineProperty(HTMLDivElement.prototype, "isSuperContentEditable", {
get: function() { return true; },
set: function() { /* some logic to set it up */ },
});
Bu değişiklikten önce (Chrome'daki diğer DOM özellikleriyle tutarlılık sağlamak amacıyla), sayfadaki her HTMLDivElement
için yeni özelliği her örnekte oluşturmanız gerekiyordu. Bu da sayfadaki her HTMLDivElement
için çok verimsiz olurdu.
Bu değişiklikler web platformunun tutarlılığı, performansı ve standartlaştırılması açısından önemlidir ancak geliştiriciler için bazı sorunlara neden olabilir. Chrome ve WebKit arasındaki eski uyumluluk nedeniyle bu davranışa güveniyorsanız sitenizi kontrol etmenizi ve değişikliklerin özetini aşağıda incelemenizi öneririz.
Değişiklik özeti
Bir DOM Nesnesi örneğinde hasOwnProperty
kullanıldığında artık false
döndürülür
Bazen geliştiriciler bir nesnede özellik olup olmadığını kontrol etmek için hasOwnProperty
kullanırlar. DOM özellikleri artık prototip zincirinin bir parçası olduğundan ve hasOwnProperty
, mevcut nesneleri inceleyerek bunların üzerinde tanımlanıp tanımlanmadığını kontrol ettiğinden bu işlem artık spesifikasyona göre çalışmaz.
Chrome 42 sürümünden önce ve dahil edildiği sürümlerde true
işlevi döndürülür.
> div = document.createElement("div");
> div.hasOwnProperty("isContentEditable");
true
Chrome 43'ten itibaren false
değerini döndürecektir.
> div = document.createElement("div");
> div.hasOwnProperty("isContentEditable");
false
Bu artık öğede isContentEditable
olup olmadığını kontrol etmek isterseniz prototipi HTMLElement nesnesinde kontrol etmeniz gerektiği anlamına gelir. Örneğin HTMLDivElement
, isContentEditable
özelliğini tanımlayan HTMLElement
öğesinden devralır.
> HTMLElement.prototype.hasOwnProperty("isContentEditable");
true
hasOwnProperty
ürününü kullanmak zorunda değilsiniz. Prototip zincirinin tamamında özelliği kontrol edeceği için çok daha basit in
işlenenini kullanmanızı öneririz.
if("isContentEditable" in div) {
// We have support!!
}
DOM Nesne Örneğindeki Object.getOwn PropertyDescriptor, artık Özellikler için özellik tanımlayıcısı döndürmeyecek
Sitenizin, bir DOM Nesnesi'ndeki bir özelliğin özellik tanımlayıcısını alması gerekiyorsa, artık prototip zincirini izlemeniz gerekecektir.
Chrome 42 ve önceki sürümlerde özellik açıklamasını almak istediğinizde şunları yaparsınız:
> Object.getOwnPropertyDescriptor(div, "isContentEditable");
Object {value: "", writable: true, enumerable: true, configurable: true}
Chrome 43 ve sonraki sürümler, bu senaryoda undefined
değerini döndürür.
> Object.getOwnPropertyDescriptor(div, "isContentEditable");
undefined
Bu durumda, isContentEditable
özelliğinin özellik tanımlayıcısını almak için prototip zincirini aşağıdaki şekilde izlemeniz gerekir:
> Object.getOwnPropertyDescriptor(HTMLElement.prototype, "isContentEditable");
Object {get: function, set: function, enumerable: false, configurable: false}
JSON.stringify artık DOM Özelliklerini serileştirmeyecek
JSON.stringify
, prototipte bulunan DOM özelliklerini serileştirmez. Örneğin, Push Bildirimi'ndeki PushSubscription gibi bir nesneyi seri hale getirmeye çalışıyorsanız bu durum sitenizi etkileyebilir.
Chrome 42 ve önceki sürümlerde aşağıdakiler çalışır:
> JSON.stringify(subscription);
{
"endpoint": "https://something",
"subscriptionId": "SomeID"
}
Chrome 43 ve sonraki sürümler, prototipte tanımlanan özellikleri seri hale getirmez ve size boş bir nesne döndürülür.
> JSON.stringify(subscription);
{}
Kendi serileştirme yönteminizi sağlamanız gerekecektir. Örneğin, aşağıdakileri yapabilirsiniz:
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);
Yüksek düzey modunda salt okunur özelliklere yazmak hata verir
Yüksek düzey modu kullanırken salt okunur özelliklere yazmanın bir istisna gönderilmesi gerekir. Örneğin, aşağıdakileri ele alalım:
function foo() {
"use strict";
var d = document.createElement("div");
console.log(d.isContentEditable);
d.isContentEditable = 1;
console.log(d.isContentEditable);
}
Chrome 42 ve önceki sürümlerinde işlev, isContentEditable
değiştirilmese de işlevi sessiz bir şekilde yürütmeye devam ediyordu.
// Chrome 42 and earlier behavior
> foo();
false // isContentEditable
false // isContentEditable (after writing to read-only property)
Şimdi Chrome 43 ve sonraki sürümlerde bir istisna olacaktır.
// Chrome 43 and onwards behavior
> foo();
false
Uncaught TypeError: Cannot set property isContentEditable of #<HTMLElement> which has only a getter
Sorun yaşıyorum, ne yapmalıyım?
Talimatları uygulayın veya aşağıya yorumunuzu yazın ve birlikte konuşalım.
Sorunlu bir site gördüm, ne yapmalıyım?
Harika bir soru. Sitelerle ilgili çoğu sorun, bir sitenin getOwnProperty
yöntemiyle Özellik varlığı algılamayı yapmayı seçmesine dayanır. Bu, çoğunlukla bir site sahibi yalnızca eski WebKit tarayıcılarını hedeflediğinde gerçekleşir. Bir geliştiricinin yapabileceği birkaç şey vardır:
- Etkilenen siteyle ilgili bir sorunu (Chrome) sorun izleyicimizde bildirin
- WebKit radarında sorun bildiriminde bulunun ve https://bugs.webkit.org/show_bug.cgi?id=49739 adresine bakın.
Genel olarak bu değişikliği takip etmekle ilgileniyorum
- 2010'dan alınan orijinal hata: https://bugs.chromium.org/p/chromium/issues/detail?id=43394 - not: üzerinde işin büyük bir kısmı vardır.
- Kaydetme için Kod İncelemesi