Aynı kimliğe sahip iki HTML öğesi: Gerçekten ne kadar kötü?


122

Sadece Google Maps kaynak koduna göz atıyorsunuz. Başlıklarında id = "search" biri diğerini içeren 2 divs ve ayrıca jstrack = "1" niteliği vardır. Onları bu şekilde ayıran bir form var:

<div id="search" jstrack="1">
    <form action="/maps" id="...rest isn't important">
        ...
        <div id="search">...

Bu google olduğundan, bunun bir hata olmadığını farz ediyorum.

Peki bu kuralı ihlal etmek ne kadar kötü olabilir? Css ve dom seçiminizde dikkatli olduğunuz sürece neden kimliğin sınıflarını kullanmıyorsunuz? Bunu bilerek yapan var mı, öyleyse neden?


102
"Bu google olduğundan, bunun bir hata olmadığını farz ediyorum." -> Google yanılmaz değildir. Geri kalanımız gibi hatalar yapıyorlar.
Joeri Sebrechts

43
aslında google adamlar gelmiş arama başka hiçbir kimlik yılların düşünemiyorum böylece zihinlerinde cıvatalı: P
Pankaj Upadhyay

10
Bu sayfanın farklı html parçalarından oluşturulduğunu hissediyorum, böylece bir parçadaki bir geliştirici bu kimliği kullandı ve aynı diğer parçadaki diğer geliştiriciyle oldu.
Luciano

10
"Gerçekten ne kadar kötü" sorusunun tamamı bana şunu hatırlatıyor: xkcd.com/292
Daniel Roseman

3
@DanielRoseman xkcd de yapıyor: what-if.xkcd.com/23/#question
SQB

Yanıtlar:


140

Şartname UNIQUE diyor

HTML 4.01 özelliği , kimliğin belge genelinde benzersiz olması gerektiğini söylüyor.

HTML 5 özelliği aynı şeyi ancak başka bir deyişle söylüyor. Kimliğinin, ev tanımında benzersiz olması gerektiğini , bunun tanımını okuduğumuzda temelde belge olduğunu söylüyor .

Çoğaltma kaçının

Ancak HTML oluşturucular, HTML oluşturmaya gelince çok bağışlayıcı olduklarından, yinelenen kimliklere izin verirler. Bu , JavaScript'teki ID'lerle programlı olarak programlara erişirken mümkün olduğu ve kesinlikle kaçınılması gerekenlerden kaçınılmalıdır . getElementByIdEşleşen birkaç eleman bulunduğunda hangi fonksiyonun dönmesi gerektiğinden emin değilim ? Olmalı:

  • hata döndürmek
  • ilk eşleşen öğeyi döndür
  • son eşleşen öğeye dönülsün mü?
  • eşleşen öğeler kümesi döndür?
  • hiçbir şey döndürmemek?

Ancak bu günlerde tarayıcılar güvenilir bir şekilde çalışsalar da, gelecekte şartnameye aykırı olduğu için kimse bu davranışı garanti edemez. Bu nedenle , aynı belgede hiçbir zaman kimlikleri çoğaltmamanızı öneririm .


1
@missingno: Aynı şey hakkında ancak farklı ifadelerden bahseden HTML 5 spesifikasyonuna bir bağlantı ekledim.
Robert Koritnik

6
Göre DOM spec , (ki bu oldukça gerçek değerinden daha, herhangi bir tanımlanmış "doğru" sonucu olduğu anlamına gelir "birden fazla elemanın bu değerle bir kimlik özelliğinin bulunması durumunda ne döndürülür tanımsız" undefined). Tanımlanmamış davranışlara güvenmek nadiren iyi bir fikirdir.
yalnız

1
HTML5 ile dikkat çekmeye değer, data-özellik aynı kimliğe birden çok şey atamak için cazip olabileceği için kullanışlı olur. Bu data-something, ortak bir özelliğe sahip birçok farklı kimliğinizin olmasını sağlar . Yine de, benim bildiğim tüm tarayıcılar bilinmeyen özelliklerini görmezden, bu yüzden konum muhtemelen tam HTML desteği eksik hemen her modern-ish tarayıcıda güvenli.
Tim Post

2
@JoachimSauer: Veri niteliklerini kullandığınızda, CSS sınıflarını kullanırken doğru olmayan anahtar / değer çiftlerine sahip olabilirsiniz. Bu durumda hepsi boolean özellikler gibidir. Bir öğenin CSS sınıfı var veya yok. CSS sınıflarıyla değerler istiyorsanız, bunları bir şekilde CSS sınıf adıyla birleştirmeniz ve daha sonra ayrıştırmanız gerekir. Umarım artık datanitelikleri kullanmanın faydalarını görebilirsin . Ayrıca sadece data-something="123"niteliklere atıfta bulunduğunuzda jQuery tarafından doğrudan kutudan desteklenirler $(elem).data("something").
Robert Koritnik

1
@RobertKoritnik: Tabii ki! Bu kullanım durumunu düşünmedim. Sadece olayı düşündüm id="search".
Joachim Sauer

30

"Ne kadar kötü" diye sordun. Yani @ RobertKoritnik'in (tamamen doğru) cevabını biraz ...

Bu kod yanlış. Yanlış gri tonlarında gelmiyor. Bu kod standardı ihlal ediyor ve bu nedenle yanlış. Doğrulama kontrolünde başarısız olur ve yapmalıdır.

Bununla birlikte, şu anda piyasada bulunan hiçbir tarayıcı bu konuda hiçbir şikayette bulunmayacak veya sorun yaşamaması gerektiğini söyledi. Tarayıcılar bu konuda şikayette bulunma hakları dahilinde olacak, ancak şu anda hiçbirinin geçerli sürümünün hiçbiri bulunmuyor. Gelecekteki sürümleri bu kodu kötü işlemeyebilir anlamına gelmez.

Bu tanıtıcıyı css veya javascript'te bir seçici olarak kullanmaya çalışan davranışınız değiştirilemez ve muhtemelen tarayıcıdan tarayıcıya değişir. Sanırım her tarayıcının buna nasıl tepki gösterdiğini görmek için bir çalışma yapılabilir. En iyi durumda, "class =" gibi davranacağını ve onların listesini seçeceğini düşünüyorum. (Bununla birlikte, JavaScript kitaplıklarının kafasını karıştırabilir - eğer jQuery'nin yazarı olsaydım, "#" ile başlayan bir seçiciyle gelirseniz, tek bir nesne beklediğimden ve tek bir nesne beklediğimden, seçim kodumu optimize etmiş olabilirim. liste beni tamamen rahatsız edebilir.)

Ayrıca, ilki veya muhtemelen sonuncuyu seçebilir veya hiçbirini seçmeyebilir veya tarayıcıyı tamamen çökertebilir. Denemeden söylemenin yolu yok.

“Ne kadar kötü” o zaman tamamen belirli bir tarayıcının HTML spesifikasyonunu ne kadar sıkı uyguladığına ve bu şartnamenin ihlali ile karşı karşıya kaldığında ne yaptığına bağlıdır.

EDIT: SADECE bugün bu rastlamak oldu. Bu site için harika, hepsi bir arada bir raporlama programı oluşturmak için çeşitli varlıklardaki arama formlarından çeşitli bileşenlerden faydalanıyorum, uzak sayfaların arama formlarını gizli div'ler içine yüklüyorum ve bunları Raporun kaynağı olarak uygun varlık türü seçildiğinde rapor oluşturucu. Dolayısıyla, formun gizli bir sürümü ve rapor oluşturucuda görüntülenen bir sürüm var. Birlikte verilen JavaScript, her durumda, sayfada artık İKİ olan gizli kimliğe ve görüntülenen kimliğe göre öğeleri belirtir.

JQuery’nin yaptığı gibi, beni ilk olanı seçmek, ki bu da her durumda tam olarak istemediğim bir şey.

Bu konuda çalışıyorum, alanımı almak istediğim sayfanın bölgesini belirtmek için seçiciler yazarak (yani: $ ('# containerDiv #specificElement')). Ancak sorunuza bir cevap var - Chrome'daki jQuery, bu şart ihlali ile karşı karşıya kaldığında kesinlikle özel bir davranış sergiliyor.


... ilgili bir soru: CSS hızlı profilinde kimliklerin zorunluluğu hakkında stackoverflow.com/q/29295824/287948 .
Peter Krauss

3
"Yanlış gri tonlarında gelmiyor." Bunu çok görüyorum ve teknik olarak doğru olan ama hayatta veya programlamada "gerçek" olmayan şeylerden biri. Siz dolaylı olarak cevabınızı oldukça iyi ele alıyorsunuz ve açıklayabiliyorum ama The Big Bang Theory'den bu sahne benim için konuşmasına izin vereceğim ve umarım birini güldürecek kadar iyi bir iş çıkarıyor ... Stuart vs Sheldon youtube.com/ v? F_1zoX5Ax9U
Night Owl

bu 8 yıllık bir cevap, ancak OP'nin sorusu üzerinde abartılı olmanın henüz dengesiz olduğunu düşünüyorum, ancak tarayıcıların tekrarlayan kimlikleri için izin veren ve tehlikeli davranışlarından şikayet etmiyor, bu da OP'nin yapmaya çalıştığından çok daha kötü.
erandros

20

Bu gerçekten ne kadar kötü?

  1. Beni ağlatıyor
  2. Geçersiz
  3. Birçok javascript kütüphanesi beklendiği gibi çalışmayacak
  4. Kodunuzu kafa karıştırıcı hale getirir

Deneyim, büyük tarayıcılardaki getElementById öğesinin belgedeki ilk eşleşen öğeyi döndüreceğini söylüyor. Ancak bu gelecekte her zaman böyle olmayabilir.

JQuery'ye bir kimlik verildiğinde, örneğin #foo, getElementById öğesini kullanır ve bu davranışı taklit eder. Bunun üzerinde çalışmak zorundaysanız (üzücü), jQuery'i getElementsByTagName kullanmaya ve tüm eşleşen öğelerin bir listesini döndürmeye ikna edecek olan $ (" * #foo") kullanabilirsiniz.

Genellikle diğer siteler için kod yazmam gerekiyor ve bunun üzerinde çalışmam gerekiyor. Adil bir dünyada, kimliğin benzersiz olup olmadığını kontrol ederek başlamak için işlevleri yeniden tasarlamak zorunda kalmam. Kimlikler her zaman benzersiz olmalıdır. Dünya acımasız ve bu yüzden ağlıyorum.


5
Bu cevap beni ağlattı ... kahkaha attı!
A1rPun

8

Sen edebilirsiniz pek çok şeyler yapmak - ama bu yapmanız gerekir anlamına gelmez.

Bir programcı olarak (genel olarak konuşursak) hayatlarımızı kesin ve kurallara uymaya dayandırırız - işte izlenmesi kolay olan, yaptığımız iş için oldukça temel olan bir kuraldır - belirli bir kapsamdaki benzersiz tanımlayıcıları seviyoruz (bağımlıyız) ...

Kuralı çiğnemek, yapabileceğimiz bir şeydir, çünkü tarayıcı çok fazla uygundur - ancak eğer tarayıcılar iyi biçimlendirilmiş ve geçerli HTML’ye ihtiyaç duyma konusunda katı olsaydı, bizlerin neden olacağı acıdan çok daha uzun bir zaman alabilirdi. geri ödendi!

Yani, gerçekten bu kadar kötü mü? Bir programcı olarak nasıl sorabilirsiniz? Uygarlığa karşı bir suç (-:


Zeyilname:

Tarayıcıların kötü bir şey gibi ağırlandığını yazıyorsun

Yapıyorum, çünkü bu - karmaşık kurallardan bahsetmiyoruz, esas olarak iyi biçimlendirilmiş şeyleri yapmaktan ve başka şekilde mekanik olarak test edilebilecek ve sonuçların mekanik olarak işlenmesini kolaylaştıracak kuralları uygulamaktan bahsediyoruz. Eğer tarayıcılar katı olsaydı, araçlar çok hızlı bir şekilde bunu destekleyecek şekilde adapte olurlardı - öyle değil, bir dereceye kadar bu başarısızlıktan istifade ettiler. Sadece bunu düşünün - eğer MS ve Netscape tarafından alıntı metni için açıkça desteklenmiş çok daha az karmaşık bir "e-posta biçimlendirme dili" bize çok daha iyi bir araç verdiğinde, sınırsız HTML’e izin vererek bu sorunu çözmemiş olsaydı, e-posta çok daha iyi bir ortam olurdu. ... ama o gemi gitti ve benzer şekilde yapabiliriz.olmalıdır ) ama biz yapamayız


Tarayıcıların kötü bir şey gibi uyum sağlayamadıklarını yazıyorsunuz, ama kesinlikle buna inanmıyorsunuz?
KaptajnKold

4
Murph için konuşamam, ama bunun gerçekten kötü bir şey olduğunu düşünüyorum. O zaman yine, bu affetme düzeyi olmadan, web bizim bildiğimiz gibi büyümek için bir itme gücüne sahip olmayabilir.
Andrea,

1
@Andrea: İnternet bildiğimiz kadar büyük olmazdı. Daha yavaş büyürdü. Ancak aynı zamanda doğru kodun ne olduğu ve ne olmadığı konusunda daha sağlam bir temele sahip olacaktır. Hızlı ama özensiz işe yarayabilir, ama ben daha yavaş ama doğru olanı tercih ederim. Özellikle de öyle olmadığından, sadece birkaç yıllık büyüme hakkında konuşacağız.
Nicol Bolas

3
@Andrea, neredeyse o kadar çabuk büyüdüğü üzerine bahse girerdim - araçlar sorunla başa çıkmak için gelişti. Oysa, çoğu durumda araçlar zayıf işaretlemenin temel nedeni idi. Gerçek şu ki, insanlar en az gerekli olanı yapma eğilimindedir - "iyi şekillendirilmiş olma" adımı nispeten küçük ve test edilebilecek ve uygulanabilecek kadar kolaydır ve insanlar önemli bir stres olmadan bunu yapabilirdi
Murph

1
Tarayıcıların accomodating korkunç değil. Hepsinin farklı şekillerde uyum sağlamaları korkunç .
Dan Ray

7

Komut Dosyasında: getElementByIDyalnızca ilk eşleşmeyi döndürür. CSS'de: #idbu kimliğe sahip TÜM öğeleri etkileyecektir. Tarayıcıda Render herhangi bir etkisi olmayacak.

Bu w3c standardının davranışıdır. Mümkün değil, tanımlanmış olanı.

https://dom.spec.whatwg.org/#interface-nonelementparentnode


7
Bu olası bir davranış. getElementByIdherhangi bir öğeyi, hatta boş bir nesneyi mükemmel bir şekilde döndürebilirdi. CSS etkisi herhangi bir element üzerinde olabilir veya hiçbiri veya hiçbiri olmayabilir. Veya tarayıcı çökebilir. Standardın dışında, davranış olduğunu tanımsız
rds

2
Standart dışı değil çünkü standart bu durumlarda ne yapılacağını belirler. Yani hayır, getElementById herhangi bir öğeyi döndüremedi, standart açıkça ilk maçı geri getireceğimi söylüyor. Standart dışı davranışların tanımsız olduğu, anlamadığınız şeyin tüm bu vakaların standardın bir parçası olduğu konusunda hemfikirsiniz.
Bart Calixto

1
Bu cevap, referans olarak standardın ilgili kısmının (veya en azından bir bölüm numarasının) bir kısmına bir alıntı olarak dahil edildiyse, biraz daha iyi olacaktır.
yoniLavi

2
@yoniLavi güncellendi.
Bart Calixto

2
Teşekkürler @Bart. Kesinlikle haklısın :) Standart " Düğümü ID'sIId olan torunları içindeki ilk öğeyi döndürür " der.
yoniLavi
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.