最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - RxJs How do deal with document events - Stack Overflow

programmeradmin1浏览0评论

Started using RxJs. Can't find a way around this problem. I have a draggable control:

startDrag = rx.Observable.fromEvent(myElem,'mousedown')

now, because the control is too small mousemove and mouseup events should be at document level (otherwise it won't stop dragging unless cursor exactly on the element)

endDrag = rx.Observable.fromEvent document,'mouseup'

position = startDrag.flatMap ->
   rx.Observable.fromEvent document,'mousemove'
   .map (x)-> x.clientX
   .takeUntil endDrag

now how do I "catch" the right moment when is not being dragged anymore (mouseup). you see the problem with subscribing to endDrag? It will fire every time clicked anywhere, and not just myElem How do I check all 3 properties at once? It should take only those document.mouseups that happened exactly after startDrag and position

Upd: I mean the problem is not with moving the element. That part is easy - subscribe to position, change element's css. My problem is - I need to detect the moment of mouseup and know the exact element that's been dragged (there are multiple elements on the page). How to do that I have no idea.

Started using RxJs. Can't find a way around this problem. I have a draggable control:

startDrag = rx.Observable.fromEvent(myElem,'mousedown')

now, because the control is too small mousemove and mouseup events should be at document level (otherwise it won't stop dragging unless cursor exactly on the element)

endDrag = rx.Observable.fromEvent document,'mouseup'

position = startDrag.flatMap ->
   rx.Observable.fromEvent document,'mousemove'
   .map (x)-> x.clientX
   .takeUntil endDrag

now how do I "catch" the right moment when is not being dragged anymore (mouseup). you see the problem with subscribing to endDrag? It will fire every time clicked anywhere, and not just myElem How do I check all 3 properties at once? It should take only those document.mouseups that happened exactly after startDrag and position

Upd: I mean the problem is not with moving the element. That part is easy - subscribe to position, change element's css. My problem is - I need to detect the moment of mouseup and know the exact element that's been dragged (there are multiple elements on the page). How to do that I have no idea.

Share Improve this question edited Feb 12, 2015 at 12:26 iLemming asked Feb 12, 2015 at 12:11 iLemmingiLemming 36.3k61 gold badges198 silver badges316 bronze badges 0
Add a ment  | 

1 Answer 1

Reset to default 8

I have adapted the drag and drop example provided at the RxJS repo to behave as you need.

Notable changes:

  • mouseUp listens at document.

  • The targeted element is added to the return from select.

  • Drag movements are handled inside of map and map returns the element that was targeted in the mouseDown event.

  • Call last after takeUntil(mouseUp) so subscribe will only be reached when the drag process ends (once per drag).

Working example:

function main() {
  var dragTarget = document.getElementById('dragTarget');

  // Get the three major events
  var mouseup = Rx.Observable.fromEvent(document, 'mouseup');
  var mousemove = Rx.Observable.fromEvent(document, 'mousemove');
  var mousedown = Rx.Observable.fromEvent(dragTarget, 'mousedown');


  var mousedrag = mousedown.selectMany(function(md) {

    // calculate offsets when mouse down
    var startX = md.offsetX;
    var startY = md.offsetY;

    // Calculate delta with mousemove until mouseup
    return mousemove.select(function(mm) {
      if (mm.preventDefault) mm.preventDefault();
      else event.returnValue = false;

      return {
        // Include the targeted element
        elem: mm.target,
        pos: {
          left: mm.clientX - startX,
          top: mm.clientY - startY
        }
      };
    })
    .map(function(data) {
      // Update position
      dragTarget.style.top = data.pos.top + 'px';
      dragTarget.style.left = data.pos.left + 'px';

      // Just return the element
      return data.elem;
    })
    .takeUntil(mouseup)
    .last();
  });


  // Here we receive the element when the drag is finished
  subscription = mousedrag.subscribe(function(elem) {
    alert('Drag ended on #' + elem.id);
  });
}
main();
#dragTarget {
  position: absolute;
  width: 20px;
  height: 20px;
  background: #0f0;
}
<script src="https://cdnjs.cloudflare./ajax/libs/rxjs/4.0.7/rx.all.min.js"></script>
<div id="dragTarget"></div>

发布评论

评论列表(0)

  1. 暂无评论
ok 不同模板 switch ($forum['model']) { /*case '0': include _include(APP_PATH . 'view/htm/read.htm'); break;*/ default: include _include(theme_load('read', $fid)); break; } } break; case '10': // 主题外链 / thread external link http_location(htmlspecialchars_decode(trim($thread['description']))); break; case '11': // 单页 / single page $attachlist = array(); $imagelist = array(); $thread['filelist'] = array(); $threadlist = NULL; $thread['files'] > 0 and list($attachlist, $imagelist, $thread['filelist']) = well_attach_find_by_tid($tid); $data = data_read_cache($tid); empty($data) and message(-1, lang('data_malformation')); $tidlist = $forum['threads'] ? page_find_by_fid($fid, $page, $pagesize) : NULL; if ($tidlist) { $tidarr = arrlist_values($tidlist, 'tid'); $threadlist = well_thread_find($tidarr, $pagesize); // 按之前tidlist排序 $threadlist = array2_sort_key($threadlist, $tidlist, 'tid'); } $allowpost = forum_access_user($fid, $gid, 'allowpost'); $allowupdate = forum_access_mod($fid, $gid, 'allowupdate'); $allowdelete = forum_access_mod($fid, $gid, 'allowdelete'); $access = array('allowpost' => $allowpost, 'allowupdate' => $allowupdate, 'allowdelete' => $allowdelete); $header['title'] = $thread['subject']; $header['mobile_link'] = $thread['url']; $header['keywords'] = $thread['keyword'] ? $thread['keyword'] : $thread['subject']; $header['description'] = $thread['description'] ? $thread['description'] : $thread['brief']; $_SESSION['fid'] = $fid; if ($ajax) { empty($conf['api_on']) and message(0, lang('closed')); $apilist['header'] = $header; $apilist['extra'] = $extra; $apilist['access'] = $access; $apilist['thread'] = well_thread_safe_info($thread); $apilist['thread_data'] = $data; $apilist['forum'] = $forum; $apilist['imagelist'] = $imagelist; $apilist['filelist'] = $thread['filelist']; $apilist['threadlist'] = $threadlist; message(0, $apilist); } else { include _include(theme_load('single_page', $fid)); } break; default: message(-1, lang('data_malformation')); break; } ?>