2013-07-24 17 views
20

node ve link sınıflarıyla birlikte bir dizi SVG öğesi var. Programım, bir öğenin SVG öğelerinin herhangi birinin üzerine geldiğinde node sınıfına veya link sınıfına sahip olup olmadığını algılamalıdır. Ancak, bazı nedenlerden dolayı, .hasClass() çalışmak görünmüyor:jQuery .hasClass() yöntemi, SVG öğeleri için başarısız oluyor

$(".node").hover(function(evt){ 
    console.log($(this).attr("class")); //returns "node" 
    console.log($(this).hasClass('node')); //returns false 
}, function(){console.log("Done");}); 

Yani üzerinde süpürdü eleman sınıfını node vardır ve console.log($(this).attr("class")); ile gösterildiği gibi jQuery da olduğunu tespit ama nedense gerçek için .hasClass() başarısız. Bu neden? SVG yüzünden başarısız mıdır?

+1

sadece bir yan not, sen) 'eksik; (sonunda' :) ve [benim için iş gibi görünüyor] http://jsfiddle.net/hungerpain/V4BNT /) – krishgopinath

+0

İlginç ... '$ (this) .attr ("class") 'a eşit bir değişken ayarlamayı deneyin ve o halde" hasClass "öğesini kullanın. Hala yanlış mı? – tymeJV

+5

SVG içindeki öğeler gerçekten HTML değildir ve bu öğelerden eksik özellikler vardır, bu nedenle özniteliğin işe yaraması, ancak className özelliğini muhtemelen kontrol eden hasClass kullanımı, çalışmaz. – adeneo

cevap

11

HTML öğesine yönelik sınıf özniteliği, SVG'de aynı anlama sahip değil.

$("<b></b>").addClass($(this).attr("class")).hasClass("node") 

Ya SVG öğeleri için

/(^|\s)node(\s|$)/.test($(this).attr("class")) 

. Bir sözdizimi hatası, eski bir tarayıcı kullanarak, bir eski kullanarak:

DÜZENLEME .hasClass http://jsfiddle.net/X6BPX/1/

Yani sorun aşağıdakilerin herhangi bir kombinasyonu olabilir (en azından IE9 ve FF) sadece iyi iş gibi görünüyor jQuery sürümü.

+0

SVG'de sınıf başka ne anlama geliyor? – Bergi

+0

@Bergi - Bu, className vs class gibi tarayıcıya özel kancalarla HTML öğelerinde olduğu gibi özel bir stil özelliği yerine normal bir özelliktir. –

+0

http://www.w3.org/TR/SVG/styling.html#ClassAttribute – Bergi

-4

Çalışmaları. Bergi Açıklamalarda belirttiği gibi Ancak fonksiyonunu

$(".node").hover(function(evt){ 
    console.log($(this).attr("class")); //returns "node" 
    console.log($(this).hasClass('node')); //returns false 
}, function(){console.log("Done");}); 

http://jsfiddle.net/X6BPX/

+0

Teşekkürler Rick, ama eksik parantezin bir yazım hatası olduğu yorumlarında açıklığa kavuştum. Bilgisayarımdaki işlevi kapalı. –

+0

im sry. bunu okumadı. ama işe yarıyor :) –

+0

@Rick: "hasClass ('node')' false döndürdüğünde bu "nasıl çalışır"? – Tom

5

kapatmak emin olun jQuery sessizce normal DOMString yerine bir SVGAnimatedString nesne dönen className dolayı SVG öğeleri üzerinde başarısız olur.

Karşılaştırma için bkz. this JSFiddle.

Bu konuda bir çekme isteği göndermek için cazip, ama hızlı proje arama yaptı ve görünüşe göre SVG konularında jQuery proje duruşu wontfix olduğunu edilmiştir: https://github.com/jquery/jquery/pull/1511

Eğer D3 kullanıyorsanız, size d3.select(this).classed('node') kullanabilirsiniz . D3'ün hem HTML öğeleri hem de SVG öğeleri için doğru şekilde döndüğünü unutmayın.

2

Bu, şimdiye kadarki en hızlı seçenek değil, ancak olası bir çözümdür. JQuery's hasClass kullanmak yerine, class özniteliğini bir dize olarak alabilir ve üzerinde arama yapmak için indexOf kullanabilirsiniz. Muhtemelen bu durumun başarısız olacağı durumlar vardır, bu yüzden süper basit projeler dışında bunu tavsiye etmem.

Çalışma örneği:

var s = $(this).attr('class'); 
if(s.indexOf('node')!==-1){ 
    // do something 
} 

Unutmayın: bir şey bulamıyorum indexOf döner -1 değil 0. Alt dizgi 0 dizininde başlatıldığında 0 döndürülür.

0

Bu jquery 3.x.x sürümleri için addClass, removeClass, hasClass jquery yöntemleri için bir kesmek.

$.fn.extend({ 
    addSVGClass: function (cls) { 
     return this.each(function() { 
      var classList = $(this).attr('class'); 
      if (classList) { 
       var classListArr = classList.split(" "); 
       if (classListArr.indexOf(cls) === -1) { 
        classListArr.push(cls); 
        classList = classListArr.join(" ").trim(); 
        $(this).attr('class', classList); 
       } 
      } else { 
       $(this).attr('class', cls); 
      } 
     }); 
    }, 
    removeSVGClass: function (cls) { 
     return this.each(function() { 
      var classList = $(this).attr('class'); 
      if (classList) { 
       var classListArr = classList.split(" "); 
       if (classListArr.indexOf(cls) !== -1) { 
        delete classListArr[classListArr.indexOf(cls)]; 
        classList = classListArr.join(" ").trim(); 
        $(this).attr('class', classList); 
       } 
      } 

     }); 
    }, 
    hasSVGClass: function (cls) { 
     var el = this[0]; 
     var classList = $(el).attr('class'); 
     if (classList) { 
      var classListArr = classList.split(" "); 
      if (classListArr.indexOf(cls) !== -1) { 
       return true; 

      } else { 
       return false; 
      } 
     } 
     return false; 
    } 
}); 

kullanımı:

$('.svg-element').addSVGClass('selected'); 
İlgili konular