经过几个小时毫无结果的实验,网络搜索,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方法正常工作,那么似乎应该不太可能破坏事情。有什么想法吗?
答案 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指出我正确的方向!