Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript RxJS:区分单击和拖动_Javascript_Angularjs_Rxjs - Fatal编程技术网

Javascript RxJS:区分单击和拖动

Javascript RxJS:区分单击和拖动,javascript,angularjs,rxjs,Javascript,Angularjs,Rxjs,我有一个AngularJS组件,它可以对单击或拖动(调整区域大小)做出反应 我开始在我的应用程序中使用RxJS(ReactiveX),所以我试图找到一个使用它的解决方案。请求的角度很小 为了简化问题(并训练自己),我根据rx.angular.js拖放示例制作了一个滑块指令: 请参阅Slide.js文件(其他代码用于其他实验)。此逻辑的代码为: function(scope, element, attributes) { var thumb = element.chil

我有一个AngularJS组件,它可以对单击或拖动(调整区域大小)做出反应

我开始在我的应用程序中使用RxJS(ReactiveX),所以我试图找到一个使用它的解决方案。请求的角度很小

为了简化问题(并训练自己),我根据rx.angular.js拖放示例制作了一个滑块指令: 请参阅Slide.js文件(其他代码用于其他实验)。此逻辑的代码为:

    function(scope, element, attributes)
    {
      var thumb = element.children(0);
      var sliderPosition = element[0].getBoundingClientRect().left;
      var sliderWidth = element[0].getBoundingClientRect().width;
      var thumbPosition = thumb[0].getBoundingClientRect().left;
      var thumbWidth = thumb[0].getBoundingClientRect().width;

      // Based on drag'n'drop example of rx-angular.js
      // Get the three major events
      var mousedown = rx.Observable.fromEvent(thumb,     'mousedown');
      var mousemove = rx.Observable.fromEvent(element,   'mousemove');
      var mouseup   = rx.Observable.fromEvent($document, 'mouseup');

      // I would like to be able to detect a single click vs. click and drag.
      // I would say if we get mouseup shortly after mousedown, it is a single click;
      // mousedown.delay(200).takeUntil(mouseup)
      //   .subscribe(function() { console.log('Simple click'); }, undefined, function() { console.log('Simple click completed'); });

      var locatedMouseDown = mousedown.map(function (event) 
      {
        event.preventDefault();
        // console.log('Click', event.clientX - sliderPosition);
        // calculate offsets when mouse down
        var initialThumbPosition = thumb[0].getBoundingClientRect().left - sliderPosition;
        return { from: initialThumbPosition, offset: event.clientX - sliderPosition };
      });

      // Combine mouse down with mouse move until mouse up
      var mousedrag = locatedMouseDown.flatMap(function (clickInfo) 
      {
        return mousemove.map(function (event)
        {
          var move = event.clientX - sliderPosition - clickInfo.offset;
          // console.log('Move', clickInfo);
          // calculate offsets from mouse down to mouse moves
          return clickInfo.from + move;
        }).takeUntil(mouseup);
      });

      mousedrag 
        .map(function (position)
        {
          if (position < 0)
            return 0;
          if (position > sliderWidth - thumbWidth)
            return sliderWidth - thumbWidth;
          return position;
        })
        .subscribe(function (position) 
        {
          // console.log('Drag', position);
          // Update position
          thumb.css({ left: position + 'px' });
        });
    }
函数(范围、元素、属性)
{
var thumb=element.children(0);
var sliderPosition=元素[0]。getBoundingClientRect()。左;
var sliderWidth=元素[0]。getBoundingClientRect().width;
var thumbPosition=thumb[0].getBoundingClientRect().left;
var thumbWidth=thumb[0]。getBoundingClientRect().width;
//基于rx-angular.js的拖放示例
//获取三大事件
var mousedown=rx.Observable.fromEvent(拇指“mousedown”);
var mousemove=rx.Observable.fromEvent(元素“mousemove”);
var mouseup=rx.Observable.fromEvent($document,'mouseup');
//我想能够检测到一个单一的点击与点击和拖动。
//我想说,如果我们在鼠标下移后很快得到mouseup,那只是一次单击;
//mousedown.delay(200)。takeUntil(mouseup)
//.subscribe(函数(){console.log('Simple click');},未定义,函数(){console.log('Simple click completed');});
var locatedMouseDown=mousedown.map(函数(事件)
{
event.preventDefault();
//log('Click',event.clientX-sliderPosition);
//按下鼠标时计算偏移量
var initialThumbPosition=thumb[0]。getBoundingClientRect()。左-滑块位置;
返回{from:initialThumbPosition,offset:event.clientX-sliderPosition};
});
//将鼠标向下移动与鼠标移动相结合,直到鼠标向上移动
var mousedrag=locatedMouseDown.flatMap(函数(单击信息)
{
返回mousemove.map(函数(事件)
{
var move=event.clientX-sliderPosition-clickInfo.offset;
//console.log('Move',clickInfo);
//计算从鼠标下移到鼠标移动的偏移量
返回clickInfo.from+移动;
}).takeUntil(mouseup);
});
鼠笼
.地图(功能(位置)
{
如果(位置<0)
返回0;
如果(位置>滑块宽度-指宽)
返回滑块宽度-指宽;
返回位置;
})
.订阅(功能(职位)
{
//console.log('拖动',位置);
//更新位置
css({left:position+'px'});
});
}
这主要是D'n'D水平约束和给定范围

现在,我想听听mousedown,如果鼠标在短时间内向上移动(比如说200毫秒,进行调整),我会将其视为单击,并进行特定处理(例如,将位置重置为零)

我尝试了
delay().takeUntil(mouseup)
,如另一个SO答案所示,但没有成功。也许还需要一个switch()(以避免走拖动路线)


有什么想法吗?提前感谢。

延迟(Xms)不是一个诀窍吗?takeUntil(鼠标)做的与你想要的相反?我的意思是,你想在倒计时之前检测
mouseup
事件发生的时间,而前面提到的技巧是在倒计时之后检测mouseup事件发生的时间

我会围绕这些思路尝试一些东西(目前尚未测试,但希望它能让你朝着积极的方向发展):

想法是将
mouseup
事件与延迟后发生的虚拟发射进行比赛,然后看谁获胜。因此,如果<代码>点击$< /代码>发出“NoCeCt”,那么你可以考虑没有点击发生。
希望这能起作用,我将很快进行测试,但如果您在我之前进行测试,请让我知道。

您可以使用
timeout
timeout with
如果您使用的是ReactiveX/RxJS)


如果鼠标在超时之前没有出现,它只会传播一个空的
可观察的
。如果是这样,那么下游的观察者将收到一个事件。

我还没有尝试(还没有?),因为我第一次尝试了@paulpdniels的答案,这更简单。。。而且有效。但是我很欣赏这个答案,它展示了一个有趣的技巧。谢谢。当然,你选择的答案是最好的。毫无疑问,我不知道那个接线员,他们太多了,你很难理解他们所有的+1,这就是为什么我问问题,因为我必须让我的思维适应Rx的思维方式。。。一旦掌握了基本知识,尝试回答问题也是探索API的一个好方法…:-DIt与
timeout()
一起工作。我在版本4.0的RxJS库中没有发现
timeoutWith
,但是有一个
timeoutWithSelector
,它显然只在lite子库中可用。它似乎与第二个版本的
timeout
做了相同的事情。也许这只是一个遗产。不管怎样,它是有效的。所以谢谢。@PhiLho
timeoutWith
是其中的一部分。RxJS 4.0仍在被动扩展项目下,因此它使用的是
timeout
。你提到了ReactiveX,这就是我提到它的原因。但我很乐意帮忙!vNext?唉。名称和ESNext一样愚蠢…;-)每个版本都是“下一个”,不知怎的。。。我理解这是为了标记一个重大的更新/更改,但名称仍然没有意义。我想vNext最终会是v.5?无论如何,你把我推向了正确的方向(如果你愿意,请参阅Plunker的更新),再次感谢。
var click$ = mousedown.flatMap(function ( mouseDownEv ) {
  return merge(
      Rx.just(mouseDownEv).delay(Xms).map(function ( x ) {return {event : 'noclick'};}),
      mouseup.map(function ( mouseUpEv ) {return {event : mouseUpEv};})
      ).first();
});
var click$ = mousedown.flatMap(function (md) {
  return mouseup.timeoutWith(200, Observable.empty());
});