嵌入/渲染异步加载服务器端生成的 SVG 时出现问题



我正在尝试覆盖一些JavaScript代码以优化我无法访问原始源代码的现有解决方案。它是一个基于Liferay的门户,带有一些渲染SVG图像的Portlet。SVG 用作图形导航元素,可用于向下钻取到技术服务模型。SVG 图像的加载和刷新可能会很慢,因为它的实现方式。SVG 消失几秒钟,因为刷新实际上对 Web 服务器执行了 2 个请求。首先,完整的对象标记被重新生成服务器端并重新插入到 dom 中。第一个请求的响应如下所示:

<div><object type="image/svg+xml" data="generateSvg.svg” width="100" height="300" name="svgId"> <param name="wmode" value="transparent"></object></div>

SVG 的实际请求从第一个响应文本插入 DOM 并删除原始对象标记时开始。由于 SVG 图像可能会变得非常复杂,并且软件会变得有些缓慢,因此 SVG 在 Web 浏览器接收和渲染时会消失并返回。我想跳过第一步,并通过异步刷新 SVG 来确保图像不会"闪烁"。使用 jQuery,我可以覆盖原始的 JavaScript 代码并获取 SVG 的 url 并执行 jQuery ajax 请求。我还能够在 DOM 中插入结果,但是当我将其作为内联 SVG 插入时,图像的渲染与嵌入对象标签时不同。svg 内容元素的某些部分被切断,当 SVG 添加为带有外部 URL 的对象标签时,不会发生这种情况。

我要么想将 SVG 嵌入到对象标签中并异步加载其 url,要么找到内联 SVG 渲染问题的解决方法。我无法更改 SVG 代码,因为它是现有软件的一部分。我有一种方法可以将异步加载的数据添加到对象标签中,而无需将 url 添加到数据属性?

我用于添加 SVG 的 JavaScript 如下所示:

indentifier.loadSvg = (function(){
    if(this.svgUrl){                        
        $.ajax({
            url: this.svgUrl,
            //enclose the right div in which the svg should be loaded as a context
            context: $('#_layout_WAR_Portlets_INSTANCE_' + this.portalId + '_plugin'),
            dataType: 'xml'
            }).done(function(svgDoc) {
                //construct an svg node and add it to the DOM
                var svgNode = $('svg', svgDoc);
                var docNode = document.adoptNode(svgNode[0]);
                $(docNode).attr('width', '100%').attr('height', '300');
                this.html(docNode);
            });
    }
});

我不确定在对象标签中是否可行,但 Iframe 应该可以解决问题。您可以尝试使用 javascript 创建一个新的 Object 标签,加载 svg 并用新对象替换旧对象。它看起来像这样:

var datasrc = "#";
// Create new object tag
var newobj = jQuery('<obj>', {
    id: 'newobject',
    data: datasrc,
    type: 'image/svg+xml'
});
    // Set parameters
    jQuery('<param />', {
        name: 'src',
        value: datasrc
    }).appendTo('#newobj');
    jQuery('<param />', {
        name: 'wmode',
        value: 'transparent'
    }).appendTo('#newobj');
// Dynamically load content and replace when done
newobj.load(datasrc,function(){
    $('#objectwrapper').empty();
    newobj.appendTo('#objectwrapper');
    alert("succes"); // Just to check if this works!
});

JSFiddle: http://jsfiddle.net/cfERU/9/

警报会触发两次,我相信这是JSFiddle的事情。

最新更新