JQuery数据属性选择器未定义

时间:2015-07-02 13:13:38

标签: javascript jquery html css

我在某些基本的html和javascript中遇到数据属性问题。我在整个页面中有几个链接,可以动态插入地图并关闭'链接摆脱地图。

链接类似于:

<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'));

他们正在返回&#39; undefined&#39;。

2 个答案:

答案 0 :(得分:5)

使用.data()附加数据不会添加/更改任何data-*属性,因此您的属性选择器将无法匹配任何内容。

您可以使用过滤器代替:

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

答案 1 :(得分:1)

只是为了扩展@Georges回答后的评论。

导致问题的代码:

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

现在,首先这个选择器的语法是错误的。即使您在元素上有一个名为anchorid的数据属性,也不是您检索它的方式。您应该包含数据 - 部分; 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

<强>解决方案
因此,George提供的解决方案将起作用,因为它将使用.maplocation获取所有元素的集合,然后对其进行过滤以仅返回具有.data('anchorid') == assocAnchorID的元素。

其他选择:

  • 您可以使用attr()代替data()进行设置/获取。所有内容都将被视为字符串,因此您必须相应地修改代码,并在使用时记住包含&#39;数据 - &#39; (例如:{{1应该是data('test'))。例如:

    attr('data-test')
  • 您可以使用其他选择器来获取元素,然后照常使用$('.maplocation[data-anchorid="'+assocAnchorID+'"]').attr( "data-mapopen", "false" ); 。这只是一个例子,因为我不知道data()是否适用于您的结构:

    closest