【问题标题】:Populate object tag with SVG code with javascript使用 javascript 使用 SVG 代码填充对象标签
【发布时间】:2018-04-24 23:09:33
【问题描述】:

我确实有可用的 svg 代码作为 javascript 变量中的文本。我需要将其设置为对象标签(不是 SVG 或 IMG)中的图像。这可能吗?

Create SVG Object tag with Cached SVG code 讨论过这个问题,没有任何回应。

【问题讨论】:

    标签: javascript svg dynamically-generated object-tag


    【解决方案1】:

    有几种方法可以做到这一点,但它们并不都允许您访问对象的 contentDocument...

    最简单的方法是将 SVG 标记转换为数据 URI。

    但是浏览器会认为这个文档是跨域资源,然后会禁止你通过js访问。

    // an svg string
    const svgStr = `<svg width="120" height="120" viewBox="0 0 120 120"
        xmlns="http://www.w3.org/2000/svg">
    
      <rect x="10" y="10" width="100" height="100"/>
    </svg>`;
    // as dataURI
    const dataURI = 'data:image/svg+xml;charset=utf8, '+ encodeURIComponent(svgStr);
    obj.data = dataURI;
    
    // do some checks after it has loaded
    obj.onload = e => {
      console.log('loaded');
      try{  
        console.log(obj.contentDocument.documentElement.nodeName);
        }
      catch(err){
        console.log('but cant access the document...');
        console.error(err);
      }
    };
    &lt;object id="obj"&gt;&lt;/object&gt;

    在大多数浏览器中规避此问题的一种方法是使用 blobURI,应该标记文档的来源,从而允许我们访问文档。 但是 IE 并没有在 blobURIs 上设置这个来源......所以这个浏览器也不允许你访问 contentDocument。

    以下 sn-p 将在所有浏览器中充当 IE,因为 StackSnippets iframe 源自 null:

    // an svg string
    const svgStr = `<svg width="120" height="120" viewBox="0 0 120 120"
        xmlns="http://www.w3.org/2000/svg">
    
      <rect x="10" y="10" width="100" height="100"/>
    </svg>`;
    
    // as blobURI
    const blob = new Blob([svgStr], {type:'image/svg+xml'})
    const blobURI = URL.createObjectURL(blob);
    obj.data = blobURI;
    
    // do some checks after it has loaded
    obj.onload = e => {
      console.log('loaded');
      try{  
        console.log(obj.contentDocument.documentElement.nodeName);
        }
      catch(err){
        console.log('but cant access the document...');
        console.error(err);
      }
    };
    &lt;object id="obj"&gt;&lt;/object&gt;

    但this fiddle 可以在除 IE 浏览器之外的所有浏览器中使用。

    因此,在 IE 上也可以使用的一种方法是使用一个空的 HTML 文档,从同一来源提供服务,我们将在加载 svg 后在其上附加它。

    // first load an same-origin document (not sure if about:blank works in IE...)
    obj.data = 'empty.html';
    
    // once it has loaded
    obj.onload = e => {
      // parse our svgString to a DOM element
      const svgDoc = new DOMParser().parseFromString(svgStr, 'image/svg+xml');
      const objDoc = obj.contentDocument;
      // ask the object's document to adopt the svg node
      const toAppend = objDoc.adoptNode(svgDoc.documentElement);
      // now we can append it and it will display
      objDoc.documentElement.appendChild(toAppend);
    };
    

    As a fiddle.

    【讨论】:

    • 用empty.html我浪费了一个对服务器的http请求,因为它是对象元素的数据源,所以无法缓存
    • @Nillus 是的,你会向一个 28 字节的文件发出 http 请求……(只需要&lt;!DOCTYPE html&gt;&lt;html&gt;&lt;/html&gt;)。
    猜你喜欢
    • 2019-10-22
    • 2016-01-12
    • 2015-12-07
    • 2018-12-08
    • 2020-05-12
    • 1970-01-01
    • 2021-12-23
    • 2016-04-25
    • 2021-11-10
    相关资源
    最近更新 更多