Chrome ekibi kısa süre önce DOM mülklerinin prototip zincirine taşınacağını duyurdu. Chrome 43'te (Nisan 2015'in ortasından itibaren Beta) uygulanan bu değişiklik, Chrome'u Web IDL Spec ve IE ile Firefox gibi diğer tarayıcıların uygulamalarıyla daha uyumlu hale getirir. Düzenleme: Açıklama Eski WebKit tabanlı tarayıcılar şu anda spesifikasyonla uyumlu değildir ancak Safari artık uyumludur.
Yeni davranış birçok açıdan olumludur. Otomatik etiketleme:
- Spesifikasyona uygunluk sayesinde web genelinde uyumluluğu iyileştirir (IE ve Firefox bunu zaten yapar).
- Her DOM nesnesinde tutarlı ve verimli bir şekilde alıcı/ayarlayıcı oluşturmanıza olanak tanır.
- DOM programlamasının saldırıya uğrama olasılığını artırır. Örneğin, bazı tarayıcılarda eksik olan işlevleri verimli bir şekilde taklit etmenize olanak tanıyan çoklu dolgular ve varsayılan DOM özellik davranışlarını geçersiz kılan JavaScript kitaplıkları uygulamanıza olanak tanır.
Örneğin, varsayımsal bir W3C spesifikasyonu isSuperContentEditable
adlı yeni bir işlev içerir ve Chrome Tarayıcı bu işlevi uygulamaz ancak işlevi bir kitaplıkla "polyfill" olarak eklemek veya taklit etmek mümkündür. Kitaplık geliştiricisi olarak, verimli bir polyfill oluşturmak için prototype
'yi aşağıdaki gibi kullanmak istersiniz:
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 mülkleriyle tutarlılık sağlamak için her örnekte yeni mülkü oluşturmanız gerekiyordu. Bu, sayfadaki her HTMLDivElement
için çok verimsiz olurdu.
Bu değişiklikler, web platformunun tutarlılığı, performansı ve standartlaşması için önemlidir ancak geliştiriciler için bazı sorunlara neden olabilir. Chrome ile WebKit arasındaki eski uyumluluk nedeniyle bu davranıştan yararlanıyorsanız sitenizi kontrol etmenizi ve aşağıdaki değişikliklerin özetini incelemenizi öneririz.
Değişiklik özeti
Bir DOM nesnesi örneğinde hasOwnProperty
kullanıldığında artık false
döndürülür
Geliştiriciler bazen bir nesnede mülkün bulunup bulunmadığını kontrol etmek için hasOwnProperty
değerini kullanır. DOM özellikleri artık prototip zincirinin bir parçası olduğu ve hasOwnProperty
yalnızca tanımlanıp tanımlanmadığını görmek için mevcut nesneleri denetlediği için bu yöntem artık spesifikasyona göre çalışmaz.
Chrome 42 ve önceki sürümlerde aşağıdaki değer true
olarak döndürülürdü.
> div = document.createElement("div");
> div.hasOwnProperty("isContentEditable");
true
Chrome 43 ve sonraki sürümlerde false
döndürülür.
> div = document.createElement("div");
> div.hasOwnProperty("isContentEditable");
false
Bu durumda, öğede isContentEditable
'ün kullanılabilir olup olmadığını kontrol etmek için HTMLElement nesnesinde prototipi kontrol etmeniz gerekir. Örneğin, HTMLDivElement
, isContentEditable
mülkünü tanımlayan HTMLElement
'ten devralır.
> HTMLElement.prototype.hasOwnProperty("isContentEditable");
true
hasOwnProperty
'ü kullanmak zorunda değilsiniz. Mülkü prototip zincirinin tamamında kontrol edeceği için çok daha basit olan in
operatörünü kullanmanızı öneririz.
if("isContentEditable" in div) {
// We have support!!
}
DOM Nesnesi örneğindeki Object.getOwnPropertyDescriptor artık Özellikler için bir özellik tanımlayıcısı döndürmeyecek
Sitenizin bir DOM nesnesindeki bir özelliğin mülk tanımlayıcısı alması gerekiyorsa artık prototip zincirini izlemeniz gerekir.
Chrome 42 ve önceki sürümlerde tesis açıklamasını almak için şunları yapmalıydı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
Yani artık isContentEditable
mülkünün mülk tanımlayıcısı almak için prototip zincirini aşağıdaki gibi uygulamanız 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 Notification'ın PushSubscription gibi bir nesneyi serileştirmeye çalışıyorsanız bu durum sitenizi etkileyebilir.
Chrome 42 ve önceki sürümlerde aşağıdakiler işe yarayacaktır:
> JSON.stringify(subscription);
{
"endpoint": "https://something",
"subscriptionId": "SomeID"
}
Chrome 43 ve sonraki sürümler, prototipte tanımlanan özellikleri serileştirmez ve size boş bir nesne döndürülür.
> JSON.stringify(subscription);
{}
Kendi serileştirme yönteminizi sağlamanız gerekir. Ö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);
Salt okunur özelliklere katı modda yazmak hata verir
Katı modu kullanırken salt okunur özelliklere yazma işleminin istisna oluşturması 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ümlerde isContentEditable
değiştirilmemiş olsa da işlev devam eder ve sessizce yürütülmeye devam eder.
// Chrome 42 and earlier behavior
> foo();
false // isContentEditable
false // isContentEditable (after writing to read-only property)
Chrome 43 ve sonraki sürümlerde ise bir istisna atılır.
// Chrome 43 and onwards behavior
> foo();
false
Uncaught TypeError: Cannot set property isContentEditable of #<HTMLElement> which has only a getter
Bir sorun yaşıyorum. Ne yapmalıyım?
Talimatları uygulayın veya aşağıdaki yorum bölümünden bize ulaşın.
Sorunlu bir site gördüm. Ne yapmalıyım?
Harika bir soru. Sitelerle ilgili sorunların çoğu, sitenin getOwnProperty
yöntemiyle özellik varlığı algılamayı seçmesinden kaynaklanır. Bu durum genellikle site sahibi yalnızca eski WebKit tarayıcılarını hedeflediğinde ortaya çıkar. Geliştiricilerin yapabileceği birkaç işlem vardır:
- Etkilenen siteyle ilgili olarak Chrome'un sorun izleyicisinde sorun kaydı oluşturun.
- WebKit radar'da sorun gönderin ve https://bugs.webkit.org/show_bug.cgi?id=49739 adresini referans olarak kullanın.
Genel olarak bu değişikliği takip etmek istiyorum
- 2010'dan kalma orijinal hata: https://bugs.chromium.org/p/chromium/issues/detail?id=43394 - not: Çalışmanın büyük kısmı bu hatada yer alıyor.
- Commit için Kod İncelemesi