我创造了动态的增强卡,它是一个唱机。我是Jquery和CSS / scss的初学者。
我将根据数据库中的数据生成多个boostrap卡。为简单起见,我在下面的示例中仅编写了2张增强卡。 我有一个音乐容器类,它有1)控制播放和2)每张卡的乙烯基(唱机)。 我的问题是如何在任何时候只允许1个控制播放,比如说如果1个控制播放已经播放,如果我点击另一个控制播放,之前的控制播放停止和乙烯基将翻转回来专辑封面。换句话说,只允许1个唱机在任何给定时间播放vinly动画。 ToggleClass不起作用,也不是removeClass。有时,即使我点击一次(我使用代理来避免这种情况,但它似乎不起作用),也会为两个控制播放项调用click事件。
错误:当我运行小提琴,并且第一次点击control-play1时,两个音乐播放器容器的乙烯基显示而不是仅显示第一个,并且当再次单击control-play1时它们会关闭。如果你点击第二个控制播放,它只显示第二个vinly。这是一种不寻常的行为。
JS
function MusicPlayer(mp, id) {
this.mpc = mp;
this.initEvents(id);
}
MusicPlayer.prototype = {
initEvents: function(id) {
var obj = this;
obj.mpc.on('click', function(event) {
var others = $("div.music-player-container").not($(this));
$.each(others, function(index, value) {
alert("other non-clicked players :" + $(value).attr("id") + " ; is it playing?" + $(value).is('.is-playing .vinyl'));
if ($(value).is('.is-playing .vinyl')) {
// $(value).removeClass('is-playing');
//$(value).toggleClass('is-playing', false);
$(value).removeClass('is-playing');
$(value).addClass('is-not-playing');
$(value).toggleClass('is-not-playing', true);
}
});
alert("Current clicked music-Player-Container being toggled :" + $(this).attr("id"));
$(this).toggleClass('is-playing');
event.stopPropagation();
});
}
}
$(function() {
var $div = $('#content');
$(".control-play").bind('click', $.proxy(function(event) {
//Get Control-Play clicked
var cplay_clicked = $(event.target).attr('id');
alert("control-player-clicked:" + cplay_clicked);
//Get Music-Player-Container that has clicked Control-Play inside it
var $musiPlayerContainer = $div.find('#' + event.target.dataset.id + 'mpc');
var mpc = new MusicPlayer($musiPlayerContainer, event.target.dataset.id);
$('div.music-player-container').removeClass('is-playing');
}, this));
});
CSS
/* CSS used here will be applied after bootstrap.css */
/* CSS used here will be applied after bootstrap.css */
/*@import '../../bourbon/_bourbon.scss';*/
/*@import "../../bourbon-bitters/_bitters.scss";*/
@import url(https://fonts.googleapis.com/css?family=Raleway:400,300,500);
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
box-sizing: border-box;
}
*:before,
*:after {
box-sizing: border-box;
}
/*@import "compass/css3";*/
/*@import "../../bourbon-bitters/mixins/_base.scss";*/
/*@mixin filter($function: none) {
// @warn "This old mixin is deprecated!";
@include _bourbon-deprecate-for-prefixing("filter");
// <filter-function> [<filter-function]* | none
@include prefixer(filter, $function, webkit spec);
}*/
body {
background-color: #fff;
color: #515044;
font-family: 'Raleway', sans-serif;
}
.music-player-container {
-webkit-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
-o-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
display: inline-block;
height: 220px;
position: relative;
max-width: 130px;
margin-left: 70px;
margin-top: 170px;
}
.music-player {
background-color: #fff;
height: 120px;
padding: 40px 200px 40px 40px;
position: absolute;
text-align: right;
width: 125px;
z-index: 3;
}
.player-content-container {
-webkit-transform: translateY(-50%);
-moz-transform: translateY(-50%);
-ms-transform: translateY(-50%);
-o-transform: translateY(-50%);
transform: translateY(-50%);
top: 50%;
position: relative;
}
.artist-name {
font-size: 28px;
font-weight: normal;
margin: 0 0 0.75em 0;
}
.album-title {
font-weight: 200;
font-size: 24px;
margin: 0 0 1.75em 0;
}
.song-title {
font-size: 18px;
font-weight: 200;
margin: 0 0 1.5em 0;
}
.album {
box-shadow: 3px 3px 15px rgba(0, 0, 0, 0.65);
height: 120px;
/*margin-left: 250px;
margin-top: 27px;*/
position: relative;
width: 125px;
z-index: 10;
}
.album-art {
background: #fff center no-repeat;
height: 120px;
position: relative;
width: 125px;
z-index: 10;
}
.card-img {
background: #fff center no-repeat;
height: 120px;
position: relative;
width: 125px;
z-index: 10;
}
.card-img > .card-img-overlay {
background: #e0eaec center no-repeat;
z-index: 10;
}
.vinyl {
-webkit-animation: spin 2s linear infinite;
-moz-animation: spin 2s linear infinite;
animation: spin 2s linear infinite;
-webkit-transition: all 500ms;
-moz-transition: all 500ms;
transition: all 500ms;
background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/83141/vinyl.png"), url("https://localhost:49544/Albums/The_Beatles/Greatest_Hits/Album_Cover/IMG_Greatest_Hits.jpg");
background-position: center, center;
background-size: cover, 40% auto;
background-repeat: no-repeat;
border-radius: 100%;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.8);
height: 110px;
left: 10px;
position: absolute;
top: 10px;
width: 105px;
z-index: 5;
will-change: transform, left;
}
.is-playing .vinyl {
left: 52%;
}
/*
.is-not-playing .vinyl {}
*/
.is-not-playing .vinyl {
left: 1%;
animation: none;
transition: none;
}
.i-2x {
text-align: center;
font-size: 2em;
}
[class^="control-"] {
border-radius: 100%;
display: inline-block;
height: 44px;
margin: 0 3px;
width: 44px;
}
[class^="control-"]:hover {
cursor: pointer;
}
.card-img-overlay > .control-play {
background: url("https://png.icons8.com/circled-play/androidL/64");
height: 64px;
width: 64px;
margin-left: 20px;
background-repeat: no-repeat;
}
.control-forwards {
background: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/83141/forwards.ico") center/cover no-repeat;
}
.control-back {
background: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/83141/backwards.ico") center/cover no-repeat;
}
@-webkit-keyframes spin {
0% {
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-ms-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@-moz-keyframes spin {
0% {
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-ms-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@-o-keyframes spin {
0% {
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-ms-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes spin {
0% {
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-ms-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
HTML
<div class="container-fluid">
<div id="content">
<div class="music-player-container" id="1mpc">
<div class="card card-inverse" id="1card">
<div class="card-header" id="1cardHeader">
<div class="top">
<i id="1fav" class="favtoggle fa not-liked"></i>
<i id="1pl" class="fa fa-plus-circle"></i>
</div>
</div>
<div id="1album" class="album">
<div class="album-art">
<img class="card-img-top" src="https://images-na.ssl-images-amazon.com/images/I/81kZdGYO%2ByL._SL1500_.jpg" alt="Card image cap">
<div class="card-img-overlay h-100 d-flex flex-column justify-content-center text-center">
<span class="control-play" id="1control-play" data-id="1" data-ctype="audio/mp3" data-src="http://localhost:49544/Albums/The_Beatles/Greatest_Hits/hey jude.mp3" title="Play"></span>
</div>
</div>
<div class="vinyl" id="1vinyl"></div>
</div>
<div class="card-footer">
<span class="text-ellipsis text-left">hey jude</span>
<small class=" text-left text-ellipsis text-xs text-muted">Abbey Road</small>
</div>
</div>
<!-2nd one->
<div class="music-player-container" id="2mpc">
<div class="card card-inverse" id="2card">
<div class="card-header" id="2cardHeader">
<div class="top">
<i id="2fav" class="favtoggle fa not-liked"></i>
<i id="2pl" class="fa fa-plus-circle"></i>
</div>
</div>
<div id="2album" class="album">
<div class="album-art">
<img class="card-img-top" src="https://images-na.ssl-images-amazon.com/images/I/81kZdGYO%2ByL._SL1500_.jpg" alt="Card image cap">
<div class="card-img-overlay h-100 d-flex flex-column justify-content-center text-center">
<span class="control-play" name="CP2" id="2control-play" data-id="2" data-ctype="audio/mp3" data-src="http://localhost:49544/Albums/The_Beatles/Greatest_Hits/hey jude.mp3" title="Play"></span>
</div>
</div>
<div class="vinyl" id="2vinyl"></div>
</div>
<div class="card-footer">
<span class="text-ellipsis text-left">hey jude</span>
<small class=" text-left text-ellipsis text-xs text-muted">Abbey Road</small>
</div>
</div>
<div style="clear:both"></div>
</div>
</div>
如果我没有按照建议创建MusicPlayerContainer的对象或使用bind(),那么它就不起作用了。
$(function() {
var $div = $('#content');
$(".control-play").on('click', function (event) {
//Get Control-Play clicked
var cplay_clicked = $(event.target).attr('id');
alert("control-player-clicked:" + cplay_clicked);
//Get Music-Player-Container that has clicked Control-Play inside it
var $musiPlayerContainer = $div.find('#' + event.target.dataset.id + 'mpc');
var others = $("div.music-player-container").not($(this));
$.each(others, function(index, value) {
alert("other non-clicked players :" + $(value).attr("id") + " ; is it playing?" + $(value).is('.is-playing .vinyl'));
if ($(value).is('.is-playing .vinyl')) {
// $(value).removeClass('is-playing');
//$(value).toggleClass('is-playing', false);
$(value).removeClass('is-playing');
$(value).addClass('is-not-playing');
$(value).toggleClass('is-not-playing', true);
}
});
alert("Current clicked music-Player-Container being toggled :" + $(this).attr("id"));
$(this).toggleClass('is-playing');
event.stopPropagation();
$('div.music-player-container').removeClass('is-playing');
},
);
});
答案 0 :(得分:0)
正如我在评论中提到的,你的小提琴中的第24到28行读到了:
</div>
<!-2nd one->
<div class="music-player-container" id="2mpc">
这无法使用'music-player-container'类关闭之前的<div>
。您需要添加另一个</div>
,如下所示:
</div>
</div>
<!-2nd one->
<div class="music-player-container" id="2mpc">
您的代码末尾也遗漏了</div>
。可在此处查看更正:https://jsfiddle.net/Twisty/ysLmyzb7/1/
关于我评论的第二部分,您可能需要考虑使用jQuery UI Widget Factory($.widget()
)。
使用与所有jQuery UI小部件相同的抽象创建有状态的jQuery插件。
这方面的一个例子:
$(function() {
$.widget("custom.musicPlayer", {
options: {
autoPlay: false,
singlePlayer: true
},
playing: false,
id: null,
playButton: null,
source: null,
_create: function() {
this.id = this.element.attr("id");
console.log("New MPC: ", this.id);
this.element.addClass("ui-mp");
this.playButton = this.element.find(".control-play");
this.source = this.element.find(".control-play").data("src");
this._on(this.playButton, {
click: "togglePlay"
});
if (this.options.autoPlay) {
console.log(this.id + ": AutoPlay Enabled.");
this.play();
}
console.log(this);
},
togglePlay: function() {
if (this.playing) {
this.stop();
} else {
this.play()
}
},
play: function() {
console.log(this.id + ": event, play");
if (this.options.singlePlayer) {
// Stop all other players
$(".ui-mp").not(this.element).musicPlayer("stop");
}
this.playing = true;
$(this.element).addClass("is-playing");
},
stop: function() {
console.log(this.id + ": event, stop");
this.playing = false;
$(this.element).removeClass("is-playing");
}
});
$(".music-player-container").musicPlayer();
});
/* CSS used here will be applied after bootstrap.css */
/* CSS used here will be applied after bootstrap.css */
/*@import '../../bourbon/_bourbon.scss';*/
/*@import "../../bourbon-bitters/_bitters.scss";*/
@import url(https://fonts.googleapis.com/css?family=Raleway:400,300,500);
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
box-sizing: border-box;
}
*:before,
*:after {
box-sizing: border-box;
}
/*@import "compass/css3";*/
/*@import "../../bourbon-bitters/mixins/_base.scss";*/
/*@mixin filter($function: none) {
// @warn "This old mixin is deprecated!";
@include _bourbon-deprecate-for-prefixing("filter");
// <filter-function> [<filter-function]* | none
@include prefixer(filter, $function, webkit spec);
}*/
body {
background-color: #fff;
color: #515044;
font-family: 'Raleway', sans-serif;
}
.music-player-container {
-webkit-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
-o-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
display: inline-block;
height: 220px;
position: relative;
max-width: 130px;
margin-left: 70px;
margin-top: 170px;
}
.music-player {
background-color: #fff;
height: 120px;
padding: 40px 200px 40px 40px;
position: absolute;
text-align: right;
width: 125px;
z-index: 3;
}
.player-content-container {
-webkit-transform: translateY(-50%);
-moz-transform: translateY(-50%);
-ms-transform: translateY(-50%);
-o-transform: translateY(-50%);
transform: translateY(-50%);
top: 50%;
position: relative;
}
.artist-name {
font-size: 28px;
font-weight: normal;
margin: 0 0 0.75em 0;
}
.album-title {
font-weight: 200;
font-size: 24px;
margin: 0 0 1.75em 0;
}
.song-title {
font-size: 18px;
font-weight: 200;
margin: 0 0 1.5em 0;
}
.album {
box-shadow: 3px 3px 15px rgba(0, 0, 0, 0.65);
height: 120px;
/*margin-left: 250px;
margin-top: 27px;*/
position: relative;
width: 125px;
z-index: 10;
}
.album-art {
background: #fff center no-repeat;
height: 120px;
position: relative;
width: 125px;
z-index: 10;
}
.card-img {
background: #fff center no-repeat;
height: 120px;
position: relative;
width: 125px;
z-index: 10;
}
.card-img>.card-img-overlay {
background: #e0eaec center no-repeat;
z-index: 10;
}
.vinyl {
-webkit-animation: spin 2s linear infinite;
-moz-animation: spin 2s linear infinite;
animation: spin 2s linear infinite;
-webkit-transition: all 500ms;
-moz-transition: all 500ms;
transition: all 500ms;
background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/83141/vinyl.png"), url("https://localhost:49544/Albums/The_Beatles/Greatest_Hits/Album_Cover/IMG_Greatest_Hits.jpg");
background-position: center, center;
background-size: cover, 40% auto;
background-repeat: no-repeat;
border-radius: 100%;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.8);
height: 110px;
left: 10px;
position: absolute;
top: 10px;
width: 105px;
z-index: 5;
will-change: transform, left;
}
.is-playing .vinyl {
left: 52%;
}
/*
.is-not-playing .vinyl {}
*/
.is-not-playing .vinyl {
left: 1%;
animation: none;
transition: none;
}
.i-2x {
text-align: center;
font-size: 2em;
}
[class^="control-"] {
border-radius: 100%;
display: inline-block;
height: 44px;
margin: 0 3px;
width: 44px;
}
[class^="control-"]:hover {
cursor: pointer;
}
.card-img-overlay>.control-play {
background: url("https://png.icons8.com/circled-play/androidL/64");
height: 64px;
width: 64px;
margin-left: 20px;
background-repeat: no-repeat;
}
.control-forwards {
background: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/83141/forwards.ico") center/cover no-repeat;
}
.control-back {
background: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/83141/backwards.ico") center/cover no-repeat;
}
@-webkit-keyframes spin {
0% {
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-ms-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@-moz-keyframes spin {
0% {
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-ms-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@-o-keyframes spin {
0% {
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-ms-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes spin {
0% {
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-ms-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js"></script>
<div class="container-fluid">
<div id="content">
<div class="music-player-container" id="mpc-1">
<div class="card card-inverse" id="card-1">
<div class="card-header" id="cardHeader-1">
<div class="top">
<i id="1fav" class="favtoggle fa not-liked"></i>
<i id="1pl" class="fa fa-plus-circle"></i>
</div>
</div>
<div id="album-1" class="album">
<div class="album-art">
<img class="card-img-top" src="https://images-na.ssl-images-amazon.com/images/I/81kZdGYO%2ByL._SL1500_.jpg" alt="Card image cap">
<div class="card-img-overlay h-100 d-flex flex-column justify-content-center text-center">
<span class="control-play" id="control-play-1" data-ctype="audio/mp3" data-src="http://localhost:49544/Albums/The_Beatles/Greatest_Hits/hey jude.mp3" title="Play"></span>
</div>
</div>
<div class="vinyl" id="vinyl-1"></div>
</div>
<div class="card-footer">
<span class="text-ellipsis text-left">hey jude</span>
<small class="text-left text-ellipsis text-xs text-muted">Abbey Road</small>
</div>
</div>
</div>
<!-2nd one->
<div class="music-player-container" id="mpc-2">
<div class="card card-inverse" id="card-2">
<div class="card-header" id="cardHeader-2">
<div class="top">
<i id="2fav" class="favtoggle fa not-liked"></i>
<i id="2pl" class="fa fa-plus-circle"></i>
</div>
</div>
<div id="album-2" class="album">
<div class="album-art">
<img class="card-img-top" src="https://images-na.ssl-images-amazon.com/images/I/81kZdGYO%2ByL._SL1500_.jpg" alt="Card image cap">
<div class="card-img-overlay h-100 d-flex flex-column justify-content-center text-center">
<span class="control-play" name="CP2" id="control-play-2" data-ctype="audio/mp3" data-src="http://localhost:49544/Albums/The_Beatles/Greatest_Hits/hey jude.mp3" title="Play"></span>
</div>
</div>
<div class="vinyl" id="vinyl-2"></div>
</div>
<div class="card-footer">
<span class="text-ellipsis text-left">hey jude</span>
<small class="text-left text-ellipsis text-xs text-muted">Abbey Road</small>
</div>
</div>
<div style="clear:both"></div>
</div>
<!--3rd one-->
<div class="music-player-container" id="mpc-3">
<div class="card card-inverse" id="card-3">
<div class="card-header" id="cardHeader-3">
<div class="top">
<i id="2fav" class="favtoggle fa not-liked"></i>
<i id="2pl" class="fa fa-plus-circle"></i>
</div>
</div>
<div id="album-3" class="album">
<div class="album-art">
<img class="card-img-top" src="https://images-na.ssl-images-amazon.com/images/I/81kZdGYO%2ByL._SL1500_.jpg" alt="Card image cap">
<div class="card-img-overlay h-100 d-flex flex-column justify-content-center text-center">
<span class="control-play" name="CP2" id="control-play-3" data-ctype="audio/mp3" data-src="http://localhost:49544/Albums/The_Beatles/Greatest_Hits/hey jude.mp3" title="Play"></span>
</div>
</div>
<div class="vinyl" id="vinyl-3"></div>
</div>
<div class="card-footer">
<span class="text-ellipsis text-left">hey jude</span>
<small class="text-left text-ellipsis text-xs text-muted">Abbey Road</small>
</div>
</div>
<div style="clear:both"></div>
</div>
</div>
</div>
外部小提琴:https://jsfiddle.net/Twisty/ynmepyec/
它可能需要更多工作,但它可以更轻松地处理整体并为您提供更多选项和控制。