2015-07-02 76 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