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

时间:2013-10-10 08:43:15

标签: javascript jquery svg

我正在尝试覆盖一些JavaScript代码,以优化我无法访问原始源代码的现有解决方案。它是一个基于Liferay的门户,其中包含一些呈现SVG图像的portlet。 SVG用作图形导航元素,可用于深入研究技术服务模型。由于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);
            });

    }
});

1 个答案:

答案 0 :(得分:0)

我不确定它是否可能在对象标签内,但是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的事情。