2015-07-02 122 views
1

我遇到了一些基本的html和javascript中的數據屬性問題。我在整個頁面中有幾個鏈接,可以動態插入地圖和「關閉」鏈接以擺脫地圖。JQuery數據屬性選擇器undefined

的鏈接都是相似的:

<a class="maplocation" href="#" data-coords="4645/234234" data-zoom="9">Link text<span class="mapslideicon"></span></a> 

而且在點擊這些鏈接的JavaScript是:

$("a.maplocation").click(function() { 
    if ($(this).data("mapopen") == true) { 
     // Map already clicked and open, do nothing 
    } else { 
     var timeStamp = $.now(); 
     var mapID = "m_"+timeStamp; 
     var mapCloseID = "c_"+timeStamp; 
     var anchorID = "a_"+timeStamp; 
     var mapClass = 'widemap'; 
     var mapDiv = $("<div class='"+mapClass+"' id='"+mapID+"'>&nbsp;</div><a href='#' id='"+mapCloseID+"' class='maplocationclose'>close</a>"); 
      mapDiv.insertAfter($(this).parent()); 
     // Set a data attribute on the link to let it know a map is open 
     $(this).data("mapopen", true); 
     // Set a data attribute on the link so that we can reference it from the close button 
     $(this).data("anchorid", anchorID); 
    } 
    return false; 
}); 

這對地圖創建一個div,則以數據屬性上的原始錨說地圖是開放的,並且還創建了關閉地圖的錨點。

當關閉地圖錨點擊它執行以下操作:

$('body').on('click', 'a.maplocationclose', function(){ // delegated. 
     var id = $(this).attr('id'); 
     idNo = id.split("_"); 
     var assocMapID = "m_"+idNo[1]; 
     var assocAnchorID = "a_"+idNo[1]; 
     $("#"+id).remove(); 
     $("#"+assocMapID).slideUp(300, function() { 
      $("#"+assocMapID).remove(); 
     }); 
    // Set a data elemt on the original map link that let's us know the map is closed again 
    $('.maplocation[anchorid="'+assocAnchorID+'"]').data("mapopen", false); 
    return false; 
}); 

這一切工作,但我有從接近錨訪問數據屬性的難度。按照我的意圖,它從原始鏈接中引用良好,並將映射屬性設置爲true並將其讀取爲true。但是,當我在關閉錨點中將其設置爲false時,它找不到它,並且它從未設置。

我運行一個測試(從maplocationclose函數內),看看我能找到錨的任何數據屬性,如:

console.log("Zoom Attr is: " + $('a.maplocation[anchorid="'+assocAnchorID+'"]').data('zoom')); 

他們返回「未定義」。

回答

5

使用.data()附加數據不會添加/更改任何data-*屬性,因此您的屬性選擇器不會匹配任何內容。

您可以使用過濾器來代替,但:

$('.maplocation').filter(function(){ 
    return $(this).data('anchorid') == assocAnchorID; 
}).data("mapopen", false); 
+1

即使它_did_工作(因爲它爲實際的屬性),這將是'$(」 .maplocation [data-anchorid =''+ assocAnchorID +'「]')...' – Mackan

+0

@Mackan值得注意的是,我猜是的。 – George

+0

我對此很感興趣,所以請原諒任何錯誤,但也許我會用'console.log'示例將焦點從現有問題轉移到現有問題上。如果這部分是一個錯誤,使用'data- *'屬性,我會糾正它,儘管可能應該不在本例中。我的問題是從'maplocationclose'函數設置'mapopen'屬性,它什麼也不做。我相信我專門爲我的'mapopen'屬性使用數據緩存。你的理由是否仍然適用?感謝您的建議。 – biscuitstack

1

只是爲了上的評論擴展以下@Georges答案。

你的代碼是導致問題:

$('.maplocation[anchorid="'+assocAnchorID+'"]').data("mapopen", false); 

現在,首先是所有的語法,這個選擇是錯誤的。即使你在元素上有一個名爲anchorid的數據屬性,那也不是你如何檢索它。您應該包含data-部分; data-anchorid

檢查下面的例子,和控制檯輸出,瞭解它爲什麼失敗:

<div class="maplocation" data-anchorid="25" data-test="works">...</div> 

var x = $('.maplocation[anchorid="25"]'); 
var y = $('.maplocation[data-anchorid="25"]'); 
console.log('Length of x: ' + x.length) //This is 0, because element x does not exist 
console.log('Length of y: ' + y.length) //1 
console.log('Value of x: ' + x.data('test')) //This is undefined because element x does not exist 
console.log('Value of y: ' + y.data('test')) //works 

但是,這並不能解決問題,因爲你有實際的元素,你可以」無屬性也可以使用該選擇器。 data()沒有寫入元素,就像attr()一樣,但是它只是將鍵/值添加到jQuery內部集合/緩存中。上data()

jQuery的文檔:與匹配的元素相關聯的或在指定的數據存儲返回 值對於該組的 匹配元素的第一個元素

存儲任意數據。上attr()

jQuery的文檔:

獲取第一元素的屬性的值的集合中的 匹配元素或設置每個匹配 元件的一個或多個屬性。

爲示意圖參見本:

$('.maplocation').data('mydata','myvalue'); //Only added to jQuery collection/internal cache, not DOM/element 
console.log($('.maplocation[data-mydata="myvalue"]').data('test')) //undefined 
$('.maplocation').attr('data-mydata','myvalue'); //Added to DOM/element 
console.log($('.maplocation[data-mydata="myvalue"]').attr('data-test')) //works 

解決方案
所以,喬治所提供的解決方案將工作,因爲它會得到所有元素的集合與.maplocation,然後篩選只返回具有.data('anchorid') == assocAnchorID的那個。

其他選項:

  • 可以使用attr()而不是data()設置/獲取。一切都將被視爲字符串,因此您必須相應地修改代碼,並且記住在使用時包含'data-'(例如:data('test')應該是attr('data-test'))。例如:

    $('.maplocation[data-anchorid="'+assocAnchorID+'"]').attr("data-mapopen", "false"); 
    
  • 您可以使用另一種選擇來獲取元素,然後用data()正常。這僅僅是因爲我不知道是否closest將與您結構工作的例子:

    $(this).closest('.maplocation').data("mapopen", false); 
    
+1

非常感謝您花時間添加這個額外的特定後續Mackan。現在寫的東西對我來說很有意義,而不是在我求助於此之前閱讀過的一些片斷之外。無論是有關'.data()'的錯誤信息,還是我在選擇性閱讀方面都比我想象的更糟糕)無論哪種方式,您和@George示例都解決了這個問題,並且在信息海洋主題(有很多類似的帖子,因爲我相信你知道)。再次感謝。 – biscuitstack

+1

@biscuitstack很明顯,我發佈了它幫助,但我也有一個次要目標:測試我自己的知識,看看我是否可以像我希望的那樣解釋它,並且如果我的理解和示例支持:)正如你所說有很多類似的信息,所以我可能不會離開這個。我在寫這個亂七八糟的時候學到了一些知識,所以這是雙贏的;)把'data()'想象成'prop()',與'attr()'相比。 – Mackan

+1

我會放棄它。老實說,我在做這個問題之前先做功課。我已經閱讀並試用了許多類似的問題和解決方案,這讓我難以置信。我不是來自編程背景,也沒有任何我發現的解釋對於那些從不同角度出現的人來說頭腦發熱,不管他們是否準確。這個徹底的解釋讚揚了我的(持續性的)問題,並且對任何人在搜索該問題的更多細節時都很有用。 – biscuitstack