2017-02-13 10 views
1

Я создаю интерактивную инфографику с использованием SVG, аудио и некоторого JavaScript.Звук элемента XHTML не разрешен как дочерний элемент SVG

можно проверить документ путем прямого ввода с помощью 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

Валидатор стара, data- атрибуты и аудио новые (часть встроенной спецификации SVG 2). –

+0

@RobertLongson Это сделает мой SVG действительным в соответствии с SVG 1.1? –

+0

В SVG 1.1 все элементы в пространстве имен, отличных от SVG, должны строго быть дочерними элементами foreignObject. На практике это никогда не было необходимым для звукового тега, который я думаю. –

ответ

0

Согласно комментарию Роберта Лонгсона, я просто использовал <foreignObject> для получения 100% правильного SVG - обратите внимание, что его содержание должно быть завернуто в <body> быть действительными.

(я избавилась от данных атрибута, как я хотел, чтобы код для полной проверки, даже если они работают в браузерах на практике и являются частью 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-*-like, другой подход, который проверяет, должен был полагаться на атрибут id или на элементы <desc>. (Если несколько data-* -как атрибуты необходимы для одного элемента, <metadata> перестает быть вариант, поскольку он не поддерживает атрибут class, в то время как <desc> делает.)