我正在设计一个乐队网站,而 Reverbnation 在页脚中有一个很酷的音乐播放器,它可以让音乐在更改页面时继续播放。
我查看了代码,但看不到任何使用框架的证据。这是我知道实现这样的目标的唯一方法。但是 HTML5 不再支持这种方式,对于 SEO 来说也是废话。
播放器的源代码中有一些 JavaScript,但我不知道足够的 JavaScript 来判断它是否负责。像这样的东西对我正在构建的网站非常有用。
我会尝试谷歌搜索,但我不知道我会用什么关键字来寻找关于这个主题的方法。
由于代码很长,如果有人愿意看一下,我将其剪切并粘贴在这里。
这是我的代码:
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
jQuery(function($) {
if (!$("body").hasClass("new_sofia_navigation")) {
$("body").addClass("new_sofia_navigation")
}
var $search_el = $('#sofia_header_search input[type=text]')
$search_el.quickSearch({
search_path: 'http://search.reverbnation.com/search/quick.json',
use_jsonp: true
});
$("#sofia_header_search").submit(function(e) {
var $form = $(this);
e.preventDefault();
Reverb.Navigate.go_to_page_url($form.attr('action') + '?' + $form.serialize());
});
var repositionSearchContainer = function() {
$("#global_menu_search").find(".expanded_content").alignTo($("#global_menu_search"), "br-tr")
}
$("#menu_notifications, #global_menu_search, #menu_user_actions").bind("expand", function() {
var $menu = $(this).find(".expanded_content"),
$align_target = $("#global_menu_search"),
align_offset = {
top: 0,
left: 0
}
if ($menu.hasAttr("data-align-target")) {
$align_target = $("#" + $menu.attr("data-align-target"))
}
if ($menu.hasAttr("data-align-offset")) {
var offsets = $menu.attr("data-align-offset").split(":")
align_offset.left = parseInt(offsets[0]) || 0
align_offset.top = parseInt(offsets[1]) || 0
}
$(this).find(".expanded_content").alignTo($align_target, "br-tr", align_offset)
})
$search_el.bind("quicksearch_disable", repositionSearchContainer).bind("quicksearch_enable", repositionSearchContainer)
$("#menu_notifications:not(.no_notices)").bind("expand", function() {
$.get("/page_object/reset_new_notice_count/artist_332065")
$(this).addClass("no_notices")
})
$(window).trigger('user:login', {
"type": "Artist",
"feat_ownapp_apple": "0",
"artist_bes": 5722,
"feat_rpk": "P",
"feat_fr_rap": "P",
"feat_ownapp_push": "0",
"feat_mega": "0",
"feat_distro": "0",
"feat_ownapp": "0",
"feat_distro_p": "0",
"feat_distro_e": "0",
"is_admin": false,
"feat_widg": "0",
"feat_mega_max": "0",
"artist_country": "UK",
"genre": "Metal",
"feat_fr": "P",
"feat_bundle": "0",
"feat_ownapp_droid": "0",
"artist_bought": true,
"control_room": "sofia",
"name": "Soul Sanctuary",
"id": 332065,
"feat_sb": "0",
"feat_fr_360": "0",
"current_layout": "v3"
});
});
</script>
</div>
</div>
<script type="text/javascript">
jQuery(function($) {
Reverb.Notification.init('#standard_flash_message');
});
</script>
</div>
<div id="docked_footer">
<style type="text/css">
#sm2-container {
position: absolute;
width: 1px;
height: 1px;
top: 0;
left: 0;
overflow: hidden;
}
</style>
<div id="loading_gif">
<img alt="16x16_black" src="http://gp1.wac.edgecastcdn.net/802892/production_static/images/spinners/16x16_black.gif?1357641892" />
<span>Loading...</span>
</div>
<textarea id="template" style="display:none">
<div class="player_queue_item" >
<a href="javascript:trackEvent('V3 Footer Data','Click','Toggle Item');" class="toggle"></a>
<a href="javascript:trackEvent('V3 Footer Data','Click','Remove Item');" class="remove" data-command="remove_song"></a>
<a href="javascript:trackEvent('V3 Footer Data','Click','Play Item ');" class="play_state" data-command="play" ></a>
<div class="content_wrap">
<div class="content">
<a href='{link}'><img src='{image}' /></a>
<h3 title="{title}">{title_display}</h3>
<a href='{link}'><h4 title="{artist}">{artist_display}</h4></a>
</div>
</div>
<div class="actions" style="text-align:center">
<a href="javascript:trackEvent('V3 Footer Data','Click','Download Button');" class="first" data-command="download">Download</a>
<a href="javascript:trackEvent('V3 Footer Data','Click','Share Button');" data-command="share">Share</a>
<a href="javascript:trackEvent('V3 Footer Data','Click','Favorite Button');" data-command="favorite">Favorite</a>
<a href="javascript:trackEvent('V3 Footer Data','Click','Lyrics Button');" data-command="lyrics">Lyrics</a>
<a href="javascript:trackEvent('V3 Footer Data','Click','Become Fan Button');" data-command="fan" class="last">Be a fan</a>
</div>
</div>
</textarea>
<div id="sm2-container"></div>
<div class="footer_content clearfix">
<div class="footer_music_player" id="music_player">
<div class="player_queue collapsed" id="player_queue">
<div class="player_queue_content">
<div class="player_queue_header">
<a href="javascript:trackEvent('V3 Footer Data','Click','Collapse Queue');" data-command="toggle" class="collapse"></a>
</div>
<div class="player_queue_items card" data-card="queue_items">
<div class="card_actions clearfix">
<span data-role="title"></span>
<a href="javascript:trackEvent('V3 Footer Data','Click','Clear Queue');" data-command="clear_playlist" class="playlist_action">Clear</a>
<a href="javascript:trackEvent('V3 Footer Data','Click','Share All');" data-command="share_playlist" class="playlist_action">Share All</a>
<a href="javascript:trackEvent('V3 Footer Data','Click','Show Channels');" data-command="show_discover" class="playlist_action">Channels</a>
</div>
<div class="player_queue_list"></div>
</div>
<div class=" card" data-card="queue_discover">
<div class="card_actions">
<a href="javascript:trackEvent('V3 Footer Data','Click','Show Queue');" data-command="show_playlist" class="discovery_action">Show Queue</a>
</div>
<div class="player_queue_discover">
<h1>ReverbNation Channels</h1>
<h3>Select a Music Channel to Get Started</h3>
<a href="javascript:trackEvent('V3 Footer Data','Click','Global Chart Toppers');" data-command="discover_global">Global Chart Toppers</a>
<a href="javascript:trackEvent('V3 Footer Data','Click','Local Chart Toppers');" data-command="discover_local">Local Chart Toppers</a>
<a href="javascript:trackEvent('V3 Footer Data','Click','Trending Artists');" data-command="discover_trending">Trending Artists</a>
<a href="javascript:trackEvent('V3 Footer Data','Click','Alt/Rock/Indie');" data-command="discover_alt_rock_indie">Alt/Rock/Indie</a>
<a href="javascript:trackEvent('V3 Footer Data','Click','Electro/Pop/Dance');" data-command="discover_electro_pop_dance">Electro/Pop/Dance</a>
<a href="javascript:trackEvent('V3 Footer Data','Click','HipHop/Rap/RB');" data-command="discover_hiphop_rap_rbsoul">HipHop/Rap/R&B</a>
<a href="javascript:trackEvent('V3 Footer Data','Click','Featured Artists');" data-command="discover_featured">Featured Artists</a>
<a href="javascript:trackEvent('V3 Footer Data','Click','My Favorites');" data-command="discover_my_favorites">My Favorites</a>
<a href="javascript:trackEvent('V3 Footer Data','Click','Custom Channel');" data-command="discover_custom_channel">Custom Channel</a>
</div>
</div>
<div class="player_queue_custom_channel card" data-card="queue_custom_channel">
<div class="card_actions">
<a href="javascript:trackEvent('V3 Footer Data','Click','Show Queue');" data-command="show_playlist" class="discovery_action">Show Queue</a>
</div>
<form action="/c/audio_player/music_now" id="custom_channel_form" method="post" onsubmit="new Ajax.Request('/c/audio_player/music_now', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;"> <label for="reverb_radio_genres_player_select">Select Genres:</label>
<input id="reverb_radio_channel" name="reverb_radio[channel]" type="hidden" value="reverb_picks" />
<select data-placeholder="Click to select genre(s)" id="reverb_radio_genres_player_select" multiple="multiple" name="reverb_radio[genres][]">
<option value="alternative">Alternative</option>
<option value="ambient">Ambient</option>
<option value="americana">Americana</option>
<option value="bluegrass">Bluegrass</option>
<option value="blues">Blues</option>
<option value="bollywoodtollywood">Bollywood/Tollywood</option>
<option value="celtic">Celtic</option>
<option value="childrens">Childrens</option>
<option value="christianrock">Christian Rock</option>
<option value="christiangospel">Christian/Gospel</option>
<option value="classical">Classical</option>
<option value="comedy">Comedy</option>
<option value="country">Country</option>
<option value="dj">DJ</option>
<option value="dance">Dance</option>
<option value="dubstep">Dubstep</option>
<option value="electronicdancemusic">Electronic Dance Music</option>
<option value="electronica">Electronica</option>
<option value="experimental">Experimental</option>
<option value="folk">Folk</option>
<option value="funk">Funk</option>
<option value="hiphop">Hip Hop</option>
<option value="holiday">Holiday</option>
<option value="house">House</option>
<option value="indie">Indie</option>
<option value="instrumental">Instrumental</option>
<option value="jam">Jam</option>
<option value="jazz">Jazz</option>
<option value="latin">Latin</option>
<option value="metal">Metal</option>
<option value="other">Other</option>
<option value="pop">Pop</option>
<option value="punk">Punk</option>
<option value="rbsoul">R&B/Soul</option>
<option value="rap">Rap</option>
<option value="reggae">Reggae</option>
<option value="rock">Rock</option>
<option value="rockabilly">Rockabilly</option>
<option value="singersongwriter">Singer Songwriter</option>
<option value="ska">Ska</option>
<option value="spiritual">Spiritual</option>
<option value="spokenword">Spoken Word</option>
<option value="world">World</option>
</select>
<input class="standard_button style_primary size_small" name="commit" type="submit" value="Ok" />
<a href="javascript:;" data-command="back">Cancel</a>
</form>
</div>
</div>
</div>
<div class="player_about" id="player_about">
<a href="javascript:trackEvent('V3 Footer Data','Click','Toggle Playlist');" class="toggle_playlist" data-command="toggle_playlist" data-qtip="Toggle Playlist"></a>
<div class="cards">
<div class="song_info card" data-card="song_info">
<div class="song_actions clearfix">
<a href="javascript:trackEvent('V3 Footer Data','Click','Share');" class="share" data-command="share" data-qtip="Share"></a>
<a href="javascript:trackEvent('V3 Footer Data','Click','Download');" data-command="download" data-qtip="Download" class="download"></a>
<a href="javascript:trackEvent('V3 Footer Data','Click','Favorite');" class="thumb" data-command="recommend" data-qtip="Favorite"></a>
</div>
<a href="#" data-role="link"><img data-role="image" src="data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" /></a>
<h3 data-role="title"></h3>
<a href="#" data-role="link">
<h4 data-role="artist"></h4>
</a>
<div class="progress_slider_wrap">
<div class="player_slider progress_slider">
<div class="progress">
<div class="progress_thumb small"></div>
</div>
<div class="time_progress extra_ui" style="word-break: normal !important;">12:123</div>
</div>
</div>
</div>
<div class="discover_music card" data-card="discover_music">
<p>Not listening to anything?</p>
<p>Try one of the <a href="javascript:trackEvent('V3 Footer Data','Click','Discover');" data-command="discover">ReverbNation Channels</a></p>
</div>
<div class="feedback card active" data-card="feedback">
</div>
</div>
</div>
<div class="player_song_control" id="player_control">
<div class="buttons">
<a href="javascript:trackEvent('V3 Footer Data','Click','Prev');" class="btn_prev" data-command="prev"></a>
<a href="javascript:trackEvent('V3 Footer Data','Click','Play');" class="btn_play" data-command="play"></a>
<a href="javascript:trackEvent('V3 Footer Data','Click','Pause');" class="btn_pause" data-command="pause" style="display:none;"></a>
<a href="javascript:trackEvent('V3 Footer Data','Click','Next');" class="btn_next" data-command="next"></a>
</div>
<div class="player_slider volume_slider">
<a href="javascript:trackEvent('V3 Footer Data','Click','Mute');" data-command="mute" class="volume_btn extra_ui"></a>
<div class="progress">
<div class="progress_thumb big"></div>
</div>
</div>
</div>
</div>
<div class="footer_content_right" id="docked_footer_content_right">
<div id="rabbit_hole_controls" class="footer_content_right_profile rabbit_hole_enabled">
<center>
<a href="#" id="rabbit-hole-wat">Wat</a>
<a href="#" class="rabbit-hole-button" id="engage_rabbit_hole">Rabbit Hole</a>
<a href="#" class="rabbit-hole-button" id="go_deeper">Go deeper</a> <br/>
<a href="#" id="what_is_rabbit_hole">What's This?</a>
</center>
</div>
<div id="rabbit_hole_tooltip" style="display: none"></div>
<script language="Javascript">
Reverb.playerReady(function() {
var $tooltip = $j('#rabbit_hole_tooltip'),
timeout_id;
$tooltip.bind('display-tooltip', function(e, message) {
$tooltip.html(message);
$tooltip.trigger('tooltip-show');
clearTimeout(timeout_id);
timeout_id = setTimeout(function() {
$tooltip.trigger('tooltip-hide');
}, 10000)
});
$tooltip.bind('tooltip-show', function(e) {
$tooltip.stop(true, true, true).
animate({
bottom: "-=10",
opacity: 'show'
});
});
$tooltip.bind('tooltip-hide', function(e) {
$tooltip.stop(true, true, true).
animate({
bottom: "+=10",
opacity: 'hide'
});
});
$tooltip.click(function(e) {
var info = MusicPlayer.getInstance().getCurrentSong()
if (info && info.link) {
Reverb.Navigate.go_to_page_url(info.link)
}
$tooltip.trigger('tooltip-hide');
})
$j('#rabbit-hole-wat').hover(function(e) {
if ($tooltip.html() != "") {
$tooltip.trigger('tooltip-show');
}
}, function(e) {
$tooltip.trigger('tooltip-hide');
});
function recommendationTextFor(hash, current_song) {
var reason = "Playing <em>" + current_song.artist + "</em> because";
switch (hash.type) {
case 'direct':
reason += " they were recommended by <em>" + $j.escapeHTML(hash.name) + "</em>";
break;
case 'show_bill':
reason += " they played a show with <em>" + $j.escapeHTML(hash.name) + "</em>" +
" on " + $j.escapeHTML(hash.latest_show_date) + ' in ' + $j.escapeHTML(hash.latest_show_location);
break;
case 'featured_artist':
reason += " they're a featured artist";
break;
default:
reason += " it's awesome";
break;
}
if (hash.reason != null) {
return $j.escapeHTML(hash.reason) + ". " + reason;
} else {
return reason;
}
}
MusicPlayer.getInstance().bind('playlist_updated', function(e, player) {
if ($j('#rabbit_hole_controls').hasClass('rabbit_hole_enabled')) {
$j('#music_player .player_queue_item:last').addClass('in_rabbit_hole');
}
});
MusicPlayer.getInstance().bind('song_play', function(e, player) {
var current_song = player && player.getCurrentSong();
if (current_song == null) {
// Hopefully means we got the thing cleared
$j('#rabbit_hole_controls').removeClass('rabbit_hole_enabled');
$j('#rabbit_hole_tooltip').html('');
Reverb.RabbitHoleCache = {};
return;
}
if (Reverb.RabbitHoleCache[parseInt(current_song.id, 10)] != null) {
$tooltip.trigger('display-tooltip', recommendationTextFor(Reverb.RabbitHoleCache[parseInt(current_song.id, 10)], current_song))
}
});
})
$j(function($) {
var goToCurrentArtist = function() {
// wee need a little delay to be sure the playlist is actually loaded before making any redirect
// not the ideal solution, but it doesn't require a beautiful reaper
window.setTimeout(function() {
var info = MusicPlayer.getInstance().getCurrentSong()
if (info && info.link) {
Reverb.Navigate.go_to_page_url(info.link)
}
})
}
$('#engage_rabbit_hole').click(function(e) {
var current_po;
if ((CURRENT_PAGE_OBJECT || '').match(/artist_/)) {
current_po = CURRENT_PAGE_OBJECT;
} else {
current_po = ''
}
trackEvent('V3 Footer Data', 'Click', 'Rabbit Hole');
$.ajax('/c/audio_player/rabbit_hole_now/' + current_po, {
type: 'get',
beforeSend: function() {
$j('#rabbit_hole_tooltip').trigger('display-tooltip', 'Loading…');
},
complete: goToCurrentArtist
});
return false;
});
$('#go_deeper').click(function(e) {
e.preventDefault();
var player = MusicPlayer.getInstance();
trackEvent('V3 Footer Data', 'Click', 'Go Deeper');
if (player.playingIndex < player.playlist.length - 1) {
player.sendCommand('next');
goToCurrentArtist()
}
});
$('#what_is_rabbit_hole').click(function(e) {
e.preventDefault();
modal_open('/audio_player/modal/rabbit_hole_modal')
trackEvent('V3 Footer Data', 'Click', 'What Is Rabbit Hole');
});
Reverb.RabbitHoleCache = Reverb.RabbitHoleCache || {};
});
</script>
</div>
</div>
<div id="footer_marketing_wrap">
<div id="footer_marketing" class="standard_footer_marketing standard_typography"></div>
</div>
<script type="text/javascript">
jQuery(function($) {
$("#player_about").qtip()
var $form = $("#custom_channel_form")
$("#music_player select").chosen().change(function() {
window.setTimeout(function() {
$form.center($form.parent())
}, 0)
})
$form.center($form.parent())
Reverb.playerReady(function() {
var load_timeout;
/* - No longer tied to profile page, will use server-side to check session cookie -
var songs_container = $("#profile_songs_container"), current_song_id, load_timeout
songs_container.delegate(".standard_play_button:not(.playing)","click", function(){
current_song_id = $(this).attr("data-song-id")
window.clearTimeout(load_timeout)
})
*/
MusicPlayer.getInstance().bind("playlist_updated", function fn(ev, player) {
var song = player.getCurrentSong();
/* - No longer tied to profile page, will use server-side to check session cookie -
if(songs_container.is(":not(:visible)")){
// detach the event listener, as the user left the original profile page
player.unbind("playlist_updated", fn)
}else if(song){
// if the current sound might not be the one the user is listening to.
// In order to be sure we're tracking the correct data, we have to check that the current song in the playlist is actually the one the user clicked on
if(current_song_id+"" == song.id+""){
current_song_id = false;
*/
window.clearTimeout(load_timeout);
var check_loaded = function() {
if (song && player.currentSound && player.currentSound.getLoaded()) { // the load percentage is > 0
//alert('before incrementing lp_song_plays');
$.get("/artist/increment_lp_song_plays", {
song_id: song.id
});
} else {
load_timeout = window.setTimeout(check_loaded, 100);
}
}
check_loaded();
/* }
}*/
});
});
})
</script>
</div>
</div>