使用 jquery ui 可拖动,是不是可以有不同的滚动灵敏度垂直和水平?

Posted

技术标签:

【中文标题】使用 jquery ui 可拖动,是不是可以有不同的滚动灵敏度垂直和水平?【英文标题】:With jquery ui draggable, is it possible to have different scrollsensitivity vertical versus horizontal?使用 jquery ui 可拖动,是否可以有不同的滚动灵敏度垂直和水平? 【发布时间】:2014-12-16 17:09:41 【问题描述】:

我正在使用jquery ui draggable,我意识到我希望在我向上向下拖动时(相对于向左/向右)滚动灵敏度要小得多。垂直拖动和水平拖动可以有不同的设置吗?

这是我当前的代码

   $(".myDraggable").draggable(
            
                stack: ".myDraggable",
                scroll: true,
                scrollSensitivity: 250,
                scrollSpeed: 40,
                revert: function (event, ui) 
                    $(this).data("uiDraggable").originalPosition = 
                        top: 0,
                        left: 0
                    ;
                    return !event;
                
            
        );

【问题讨论】:

您使用的是哪个版本的 jquery UI? @leora,如果您不提供反馈,我们将无法改进我们的答案。 【参考方案1】:

更新答案

工作示例: http://jsfiddle.net/22bpbsrw/3/

我认为检测视口中何时发生滚动事件确实有效。然后您可以设置滚动速度和灵敏度。

var lastScrollTop = 0,
    lastScrollLeft = 0,
    delta = 5;
$('#viewPort').scroll(function (event) 
    var st = $(this).scrollTop();
    var sl = $(this).scrollLeft();

    if (Math.abs(lastScrollTop - st) > delta) 
        $("#draggable").draggable("option", "scrollSensitivity", 5);
        $("#draggable").draggable("option", "scrollSpeed", 10);
        (st > lastScrollTop) ? console.log('scroll down') : console.log('scroll up');
        lastScrollTop = st;
    

    if (Math.abs(lastScrollLeft - sl) > delta) 
        $("#draggable").draggable("option", "scrollSensitivity", 100);
        $("#draggable").draggable("option", "scrollSpeed", 40);
        sl > lastScrollLeft ? console.log('scroll right') : console.log('scroll left');
        lastScrollLeft = sl;
    
);

旧答案

留下以防万一它可以帮助别人。

您不能为每个方向显式设置不同的scrollSensitivity 值。或许您可以提交一张该增强功能的票?

您也许可以通过拖动功能(based on this answer)对其进行更改。在此处查看工作示例:http://codepen.io/anon/pen/mbups?editors=001

drag: function(e)     
  console.log($("#drag1").draggable( "option", "scrollSensitivity"));
  if(prevX == -1)  prevX = e.pageX; 
  // dragged left or right
  if(prevX > e.pageX || prevX < e.pageX)  // dragged right
      $("#drag1").draggable( "option", "scrollSensitivity", 100 );
  
  prevX = e.pageX;
 
 if(prevY == -1)  prevY = e.pageY;  
  // dragged up or down
  if(prevY > e.pageY || prevY < e.pageX)  // dragged down
      $("#drag1").draggable( "option", "scrollSensitivity", 1 );
  
  prevY = e.pageY;

您可以根据拖动元素的方向设置scrollSensitivity

【讨论】:

【参考方案2】:

虽然 JSuar 的解决方案似乎可行,但我也想尝试一下。

用 jQuery UI Draggable Widget 解决问题是不可能的。

没有明确的函数来获取有关对象是垂直移动还是水平移动的信息。事实上,大多数情况下,对象是双向移动的。但是我们可以定义自己的函数来查看光标是如何移动的

使用自定义函数获取被拖动对象的信息

这个想法是在 mousemove 上触发一个 事件 并每次检查光标位置。在一定间隔鼠标移动后,我们检查整体移动以设置滚动灵敏度。在这种情况下,我们只是假设用户很可能会在下一个动作中朝同一方向拖动。

Here 是一个有效的 JSFiddle 示例。

HTML

<div id="viewPort">
    <div id="draggable">drag me</div>
</div>

CSS

#viewPort 
    width: 300px;
    height: 300px;
    background: #fff;
    overflow:scroll;
    border:1px solid #ccc;

#draggable 
    color: #fff;
    width: 75px;
    height: 75px;
    padding: 10px;
    background: #333399;
    border:1px solid #ccc;
    margin:5px;

JS

//current count of how often we got the mouse positon
var count = 0;
//position of mouse at last function call
var lastPositionX;
var lastPositionY;
//how often we moved in one direction in the last intervall
var movedX;
var movedY;
//intervall to check movement again
var countIntervall = 30;

$("#draggable").draggable(
    scrollSensitivity: 1000,
    scrollSpeed: 40,
    revert: function (event, ui) 
        $("#draggable").originalPosition = 
            top: 0,
            left: 0
        ;
        return !event;
    ,
    drag: function (e) 
       setScrollSensivity();
    
);

//init first mousepostion
$("#draggable").on('click', function() 
    lastPositionX = event.pageX;
    lastPositionY = event.pageY;
);

function setScrollSensivity()
    count++;

    //get current mousepostion
    var currentPositionX = event.pageX; 
    var currentPositionY = event.pageY; 

    //increase if moved on chose axis
    if ( currentPositionX != lastPositionX )
        movedX++;
    

    if ( currentPositionY != lastPositionY )
        movedY++;
    

    //if moved more on x axis decrease sensivity, else increase.
    if (count == countIntervall)
        if (movedX > movedY)
            console.log("moving on X axis");
            $( "#draggable" ).draggable( "option", "scrollSensitivity", 10 );
         else 
            console.log("moving on Y axis");
            $( "#draggable" ).draggable( "option", "scrollSensitivity", 200 );
        
        //reset all the counters and start again
        count = 0;
        movedX = 0;
        movedY = 0;
    
    //set last position for our next function call
    lastPositionX = currentPositionX;
    lastPositionY = currentPositionY;

【讨论】:

你的代码和我的很相似。除了扩展代码之外,究竟有什么不同? 我的方法不依赖于滚动事件,所以它可以用来设置选项,这取决于你用鼠标移动的轴。 这是一个很好的观点,但我将其包含在我的答案中,列为旧答案。 是的,它是相似的。但是在每个 px 移动后触发事件会导致每秒更改滚动灵敏度 100 次。由于用户不会精确地仅在 x 或 y 轴上移动鼠标。我看到了,并认为它可以改进。这就是为什么我说你的已经正确了。

以上是关于使用 jquery ui 可拖动,是不是可以有不同的滚动灵敏度垂直和水平?的主要内容,如果未能解决你的问题,请参考以下文章

通过Jquery UI可拖动时应用阴影可排序

Angular JQuery UI 元素的可拖动副本

Jquery UI 可拖动列表项到框

JQuery UI'可拖动不是函数'未捕获的TypeError

JQuery UI Sortable + Laravel Collection Chunk:行可拖动而不是单个元素

jQuery 和 jQuery UI:构建一个可拖动的无限网格,其中包含不同大小的内容 (imgs)