XHTML元素音频不允许作为SVG元素的子元素

时间:2017-02-13 17:49:59

标签: audio svg

我正在使用SVG,音频和一些JavaScript创建交互式信息图。

我可以使用W3C Validator通过直接输入验证文档,但是,在尝试通过URI或文件上传进行验证时出现此错误:

  

不允许XHTML元素音频作为SVG元素的子元素

我错过了什么?我理解<audio>不是标准SVG(实际上使用data-*属性同上)。我不明白的是为什么SVG标签中的命名空间声明不够。

以下是最低限度的案例:

<?xml version="1.0" encoding="utf-8"?>

<svg    xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    xmlns:html="http://www.w3.org/1999/xhtml"
    viewBox="0 0 640 640">

<defs>
    <audio id="consonant_pig_audio" xmlns="http://www.w3.org/1999/xhtml"><source type="audio/mpeg" src="https://bilingueanglais.com/tmp/ipa-infographic-preview-v1/audio/IPA-PIG.mp3"/></audio>
</defs>


<title>SVG with audio</title>

<rect class="trigger" width="640" height="640" data-target="consonant_pig" />


<script><![CDATA[
/** Shortcut to querySelector **/
function $(sel) { return document.querySelector(sel); }
function $all(sel) { return document.querySelectorAll(sel); }

/** Execute when the SVG is ready **/
(function() {

    $all( '.trigger' ).forEach( function( element ) {
        element.addEventListener( 'click', function() {

            var audio = $( '#' + this.getAttribute('data-target') + '_audio' );
            if ( audio !== null ) {
                try { audio.currentTime=0; } catch(e) {} audio.play();
            }


        }, false );
    });

})();
]]></script>

</svg>

1 个答案:

答案 0 :(得分:0)

根据Robert Longson的评论,我只使用<foreignObject>生成100%有效的SVG - 请注意,其内容需要包含在<body>中才有效。

(我也删除了data-attribute,因为我希望代码能够完全验证,即使它们在实践中在浏览器中工作并且是SVG2规范的一部分。)

<?xml version="1.0" encoding="utf-8"?>

<svg xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    viewBox="0 0 640 640">

<defs>
    <foreignObject width="0" height="0" requiredExtensions="http://www.w3.org/1999/xhtml">
        <body xmlns="http://www.w3.org/1999/xhtml">
            <audio id="consonant_pig_audio" xmlns="http://www.w3.org/1999/xhtml"><source type="audio/mpeg" src="https://bilingueanglais.com/tmp/ipa-infographic-preview-v1/audio/IPA-PIG.mp3"/></audio>
        </body>
    </foreignObject>
</defs>

<title>SVG with audio</title>

<rect class="trigger" width="640" height="640">
    <metadata>consonant_pig</metadata>
</rect>

<script><![CDATA[
/** Shortcut to querySelector **/
function $(sel) { return document.querySelector(sel); }
function $all(sel) { return document.querySelectorAll(sel); }

/** Execute when the SVG is ready **/
(function() {

    $all( '.trigger' ).forEach( function( element ) {
        element.addEventListener( 'click', function() {
            //console.log( this.querySelector( 'metadata' ).textContent );
            var audio = $( '#' + this.querySelector( 'metadata' ).textContent + '_audio' );
            if ( audio !== null ) {
                try { audio.currentTime=0; } catch(e) {} audio.play();
            }


        }, false );
    });

})();
]]></script>

</svg>

对于类似data-*的属性,另一种验证方法是依赖id属性或<desc>元素。 (如果单个元素需要多个data-* - 类似的属性,<metadata>不再是一个选项,因为它不支持class属性,而<desc>则属于。{1}}。