问题描述
我已经从mousedown
和mousemove
为<audio>
元素创建了一个滑块/搜索器。
我的问题是,只要用户在按住鼠标键的同时离开元素,就不会注册mousemove
。
这是我的代码:
/** Variables **/
isPlaying = false;
isBuffering = false;
isScrubbing = false;
isScrubberHolding = false;
tempProgress = 0;
time = playerE.currentTime;
dur = playerE.duration;
/** Binds and Properties **/
player.bind("timeupdate", timeUpdate);
scrubber.bind("mousemove", scrubberGrab);
scrubber.bind("mousedown", scrubberClick);
/** Progress and Buffer **/
function progressWidth(progress) {
var calcProgress = ((progress * 100) + "%");
$(".progress").width(calcProgress);
}
/** Time events **/
function timeUpdate(e) {
/** Update Variables **/
time = playerE.currentTime;
dur = playerE.duration;
/** Update Progress and Buffer **/
if (isScrubbing === false) {
var progress = time / dur;
}
var buffered = playerE.buffered.end(0) / dur;
timeConvert(time);
progressWidth(progress);
}
function setPlayerTime(timeset) {
playerE.currentTime = timeset * dur;
}
function timeConvert(s) {
var h = Math.floor(s / 3600);
s -= h * 3600;
var m = Math.floor(s / 60);
s -= m * 60;
var resultSubstring = ((m < 10 ? '0' + m : m) + ":" + (s < 10 ? '0' + s : s)).substring(0, 5);
$('#playerTime').text(resultSubstring);
}
/** Scrubber **/
$(".player-small").mouseenter(function () {
knob.stop().fadeIn(200);
});
setTimeout(function () {
$(".player-small").mouseleave(function () {
knob.stop().fadeOut(200);
});
}, 3000);
function scrubberClick(e) {
isScrubberHolding = true;
isScrubbing = true;
player.trigger('pause');
var $this = $(this);
var x = e.pageX - $this.offset().left;
var percent = x / $this.width();
progressWidth(percent);
tempProgress = percent;
}
$(document).mouseup(function () {
if (isScrubberHolding === true) {
isScrubberHolding = false;
isScrubbing = false;
setPlayerTime(tempProgress)
player.trigger('play');
} else {
isScrubberHolding = false;
}
})
function scrubberGrab(e) {
if (isScrubberHolding === true) {
var $this = $(this);
var x = e.pageX - $this.offset().left;
var percent = x / $this.width();
tempProgress = percent;
progressWidth(percent);
setPlayerTime(percent)
} else {}
}
实际观看:
var player = $('audio'); var playerE = $('audio')[0]; var playerE = $('audio').get(0); var canvasviz = $('canvas'); var playbutton = $("#playButton"); var buffering = $("#buffering"); var scrubber = $(".scrubber-con"); var progress = $(".progress"); var buffered = $(".buffered"); var knob = $(".knob"); var analyser = $("#analyzer"); var currentAlbum = ""; var countElement = $('#playlistCount'); var titleElement = $('#trackTitle'); /** Variables **/ isPlaying = false; isBuffering = false; isScrubbing = false; isScrubberHolding = false; tempProgress = 0; time = playerE.currentTime; dur = playerE.duration; /** Binds and Properties **/ player.bind("timeupdate", timeUpdate); scrubber.bind("mousemove", scrubberGrab); scrubber.bind("mousedown", scrubberClick); /** Progress and Buffer **/ function progressWidth(progress) { var calcProgress = ((progress * 100) + "%"); $(".progress").width(calcProgress); } /** Time events **/ function timeUpdate(e) { /** Update Variables **/ time = playerE.currentTime; dur = playerE.duration; /** Update Progress and Buffer **/ if (isScrubbing === false) { var progress = time / dur; } var buffered = playerE.buffered.end(0) / dur; timeConvert(time); progressWidth(progress); } function setPlayerTime(timeset) { playerE.currentTime = timeset * dur; } function timeConvert(s) { var h = Math.floor(s / 3600); s -= h * 3600; var m = Math.floor(s / 60); s -= m * 60; var resultSubstring = ((m < 10 ? '0' + m : m) + ":" + (s < 10 ? '0' + s : s)).substring(0, 5); $('#playerTime').text(resultSubstring); } /** Scrubber **/ $(".player-small").mouseenter(function () { knob.stop().fadeIn(200); }); setTimeout(function () { $(".player-small").mouseleave(function () { knob.stop().fadeOut(200); }); }, 3000); function scrubberClick(e) { isScrubberHolding = true; isScrubbing = true; player.trigger('pause'); var $this = $(this); var x = e.pageX - $this.offset().left; var percent = x / $this.width(); progressWidth(percent); tempProgress = percent; } $(document).mouseup(function () { if (isScrubberHolding === true) { isScrubberHolding = false; isScrubbing = false; setPlayerTime(tempProgress) player.trigger('play'); } else { isScrubberHolding = false; } }) function scrubberGrab(e) { if (isScrubberHolding === true) { var $this = $(this); var x = e.pageX - $this.offset().left; var percent = x / $this.width(); tempProgress = percent; progressWidth(percent); setPlayerTime(percent) } else {} }
.player-small { height: 55px; width: 100%; background: #ff4081; } .player-height-anim {} .player-small .left { height: 55px; float: left; width: 56%; overflow: hidden; } .player-small .right { height: 40px; position: relative; top: 8px; float: right; width: calc(44% - 2px); overflow: hidden; border-left: solid 2px rgba(0, 0, 0, .05); } .transport { overflow: auto; } .play-button-con { height: 55px; width: 55px; float: left; overflow: hidden; } #buffering { height: 55px; width: 55px; animation: rotating 900ms ease infinite; background-image: url(img/player-buffering.svg); background-size: contain; display: none; } @-webkit-keyframes rotating { from { -ms-transform: rotate(0deg); -moz-transform: rotate(0deg); -webkit-transform: rotate(0deg); -o-transform: rotate(0deg); transform: rotate(0deg); } to { -ms-transform: rotate(360deg); -moz-transform: rotate(360deg); -webkit-transform: rotate(360deg); -o-transform: rotate(360deg); transform: rotate(360deg); } } @keyframes rotating { from { -ms-transform: rotate(0deg); -moz-transform: rotate(0deg); -webkit-transform: rotate(0deg); -o-transform: rotate(0deg); transform: rotate(0deg); } to { -ms-transform: rotate(360deg); -moz-transform: rotate(360deg); -webkit-transform: rotate(360deg); -o-transform: rotate(360deg); transform: rotate(360deg); } } .rotating { -webkit-animation: rotating 2s linear infinite; -moz-animation: rotating 2s linear infinite; -ms-animation: rotating 2s linear infinite; -o-animation: rotating 2s linear infinite; animation: rotating 2s linear infinite; } #playButton { width: 55px; height: 55px; font-size: 18px; text-align: center; background-image: url(img/player-play.svg); background-size: contain; image-rendering: crisp-edges; -webkit-image-rendering: crisp-edges; } .playFailed { pointer-events: none; } .next-button-con { height: 55px; width: 55px; float: left; } #nextButton { width: 55px; height: 55px; text-align: center; font-size: 11px; background-image: url(img/player-next.svg); background-size: contain; } .scrubber-con { margin: auto; margin-top: 12px; height: 30px; width: calc(100% - 40px); overflow: visible; cursor: pointer; } .scrubber-container { float: left; height: 55px; width: calc(100% - 154px); overflow: hidden; } .scrubber { margin: auto; height: 5px; background: rgba(0, 0, 0, .04); position: relative; top: 13px; } .scrubber .knob { float: right; height: 13px; width: 13px; position: relative; bottom: 4px; left: 5px; background: white; border-radius: 50px; display: none; } .scrubber .knob:hover { cursor: grab; } .scrubber .knob:active { cursor: grabbing; } .scrubber .progress { height: 100%; float: left; background: white; width: 0%; position: relative; z-index: 1; } .scrubber .buffered { height: 5px; position: relative; width: 0%; background: rgba(0, 0, 0, .2); transition: ease 1000ms; } .time-con { float: left; width: 30px; height: 55px; } .time { position: relative; top: 20px; color: white; font-size: 13px; } .player-small .button { color: white; float: left; cursor: pointer; } .player-small .button:hover { background: rgba(0, 0, 0, .12); } .analyzer-con { float: left; position: relative; margin-left: 235px; width: calc(100% - 650px); height: 60px; } #analyzer { width: 100%; height: 45px; margin-top: 8px; display: none; } audio { display: block; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="player-small"> <div class="w-ctrl"> <div class="controls"> <div class="left"> <div class="transport"> <div class="play-button-con"> <div class="button playFailed" id="playButton" onclick="togglePlay()"> </div> <div id="buffering"> </div> </div> <div class="next-button-con"> <div class="button" id="nextButton" onclick="next()"></div> </div> <div class="scrubber-container" nmousedown="event.preventDefault ? event.preventDefault() : event.returnValue = false"> <div class="scrubber-con" nmousedown="event.preventDefault ? event.preventDefault() : event.returnValue = false"> <div class="scrubber" draggable="false" nmousedown="event.preventDefault ? event.preventDefault() : event.returnValue = false"> <div class="progress" draggable="false" onmousedown="event.preventDefault ? event.preventDefault() : event.returnValue = false"> <div class="knob" draggable="false" onmousedown="event.preventDefault ? event.preventDefault() : event.returnValue = false"></div> </div> <div class="buffered"></div> </div> </div> </div> <div class="time-con"> <div class="time" id="playerTime">0:00</div> </div> </div> </div> <div class="right"> <audio id="player" src="your track here" controls="controls" preload="none"></audio> <div class="info"> <div class="count" id="playlistCount">0/0</div> <div class="title" id="trackTitle">Track title</div> </div> </div> </div> </div> </div>
抓住我的自定义搜索器(左),然后将鼠标移出粉红色区域。 现在,对音频元素(右)执行相同的操作,您需要为其播放音轨,以便能够移动其搜索器。 看看即使您的鼠标不在里面,也可以如何拖动它?
那么如何为我的自定义搜索器获得这种行为?
1楼
由于将mousemove
绑定到scrubber, scrubberGrab()
仅在鼠标位于scrubber
元素上方时运行。
更改
scrubber.bind("mousemove", scrubberGrab);
至
$(document).bind("mousemove", scrubberGrab);
function scrubberGrab(e) {
if (isScrubberHolding === true) {
var x = e.pageX - scrubber.offset().left;
var percent = Math.min(Math.max(x / scrubber.width(), 0), 1.0);
tempProgress = percent;
progressWidth(percent);
setPlayerTime(percent);
} else {}
}