Bazı HTML etiketleri için rasgele veriler nasıl saklanır


338

Javascript tarafından sağlanan bazı etkileşimi olan bir sayfa yapıyorum. Örnek olarak: makalelerin içeriğini almak ve daha sonra bu verileri bir div içinde görüntülemek için AJAX isteği gönderen bağlantılar. Açıkçası bu örnekte, fazladan bir bilgi saklamak için her bağlantıya ihtiyacım var: makalenin kimliği. Durumda bu şekilde ele aldığım şekilde bu bilgileri href bağlantısına koymak oldu:

<a class="article" href="#5">

Daha sonra a.article elemanlarını bulmak ve uygun olay işleyicisini eklemek için jQuery kullanın. (burada kullanılabilirlik veya anlambilime fazla takılmayın, bu sadece bir örnek)

Her neyse, bu yöntem işe yarıyor, ancak biraz kokuyor ve hiç genişletilemiyor (tıklama işlevinin birden fazla parametresi varsa ne olur? Bu parametrelerden bazıları isteğe bağlıysa ne olur?)

Hemen ortaya çıkan cevap elemanda nitelikleri kullanmaktı. Demek istediğim, bu onlar için, değil mi? (Türü).

<a articleid="5" href="link/for/non-js-users.html">

Gelen benim son soru bu yöntem geçerli olup olmadığını sordum ve o zaman hayır, geçerli veya güvenilir değil, (I do not) benim kendi DTD tanımlanması da eteğine çıkıyor. Yaygın bir yanıt, verileri classözniteliğe koymaktı (bu, kötü seçilmiş örneğimden kaynaklanmış olsa da), ama bana göre, bu daha da kokuyor. Evet, teknik olarak geçerli, ancak harika bir çözüm değil.

Geçmişte kullandığım başka bir yöntem aslında bazı JS oluşturmak ve bunu bir <script>etiketteki sayfaya eklemek ve nesneyle ilişkilendirilecek bir yapı oluşturmaktı.

var myData = {
    link0 : {
        articleId : 5,
        target : '#showMessage'
        // etc...
    },
    link1 : {
        articleId : 13
    }
};

<a href="..." id="link0">

Ancak bu popodaki gerçek bir acı olabilir ve genellikle çok dağınıktır.

Peki, soruya ulaşmak için, HTML etiketleri için rasgele bilgi parçalarını nasıl saklıyorsunuz ?


Yanıtlar:


361

Hangi HTML sürümünü kullanıyorsunuz?

HTML 5, olması tamamen geçerlidir veriye öneki niteliklerini özel , örneğin

<div data-internalid="1337"></div>

XHTML'de bu gerçekten geçerli değil. XHTML 1.1 modundaysanız, tarayıcı muhtemelen bundan şikayet edecektir, ancak 1.0 modunda, çoğu tarayıcı sessizce yok sayar.

Siz olsaydım, senaryo tabanlı yaklaşımı izlerdim. Bunu sunucu tarafında otomatik olarak oluşturabilirsiniz, böylece bakım için arkada bir ağrı olmaz.


5
@Tchalvak: Doğru, ancak bu bit çoğu tarayıcıda çalışır, hiçbiri daha az değildir.
Tamas Czinege

2
Diğerleri, destek beklemek için bir neden olmadığını iddia etti, çünkü bu tek sorun doğrulamak için başarısızlık ve IE kırmaz. TJ Crowler'in cevabına buradan bakın: stackoverflow.com/questions/1923278/…
Chris

42
Data-xxx özniteliklerini kullanırsanız ve bunları almak istiyorsanız, herhangi bir üçüncü taraf çerçevesi olmadan "domElement.getAttribute ('data-whatever')" seçeneğini kullanabilirsiniz.
Ohad Kravchick


19
Hatırlatma: Verileri almak için, 1337, jquery aracılığıyla, değişken adından 'verileri' kaldırdığınızdan emin olun. Örneğin, şunu kullanın: $(this).data('internalid'); Bunun yerine:$(this).data('data-internalid');
Gideon Rosenthal

134

Eğer zaten jQuery kullanıyorsanız, o zaman jQuery ile bir dom öğesinde rasgele veri depolamak için önerilen yöntem olan "data" yöntemini kullanmalısınız.

Bir şeyi saklamak için:

$('#myElId').data('nameYourData', { foo: 'bar' });

Veri almak için:

var myData = $('#myElId').data('nameYourData');

Tüm bunlar var ama daha fazla bilgi / örnekler için jQuery belgelerine bir göz atın .


20

Başka bir yol, ben şahsen bunu kullanmak olmaz ama işe yarıyor (eval () tehlikeli olduğundan JSON geçerli olduğundan emin olun).

<a class="article" href="link/for/non-js-users.html">
    <span style="display: none;">{"id": 1, "title":"Something"}</span>
    Text of Link
</a>

// javascript
var article = document.getElementsByClassName("article")[0];
var data = eval(article.childNodes[0].innerHTML);

1
Yanal düşünme için +1. Muhtemelen bu yöntemi kullanmak istemeyeceğime katılıyorum, ancak bu belirsiz bir seçenek!
nickf

9
@nickf Bunun yerine evalkullanarak kurtulabilirsiniz jsfiddle.net/EAXmYJSON.parse
Simon

12

Rasgele özellikler geçerli değildir, ancak modern tarayıcılarda mükemmel derecede güvenilirdir. Özellikleri javascript ile ayarlıyorsanız, doğrulama konusunda da endişelenmenize gerek yoktur.

Bir alternatif, javascript'te nitelikleri ayarlamaktır. jQuery sadece bu amaç için güzel bir yardımcı program yöntemi vardır, ya da kendi rulo olabilir.


3
data-Bunun yerine özellikleri neden kullanmıyorsunuz ?
Flimm

10

Hemen hemen her tarayıcıyla çalışacak bir kesmek, aşağıdaki gibi açık sınıflar kullanmaktır: <a class='data\_articleid\_5' href="link/for/non-js-users.html>;

Bu, saflar için o kadar zarif değil, ancak evrensel olarak destekleniyor, standartlara uygun ve manipüle edilmesi çok kolay. Gerçekten mümkün olan en iyi yöntem gibi görünüyor. Eğer varsa serialize, değiştirmek , kopyalamak , etiketlerinizi, ya da başka hemen hemen her şeyi dataolacak kalmak ekli kopyalanamaz vs.

Tek sorun, serileştirilemeyen nesneleri bu şekilde depolayamamanız ve orada çok büyük bir şey koyarsanız sınırlamalar olabilir.

İkinci yol, sahte özellikleri kullanmaktır :<a articleid='5' href="link/for/non-js-users.html">

Bu daha zarif, ancak standartlara uymuyor ve destek konusunda% 100 emin değilim. Birçok tarayıcı bunu tam olarak destekliyor, IE6'nın JSerişimi desteklediğini düşünüyorum CSS selectors( ancak burada gerçekten önemli değil), belki de bazı tarayıcılar tamamen karıştırılacak, kontrol etmeniz gerekiyor.

Serileştirme ve serileştirme gibi komik şeyler yapmak daha da tehlikeli olurdu.

Kullanılması idssaf JSkarma çoğunlukla size etiketleri kopyalamak çalıştığınızda dışında çalışır. Varsa tag <a href="..." id="link0">, standart JSyöntemlerle kopyalayın ve ardından datayalnızca bir kopyaya ekli olarak değişiklik yapmaya çalışın , diğer kopya değiştirilecektir.

S'yi kopyalamazsanız tagveya salt okunur verileri kullanmazsanız sorun olmaz . Eğer kopyalarsanız tagve değiştirilmişlerse, bunu elle işlemeniz gerekir.


valse sınıfta saklamak harika
Saravanan Rajaraman

10

Jquery kullanarak,

depolamak: $('#element_id').data('extra_tag', 'extra_info');

almak için: $('#element_id').data('extra_tag');


6

Şu anda jQuery kullandığınızı biliyorum, ama onclick işleyici satır içi tanımladıysanız. Sonra şunları yapabilirsiniz:

 <a href='/link/for/non-js-users.htm' onclick='loadContent(5);return false;'>
     Article 5</a>

6

Gizli giriş etiketlerini kullanabilirsiniz. Bu w3.org hiçbir doğrulama hataları alıyorum:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang='en' xml:lang='en' xmlns='http://www.w3.org/1999/xhtml'>
  <head>
    <meta content="text/html;charset=UTF-8" http-equiv="content-type" />
    <title>Hello</title>
  </head>
  <body>
    <div>
      <a class="article" href="link/for/non-js-users.html">
        <input style="display: none" name="articleid" type="hidden" value="5" />
      </a>
    </div>
  </body>
</html>

JQuery ile makale kimliğine (test edilmedi) benzer bir şey alırsınız:

$('.article input[name=articleid]').val();

Ancak bu seçenek HTML5'i öneririm.


13
Aslında style="display: none"gizli girdi alanları için gerekli olduğunu düşünmüyorum .
phylae

1
İyi yaklaşım, tüm HTML sürümlerinde tamamen geçerlidir. Tüm kullanıcılarınızın tamamen HTML5 şikayet tarayıcısına sahip olacağı varsayımıyla kodlamayı şiddetle öneriyorum. Ve display: gizli alanlar için hiçbirine gerek yoktur.
andreszs

Çok hoş. Bu, veri özniteliklerinin geçerli bir seçenek olmadığı XHTML için bulduğum en iyi çözümdür. IMO etiketleri / nitelikleri istenmeyen şekillerde kötüye kullanmaz, neredeyse hiç "kokusu" yoktur. Diğerlerinin söylediği gibi: display: hiçbirine gerçekten gerek yok.
Arahman

4

Neden rastgele veri eklemek yerine, oradaki anlamlı verileri kullanmıyorsunuz?

yani kullanmak <a href="https://stackoverflow.com/articles/5/page-title" class="article-link">ve sonra programlı (sınıfadı aracılığıyla) sayfadaki tüm makale bağlantıları ve makale kimliğini (regex eşleşen alabilirsiniz /articles\/(\d+)/karşı this.href).


2
Bununla ilgili sorun, aynı zamanda gerçekten genişletilebilir olmamasıdır
ehdv


3

Bu yüzden bunu yapmak için dört seçenek olmalı:

  1. Verileri id özelliğine yerleştirin.
  2. Verileri keyfi özelliğe yerleştirin
  3. Verileri sınıf niteliğine koyma
  4. Verilerinizi başka bir etikete yerleştirin

http://www.shanison.com/?p=321


@ h4ck3rm1k3 ... id niteliğinde değil, çünkü belgeye göre benzersiz olmalı ve bir kenar çubuğunda veya gerekirse bir şeyde tekrarlanmalıdır ... Bu eski bir soru, ama yine de geçerli
miguel-svq

2

"Rel" özelliğinin kullanımını savunuyorum. XHTML doğrular, özelliğin kendisi nadiren kullanılır ve veriler verimli bir şekilde alınır.


bu kimliği yapamam bağlantılarda nofollow özniteliğini kırmak
Carter Cole

2

Bu iyi bir tavsiye. @Prestaul sayesinde

Eğer zaten jQuery kullanıyorsanız, o zaman jQuery ile bir dom öğesinde rasgele veri depolamak için önerilen yöntem olan "data" yöntemini kullanmalısınız.

Çok doğru, ancak düz eski HTML'de rastgele veriler depolamak isterseniz ne olur? İşte başka bir alternatif ...

<input type="hidden" name="whatever" value="foobar"/>

Verilerinizi gizli bir girdi öğesinin ad ve değer özelliklerine yerleştirin. Sunucu HTML üretiyorsa (örn. Bir PHP betiği veya her neyse) ve JavaScript kodunuz bu bilgileri daha sonra kullanacaksa bu yararlı olabilir.

Kuşkusuz, en temiz değil, ama bir alternatif. Tüm tarayıcılarla uyumludur ve geçerli XHTML'dir. Sen olmalıdır DEĞİL özel özellikler kullanabilir, ne de gerçekten birlikte özelliklerini kullanmalıdır 'veriye' öneki, tüm tarayıcılarda çalışması olmayabilir olarak. Ayrıca, belgeniz W3C doğrulamasını geçmeyecektir.


tam olarak emin değilim, ancak bazı tarayıcılar "katı" bir dokümana sahip özel öznitelikler kullanırsanız şikayet edebilir. Her iki durumda da geçerli bir XHTML değil.
BMiner

2

Rastgele bir öğenin ( <span data-randomname="Data goes here..."></span>) kendi özel özniteliğinizin veri önekini kullanabilirsiniz , ancak bu yalnızca HTML5'te geçerlidir. Böylece tarayıcılar geçerlilikten şikayet edebilirler.

Bir <span style="display: none;">Data goes here...</span>etiket de kullanabilirsiniz . Ancak bu şekilde öznitelik işlevlerini kullanamazsınız ve css ve js kapalıysa, bu da gerçekten düzgün bir çözüm değildir.

Ama şahsen tercih ettiğim şey:

<input type="hidden" title="Your key..." value="Your value..." />

Giriş her durumda gizlenecek, öznitelikler tamamen geçerli olacak ve <form>herhangi bir adı olmadığı için etiketin içinde gönderilmeyecek , değil mi? Her şeyden önce, özellikleri hatırlamak gerçekten kolay ve kod güzel ve anlaşılması kolay görünüyor. Hatta bir ID özniteliği koyabilirsiniz, böylece JavaScript ile de kolayca erişebilir ve ile anahtar / değer çiftine erişebilirsiniz input.title; input.value.


Html tabloları ve seçimi ile yeterince çalışmadı eminim. Bazı işleri kaydetmek için data özelliğini daha sık kullanacaksınız.

1
Aslında 'data-' özelliğini çok kullanıyorum. Ancak gereksinimlerinizin ne olduğuna bağlıdır. Örneğin, <input /> ile herhangi bir tuşa sahip olabilirsiniz, oysa 'data-' için bu, alfasayısal olmayan herhangi bir karakter içermeyen küçük harfli bir dize ile sınırlıdır.
Yeti

1

Bir olasılık şunlar olabilir:

  • Tüm genişletilmiş / keyfi verileri tutmak için yeni bir div oluşturun
  • Bu div'in görünmez olduğundan emin olmak için bir şeyler yapın (örn. CSS artı div'ın bir sınıf niteliği)
  • Genişletilmiş / keyfi verileri [X] HTML etiketlerine (örneğin, tablonun hücreleri içindeki metin veya istediğiniz başka bir şey) bu görünmez div içine yerleştirin

1

Başka bir yaklaşım, bir anahtar: değer çiftini aşağıdaki sözdizimini kullanarak basit bir sınıf olarak saklamak olabilir:

<div id="my_div" class="foo:'bar'">...</div>

Bu geçerlidir ve jQuery seçicileri veya özel bir işlevle kolayca alınabilir.


0

Önceki işverenimde, form öğeleri hakkında bilgi tutmak için her zaman özel HTML etiketleri kullandık. Yakalama: Kullanıcının IE kullanmak zorunda olduğunu biliyorduk.

O zaman FireFox için işe yaramadı. FireFox'un bunu değiştirip değiştirmediğini bilmiyorum, ancak HTML öğelerine kendi niteliklerinizi eklemenin okuyucunuzun tarayıcısı tarafından desteklenip desteklenmeyebileceğini unutmayın.

Okuyucunuzun hangi tarayıcıyı kullandığını (ör. Şirket için dahili bir web uygulaması) kontrol edebiliyorsanız, elbette deneyin. Ne acıtabilir, değil mi?


0

Ajax sayfaları bu şekilde yapıyorum ... oldukça kolay bir yöntem ...

    function ajax_urls() {
       var objApps= ['ads','user'];
        $("a.ajx").each(function(){
               var url = $(this).attr('href');
               for ( var i=0;i< objApps.length;i++ ) {
                   if (url.indexOf("/"+objApps[i]+"/")>-1) {
                      $(this).attr("href",url.replace("/"+objApps[i]+"/","/"+objApps[i]+"/#p="));
                   }
               }
           });
}

Bu nasıl çalışır temelde 'ajx' sınıfına sahip tüm URL'lere bakar ve bir anahtar kelimenin yerini alır ve # işaretini ekler ... böylece js kapatılırsa URL'ler normalde yaptıkları gibi davranır ... all " apps "(sitenin her bölümü) kendi anahtar kelimesine sahiptir ... tek yapmam gereken daha fazla sayfa eklemek için yukarıdaki js dizisine eklemektir ...

Örneğin, geçerli ayarlarım:

 var objApps= ['ads','user'];

Yani ben gibi bir url varsa:

www.domain.com/ads/3923/bla/dada/bla

js komut dosyası / ads / parçasının yerini alır, böylece URL'm

www.domain.com/ads/#p=3923/bla/dada/bla

Sonra buna göre sayfayı yüklemek için jquery barbekü eklentisini kullanıyorum ...

http://benalman.com/projects/jquery-bbq-plugin/


0

Meta veri eklentisini, jQuery ile almayı ve kullanmayı kolaylaştıracak şekilde html etiketi ile rasgele veri saklama sorununa mükemmel bir çözüm olarak buldum.

Önemli : Eklediğiniz gerçek dosya 37 kb değil , yalnızca 5 kb'dir (indirme paketinin tamamıdır)

İşte bir Google Analytics izleme etkinliği oluştururken kullandığım değerleri depolamak için kullanıldığına bir örnek (not: data.label ve data.value isteğe bağlı parametreler olur)

$(function () {
    $.each($(".ga-event"), function (index, value) {
        $(value).click(function () {
            var data = $(value).metadata();
            if (data.label && data.value) {
                _gaq.push(['_trackEvent', data.category, data.action, data.label, data.value]);
            } else if (data.label) {
                _gaq.push(['_trackEvent', data.category, data.action, data.label]);
            } else {
                _gaq.push(['_trackEvent', data.category, data.action]);
            }
        });
    });
});

<input class="ga-event {category:'button', action:'click', label:'test', value:99}" type="button" value="Test"/>

0

Html'de, özellik adının önünde 'data-' önekiyle özel nitelikleri depolayabiliriz.

<p data-animal='dog'>This animal is a dog.</p>. Belgeleri kontrol edin

Aşağıdaki gibi jQuery kullanarak özellikleri dinamik olarak ayarlamak ve almak için bu özelliği kullanabiliriz:

<p id='animal'>This animal is a dog.</p>

Daha sonra yukarıdaki etiket için 'cins' adı verilen bir özellik oluşturmak için şunu yazabiliriz:

$('#animal').attr('data-breed', 'pug');

Verileri istediğiniz zaman almak için şunu yazabiliriz:

var breedtype = $('#animal').data('breed');


0

Gerçek iş sunucu tarafında yapıldıysa, neden çıktıdaki html etiketlerinde özel bilgilere ihtiyacınız var? sunucuda bilmeniz gereken tek şey, özel bilgilerinizle birlikte her tür yapı listesi için bir indekstir. Sanırım bilgileri yanlış yerde saklamak istiyorsunuz.

Ne kadar talihsiz olsa da, çoğu durumda doğru çözümün doğru çözüm olmadığını anlayacağım. Bu durumda, ekstra bilgileri tutmak için bazı javascript oluşturmayı şiddetle öneririm.

Yıllar sonra:

Bu soru, data-...öznitelikler html 5'in ortaya çıkmasıyla geçerli bir seçenek haline gelmeden yaklaşık üç yıl önce gönderildi , böylece gerçek değişti ve verdiğim orijinal cevap artık alakalı değil. Şimdi bunun yerine veri özniteliklerini kullanmanızı öneririm .

<a data-articleId="5" href="link/for/non-js-users.html">

<script>
    let anchors = document.getElementsByTagName('a');
    for (let anchor of anchors) {
        let articleId = anchor.dataset.articleId;
    }
</script>

javascript'e nasıl veri aktarmanız gerekiyor?
nickf
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.