【问题标题】:Rails link_to and audio_tagRails link_to 和 audio_tag
【发布时间】:2013-12-25 22:13:12
【问题描述】:

当我在 Rails 中使用 link_to 标记时,我试图找出在后台播放 wav 文件(类似 HTML5)的最佳方式。

这是我的一个观点的示例链接:

<%= link_to 'At Station', at_station_mdt_index_path, :class => 'btn btn-success btn-medium', :method => :put, :remote => true %>

我想知道如何使用 audio_tag 在按下按钮时触发声音。我尝试在 link_to ERB 中组合 audio_tag,但出现各种语法错误。

任何示例将不胜感激。

更新于 01/04/14-10:18am CT:声音一次正确地触发。但是,由于将 :id 添加到 link_to 链接不再触发 rails 路径来更改对象,因此只会播放声音

查看代码:

    <%= link_to 'En Route', en_route_mdt_index_path(:call_id => call.id), :class => 'btn btn-warning btn-medium', :method => :put, :remote => true, :id => "er" %>
            <%= link_to 'On Scene', on_scene_mdt_index_path(:call_id => call.id), :id => 'to', :class => 'btn btn-primary btn-medium', :method => :put, :remote => true, :id => "os"  %>
            <%= link_to 'To Hospital', to_hospital_mdt_index_path(:call_id => call.id), :class => 'btn btn-warning btn-medium', :method => :put, :remote => true, :id => "to" %>

 <audio id="en-route" class="audio_player" preload="true">
    <source src="audios/en-route.wav" type="audio/wav">
</audio>

<audio id="on-scene" class="audio_player" preload="true">
    <source src="audios/on-scene.wav" type="audio/wav">
</audio>

<audio id="to-hospital" class="audio_player" preload="true">
    <source src="audios/to-hospital.wav" type="audio/wav">
</audio>

<script>
$('#er').click(function (e) {
    e.preventDefault();
    $('#en-route')[0].currentTime = 0;
    $('#en-route')[0].play();
    return true;

});

$('#os').click(function (e) {
    e.preventDefault();
    $('#on-scene')[0].currentTime = 0;
    $('#on-scene')[0].play();
    return true;

});

$('#to').click(function (e) {
    e.preventDefault();
    $('#to-hospital')[0].currentTime = 0;
    $('#to-hospital')[0].play();
    return true;

});
</script>

【问题讨论】:

    标签: ruby-on-rails-3 html5-audio link-to


    【解决方案1】:

    这是一个播放 wav 文件的简单示例:

    http://jsfiddle.net/84pav/

    HTML:

    <a href="javascript:void(0)" id="playsound">At Station</a>
    
    <audio id="sound_effect" class="audio_player" preload="auto">
        <source src="http://www.villagegeek.com/downloads/webwavs/alrighty.wav" type="audio/wav">
    </audio>
    

    JavaScript:

    $('#playsound').click(function (e) {
        $('#sound_effect')[0].currentTime = 0;
        $('#sound_effect')[0].play();
        return false;
    });
    

    我在播放前设置了currentTime = 0,让它总是从头开始播放。

    它在 IE 上不起作用,因为 IE 不支持 wav 文件。

    【讨论】:

    • 这确实有效。但是,在我通过 Javascript 刷新部分内容后,该链接不再有效。只有在我重新加载整个页面后它才会起作用。我的 JS 函数每 10 秒刷新一次部分以获取新数据,这会导致音频标签无法加载。仅在页面刷新时。
    • 在您的问题中,您从 application.js 收到错误。这意味着您将脚本放在 assets.js 中的 js 文件之一中。我猜你在布局中加载了 application.js。通过部分重新加载,DOM 元素被替换。 click 事件需要再次绑定到新的 DOM 元素。但是你的脚本只加载了一次,所以它不起作用。有两种方法可以解决这个问题:(1) 将脚本放在您的部分中,以便每次重新加载页面时重新运行,或者 (2) 重新加载页面后,调用函数来绑定事件自己。
    • 我尝试将音频元素和 javascript 移动到部分中。即使使用适当的 ID 元素来区分这两个链接,页面上的任何链接都会触发这两种声音。此外,当 index.html.erb javascript 每 10 秒重新加载一次时,它会同时播放两种声音。我已经粘贴了我当前的代码供您查看。
    • @teknull,如果您想建议代码编辑,如何使用注释以便 Tyler Nguyen 可以根据他们的需要进行修改?请注意不要在 Edits 中更改代码。
    • @teknull,您应该删除音频标签中的 autoplay="false"。它会导致音频文件自动播放。不管你在 autoplay="anything" 里放什么,它都会自动播放。
    【解决方案2】:

    我在这个答案中做了一些假设:

    1. 您正在使用 HTML5 标记
    2. 您想要一个样式化的链接“按钮”来触发声音
    3. 您不想显示默认的 HTML5 音频播放器
    4. 声音文件存储在public/audios
    5. 声音文件已预加载到页面上

    不幸的是,audio_tag 的 Rails 3.2 实现已损坏 (https://github.com/rails/rails/issues/9373)。因此,除非您使用的是 Rails 4,否则最好使用实际的 HTML 标记。

    在这个例子中,我们在默认的 HTML5 音频播放器中加载一个 mp3 文件。以下 sn-p 应该在您的视图文件中。

    <audio id="sound_effect" class="audio_player" controls="false" preload="true">
      <source src="/audios/TrainWhistle.mp3" type="audio/mpeg">
    </audio>
    

    由于 HTML5 音频播放器带有“内置”显示镶边,您可能希望使用 css 将其放置在页面之外。在此示例中,您将在您的 css 文件中添加以下内容:

    .audio_player {
      position: absolute;
      top: -999em;
    {
    

    您的 link_to 标记看起来像:

    <%= link_to 'At Station', '#', class: 'btn btn-success btn-medium', id: 'playsound' %>
    

    实际播放声音的 javascript 看起来类似于这个 jQuery 示例:

    $('#playsound').on('click', function (e) {
      e.preventDefault();
      $('#sound_effect').currentTime = 0;
      $('#sound_effect').play();
      return false;
    });
    

    通过对 link_to 标记和 javascript 进行小的更改,可以轻松扩展此示例以支持多个文件。

    【讨论】:

    • 谢谢,这是正确的轨道。我编辑了代码以反映我的设置(我在 public/audios 目录中使用 wav 文件)。 CSS确实隐藏了很好的音频播放器。我已经取消隐藏它以查看发生了什么,因为当我单击 link_to 时它不会播放任何内容。它只是快速跳过文件。有什么想法吗 ?我已经编辑了您上面的代码示例以反映我的配置。
    • 当我取消隐藏 audio_player 类并尝试播放时,没有任何反应。它只是非常快地跳过文件。另外,无论我是否启用控件,音量图标都有一个斜线。我正在使用铬顺便说一句。虽然此功能将适用于 iOS Safari。
    • 你能发个链接吗?可能有助于调试。
    • 我只有在开发环境中才有这个。它没有部署到生产中。很抱歉给您带来麻烦。
    • 强制声音始终从头开始播放并不是一个坏主意。我也会用这个来更新我的答案。它可能会处理“高速”播放。
    【解决方案3】:

    这样的事情怎么样...

    function playSound(soundfile) {
      document.getElementById("playsound").innerHTML=
      "<embed src=\""+soundfile+"\" hidden=\"true\" autostart=\"true\" loop=\"false\" />";
    }
    
    $('#playsound').observe('click', function (event) {
      playSound('URL to soundfile');
      event.stop(); // Prevent link from following through to its given href
    });
    

    然后将playsound id 添加到您的链接中。

    【讨论】:

    • 感谢 JS。我已经尝试过了,但我得到了 Uncaught TypeError: Object [object Object] has no method 'observe' 在浏览器控制台中并且它不会触发 soundbyte。我已经更新了我的代码以反映您的建议,以防我的语法错误。
    • 我无法在本地尝试,这个例子主要是为了展示这个概念,你可能需要稍微调整一下才能为你工作。
    • 我正在研究它,但我是 JS/jQuery 新手。我需要找到更多示例,以便我更好地理解它并且可以使某些东西起作用。拔掉我的头发哈哈
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多