如何使用 jquery 将 A 元素动态移动到水平线上

How to dynamically move A element into a horizontal line with jquery

我用小部件 api 创建了一个自定义 Soundcloud Player,并以这种方式制作了一个图形进度条:

<a id="slider-handle" href="#" style="left: 0"></a>

我在轨道的当前位置之后动态移动左侧属性(我做了从毫秒到百分比值的转换)。这很好用。现在我会让人们在歌曲中来回移动这个锚元素(就像一个范围输入)。是否可以用 jquery 来做到这一点?

这里是完整的代码,如果你尝试在右下角播放一首歌曲会更清楚:http://jsfiddle.net/7s2joet2/27/

我来试试看:

首先,您需要在#slider-handle上设置draggable="false",因为支持HTML5拖放的浏览器在拖动时会显示'forbidden'光标().

我们需要以下属性来准确定位拖动手柄:

  • Event.clientX:光标当前x坐标
  • Element.clientWidth:元素的渲染宽度(以像素为单位)
  • Element.offsetLeft: 元素从页面左侧的渲染偏移量(以像素为单位)

我们需要标志来跟踪状态(用户是否点击了?用户是否离开了小部件?):

  • isToggled: true 当用户点击进度条或手柄时
  • isMdowntrue 当用户单击手柄时

将以下代码添加到您的代码中,并更改一些现有代码:

var isMdown     = false,    // gets set to true when user clicks the handle
    isToggled = false,  // gets set to true when user clicks the bar or handle
    progress    = $('#progress'),
    percentage= null,   // keeps track of the last % 
    handleW     = 8,            // width of the handle, req. for positioning
    handle      = document.getElementById('slider-handle'),
    range       = document.getElementById('slider-range');

// main position adjustment function
var setPos = function(e) {
  var posxBuffer = e.clientX - progress.offset().left,
      w = this.clientWidth;
  widget.getDuration(function(duration){
    widget.seekTo(percentage*duration/100);
    handle.style.left = percentage + '%';
    range.style.width = percentage + '%';
  });
  isToggled = false;
  isMdown   = false;
};

// we just need to update the % value here and set some flags
progress.on('mousedown', function(e) {
  isToggled = true;
  var posxBuffer = e.clientX - progress.offset().left,
      w = this.clientWidth;
  percentage = ((posxBuffer-handleW)*100)/w;
  if (e.target === handle)
    isMdown = true;
});

progress.on('mouseover', function(e) {
  // if the user has previously triggered a mousedown event, he is now dragging
  // => adjust handle position, but not time progress
  if (isMdown) {
    var posxBuffer = e.clientX- progress.offset().left,
        w = this.clientWidth;
    percentage = ((posxBuffer-handleW)*100)/w;
    handle.style.left = percentage + '%';
    range.style.width = percentage + '%';
  }
});

// when a user has clicked the progress bar and releases the button,
// set the position
progress.on('mouseup', setPos);

// when a user is still dragging but leaves the progress bar, 
// release and set to last position
progress.on('mouseleave', function(e) {
  if (isMdown)
    setPos(e);
});

widget.bind(SC.Widget.Events.PLAY_PROGRESS, function(){
  widget.getPosition(function(position){
    widget.getDuration(function(duration){
       $('#seekms').text(duration);  
       // Just as a bonus, the code for transforming ms into a MM:SS format =)
       var mins = (position/1000/60 < 10 ? '0' : '') + Math.floor(position/1000/60),
           secs = (position/1000%60 < 10 ? '0' : '') + Math.floor((position/1000) %60);
       $('#bufferms').text(mins + ':' + secs);
       // only updated if the user already moused down on either handler or bar
       if (isToggled || isMdown)
          return;
       var percentage = position*100/duration;
       $("#slider-range").css("width", percentage + '%');
       $("#slider-handle").css("left", percentage + '%');
                 $('#inputseek').val(percentage);
    });
  });
});

查看实际效果:http://jsfiddle.net/7s2joet2/31/(注意:我将手柄 + 栏做得更大,这样更容易拖动)