使用Jquery

时间:2016-06-29 19:23:33

标签: javascript jquery html svg

经过几个小时毫无结果的实验​​,网络搜索,Jquery API文档的咨询以及对看似相关的stackoverflow帖子的研究,我决定让这个工作的唯一希望就是转向这里的社区。希望有人能够让我深入了解为什么这不起作用以及如何解决它!

在我正在开发的网络应用程序中,我使用了几个交互式SVG图像,有时在一个页面上有多个实例。为了防止不同的SVG图像踩在彼此的脚趾上,每个中的交互元素都带有各种“条形码”,附加到它们的id属性。反过来,每个图像的条形码都编码在svg标签的id属性中。为了让页面显示具有正确初始状态的svg,我需要在加载后立即从svg获取id属性,并将其传递给另一个脚本以在目标SVG中设置正确的属性。

单个SVG通过AJAX调用加载,因此:

$(document).ready(function(){
    //mapId is supplied in various ways in different contexts, for example:
    var mapId = $("#mapId").name;
    loadSvgMap(mapId);
}

function loadSvgMap(mapId) {

  return jQuery.ajax({
    url: "[% c.uri_for('/maps/update_map/') %]" + mapId,
    success: function(result) {
        if(result.isOk == false) {
            alert("Bad response from server: " + result.message);
        } else {
            $("#som_map").load(result);
        }
    },
    error: function(result, status, errorThrown) {
        alert("Map retrieval failed: " + status + " " + result.status);
    },
    async: true,
    dataType: 'text',
    cache: false
  });
}

在这个阶段,我需要获取已加载的SVG的id属性。问题是,当我尝试这样做时,页面上似乎不存在SVG:

$(window).load(function() {
    var svg = $("svg")[0];
    console.log(svg);
    //returns "undefined"
}

问题似乎是当下一个代码块执行时,ajax调用尚未完成,因此SVG尚未出现在DOM中。我尝试在$(document).ready中使用$ .when,这是我想要使用的方法,但它似乎还没有等到SVG加载:

$.when(loadSvgMap(mapId)).done(function(a) {
    var map = $("svg")[0];
    console.log(map);
    //undefined
});

我找到了一个解决方法,但它并不理想,因为请求在每个ajax请求之后触发,而不仅仅是那些更改SVG的请求...

$(document).ajaxStop(function() {
    var svg = $("svg")[0];
    if (svg != null) {
        var map = svg.id;
        console.log(map);
        // do other stuff
    }
});

在每次ajax请求之后发生这样的攻击并不会破坏任何东西,但是如果我能让$ .when方法正常工作,那么似乎应该不太可能破坏事情。有什么想法吗?

3 个答案:

答案 0 :(得分:1)

使用异步函数时,放置这样的代码的最佳位置是callback函数 - 一旦控件从初始异步请求返回,它就会运行。在这种情况下,它将位于success来电的jQuery.ajax(..属性中:

function loadSvgMap(mapId) {

  jQuery.ajax({
    url: "[% c.uri_for('/maps/update_map/') %]" + mapId,
    success: function(result) {
        if(result.isOk == false) {
            alert("Bad response from server: " + result.message);
        } else {
            $("#som_map").load(result);
            // grab id here
            console.log($('svg').attr('id'));
        }
    },
...

答案 1 :(得分:0)

SVG中的Id和类名是对象而不是HTML字符串,因此jQuery使用的id和类选择器将不起作用。 IE..jQuery只能理解HTML DOM而不是SVG DOM。

所以,给出类似的东西:

<object id="svg" data="img/yoursvg.svg" type="image/svg+xml" height="50" width="50">

</object> 

您可以使用以下内容:

window.onload=function() {
    // The Object
    var a = document.getElementById("svg");
    // The SVG document inside the Object tag
    var svgDoc = a.contentDocument;
    // One of the SVG items by ID;
    var svgItem = svgDoc.getElementById("svgItem");
    // Do something to it.
};

答案 2 :(得分:0)

所以问题原来是嵌套在原始ajax函数中的.load()调用。外部调用只检索静态svg文件的位置,然后使用内部ajax调用将其加载到页面中。当然,.when()只知道外部调用,所以它是在svg实际加载之前触发的。

解决方案是为&#34;内部&#34;提供单独的ajax功能。使用.html()加载内容,并从嵌套的.when()调用它:

function loadSvgMap(mapId) {
    return jQuery.ajax({
        url: "[% c.uri_for('/maps/update_map/') %]" + mapId,
        success: function(result) {
            if(result.isOk == false) {
                alert("Bad response from server: " + result.message);
            } else {
                // Simply return the result
            }
        },
        error: function(result, status, errorThrown) {
            alert("Map retrieval failed: " + status + " " + result.status);
        },
        async: true,
        dataType: 'text',
        cache: false
    });
}

function loadSvgContent(mapUrl) {
    return jQuery.ajax({
        url: mapUrl,
        success: function(result) {
            if(result.isOk == false) {
                alert("Bad response from server: " + result.message);
            } else {
                $("#som_map").html(result);
            }
        },
        error: function(result, status, errorThrown) {
            alert("Map retrieval failed: " + status + " " + result.status);
        },
        async: true,
        dataType: 'text',
        cache: false
    });
}

$.when(loadSvgMap(mapId)).done(function(mapUrl) {
    $.when(loadSvgContent(mapUrl)).done(function(a) {
        var svg = $("svg")[0];
        var map = svg.id;
        console.log(map);
        // Works!!
    });
});

非常感谢@MikeMcCaughan和@ThomasW指出我正确的方向!