我是铁杆新手,我只想使用javascript提取rails对象和属性(@ tracks.audio)。我想动态地从db应用音频文件,而不是使用在注释行1,2,3
上看到的硬编码版本这是tracks.js.erb
// Event listener for DOM
document.addEventListener("DOMContentLoaded", theDOMHasLoaded, false);
// array of audio files (stored in a folder called music)
var files = ["<% @tracks.audio %>" , // this code doesn't work!
"chooseyourweapon.mp3", // 1
"interlude.mp3", // 2
"scriptures.mp3" // 3
];
///////////////////////////////////////////////
// Find and store audio info
///////////////////////////////////////////////
// array for AudioObjects
var audioList = [];
// components and the index for their AudioObject
var componentDict = {};
// store AudioObject that is currently playing
var playingAudio = null;
// store playhead id if one is being dragged
var onplayhead = null;
/* AudioObject Constructor */
function AudioObject(audio, duration) {
this.audio = audio;
this.id = audio.id;
this.duration = duration;
}
/* bindAudioPlayer
* Store audioplayer components in correct AudioObject
* num identifes correct audioplayer
*/
AudioObject.prototype.bindAudioPlayer = function (num) {
this.audioplayer = document.getElementById("audioplayer-" + num);
this.playbutton = document.getElementById("playbutton-" + num);
this.timeline = document.getElementById("timeline-" + num);
this.playhead = document.getElementById("playhead-" + num);
this.timelineWidth = this.timeline.offsetWidth - this.playhead.offsetWidth
}
/* addEventListeners() */
AudioObject.prototype.addEventListeners = function () {
this.audio.addEventListener("timeupdate", AudioObject.prototype.timeUpdate, false);
this.audio.addEventListener("durationchange", AudioObject.prototype.durationChange, false);
this.timeline.addEventListener("click", AudioObject.prototype.timelineClick, false);
this.playbutton.addEventListener("click", AudioObject.prototype.pressPlay, false);
// Makes playhead draggable
this.playhead.addEventListener('mousedown', AudioObject.prototype.mouseDown, false);
window.addEventListener('mouseup', mouseUp, false);
}
/* populateAudioList */
function populateAudioList() {
var audioElements = document.getElementsByClassName("audio");
for (i = 0; i < audioElements.length; i++) {
audioList.push(
new AudioObject(audioElements[i], 0)
);
audioList[i].bindAudioPlayer(i);
audioList[i].addEventListeners();
}
}
/* populateComponentDictionary()
* {key=element id : value=index of audioList} */
function populateComponentDictionary() {
for (i = 0; i < audioList.length; i++) {
componentDict[audioList[i].audio.id] = i;
componentDict[audioList[i].playbutton.id] = i;
componentDict[audioList[i].timeline.id] = i;
componentDict[audioList[i].playhead.id] = i;
}
}
///////////////////////////////////////////////
// Update Audio Player
///////////////////////////////////////////////
/* durationChange
* set duration for AudioObject */
AudioObject.prototype.durationChange = function () {
var ao = audioList[getAudioListIndex(this.id)];
ao.duration = this.duration;
}
/* pressPlay()
* call play() for correct AudioObject
*/
AudioObject.prototype.pressPlay = function () {
var index = getAudioListIndex(this.id);
audioList[index].play();
}
/* play()
* play or pause selected audio, if there is a song playing pause it
*/
AudioObject.prototype.play = function () {
if (this == playingAudio) {
playingAudio = null;
this.audio.pause();
changeClass(this.playbutton, "playbutton play");
}
// else check if playing audio exists and pause it, then start this
else {
if (playingAudio != null) {
playingAudio.audio.pause();
changeClass(playingAudio.playbutton, "playbutton play");
}
this.audio.play();
playingAudio = this;
changeClass(this.playbutton, "playbutton pause");
}
}
/* timelineClick()
* get timeline's AudioObject
*/
AudioObject.prototype.timelineClick = function (event) {
var ao = audioList[getAudioListIndex(this.id)];
ao.audio.currentTime = ao.audio.duration * clickPercent(event, ao.timeline, ao.timelineWidth);
}
/* mouseDown */
AudioObject.prototype.mouseDown = function (event) {
onplayhead = this.id;
var ao = audioList[getAudioListIndex(this.id)];
window.addEventListener('mousemove', AudioObject.prototype.moveplayhead, true);
ao.audio.removeEventListener('timeupdate', AudioObject.prototype.timeUpdate, false);
}
/* mouseUp EventListener
* getting input from all mouse clicks */
function mouseUp(e) {
if (onplayhead != null) {
var ao = audioList[getAudioListIndex(onplayhead)];
window.removeEventListener('mousemove', AudioObject.prototype.moveplayhead, true);
// change current time
ao.audio.currentTime = ao.audio.duration * clickPercent(e, ao.timeline, ao.timelineWidth);
ao.audio.addEventListener('timeupdate', AudioObject.prototype.timeUpdate, false);
}
onplayhead = null;
}
/* mousemove EventListener
* Moves playhead as user drags */
AudioObject.prototype.moveplayhead = function (e) {
var ao = audioList[getAudioListIndex(onplayhead)];
var newMargLeft = e.pageX - ao.timeline.offsetLeft;
if (newMargLeft >= 0 && newMargLeft <= ao.timelineWidth) {
document.getElementById(onplayhead).style.marginLeft = newMargLeft + "px";
}
if (newMargLeft < 0) {
playhead.style.marginLeft = "0px";
}
if (newMargLeft > ao.timelineWidth) {
playhead.style.marginLeft = ao.timelineWidth + "px";
}
}
/* timeUpdate
* Synchronizes playhead position with current point in audio
* this is the html audio element
*/
AudioObject.prototype.timeUpdate = function () {
// audio element's AudioObject
var ao = audioList[getAudioListIndex(this.id)];
var playPercent = ao.timelineWidth * (ao.audio.currentTime / ao.duration);
ao.playhead.style.marginLeft = playPercent + "px";
// If song is over
if (ao.audio.currentTime == ao.duration) {
changeClass(ao.playbutton, "playbutton play");
ao.audio.currentTime = 0;
ao.audio.pause();
playingAudio = null;
}
}
///////////////////////////////////////////////
// Utility Methods
///////////////////////////////////////////////
/* changeClass
* overwrites element's class names */
function changeClass(element, newClasses) {
element.className = newClasses;
}
/* getAudioListIndex
* Given an element's id, find the index in audioList for the correct AudioObject */
function getAudioListIndex(id) {
return componentDict[id];
}
/* clickPercent()
* returns click as decimal (.77) of the total timelineWidth */
function clickPercent(e, timeline, timelineWidth) {
return (e.pageX - timeline.offsetLeft) / timelineWidth;
}
///////////////////////////////////////////////
// GENERATE HTML FOR AUDIO ELEMENTS AND PLAYERS
///////////////////////////////////////////////
/* createAudioElements
* create audio elements for each file in files */
function createAudioElements() {
for (f in files) {
var audioString = "<audio id=\"audio-" + f + "\" class=\"audio\" preload=\"true\"><source src=\"http://www.alexkatz.me/codepen/music/" + files[f] + "\"></audio>";
$("#audio-players").append(audioString);
}
}
/* createAudioPlayers
* create audio players for each file in files */
function createAudioPlayers() {
for (f in files) {
var playerString = "<div id=\"audioplayer-" + f + "\" class=\"audioplayer\"><button id=\"playbutton-" + f + "\" class=\"play playbutton\"></button><div id=\"timeline-" + f + "\" class=\"timeline\"><div id=\"playhead-" + f + "\" class=\"playhead\"></div></div></div>";
$("#audio-players").append(playerString);
}
}
/* theDOMHasLoaded()
* Execute when DOM is loaded */
function theDOMHasLoaded(e) {
// Generate HTML for audio elements and audio players
createAudioElements();
createAudioPlayers();
// Populate Audio List
populateAudioList();
populateComponentDictionary();
}
答案 0 :(得分:1)
您可以随时使用'gon'宝石。在这里找到:https://github.com/gazay/gon。通过这种方式,您可以将rails变量传递给JS。
<强>的Gemfile 强>
gem 'gon'
<强> application.html.erb 强>
<head>
<%= include gon %>
</head>
<强> your_controller.rb 强>
class YourController < ApplicationController
def index
# Define your variable and now you can pass it in JS
@variable = YourModel.all
gon.new_variable = @variable
end
end
现在,您的JS文件中提供了“gon.new_variable”。
答案 1 :(得分:0)
有很多方法可以做到这一点:
我在视频中解释了我提到的一些解决方案:
http://railscasts.com/episodes/324-passing-data-to-javascript
观看并选择适合您需求的选项,请记住还有其他方法可以提及我没有提及。
答案 2 :(得分:0)
有很多方法可以做到这一点。通常我们使用:
var variable_a = '<%= my_fav_variable %>'
或
var variable_b = '<%= raw %>'