鼠标移动不能在元素外工作



我已经为我的<audio>元素制作了mousedownmousemove的滑块/导引头。我的问题是,一旦用户离开元素,同时仍然按住鼠标按钮,它不注册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>

抓住我的自定义搜索器(左),并将鼠标从粉红色区域移开。现在对音频元素做同样的事情,你需要一个轨道让它播放,以便能够移动它的导引头。看到了吗,即使你的鼠标不在里面,你也可以拖动它?

那么我如何为我的自定义搜索器获得这种行为呢?

由于您将mousemove绑定到洗涤器,因此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 {}
}

最新更新