RXJS Drag n drop

空扰寡人 提交于 2019-12-22 07:37:58

问题


This questions relates to RXJS. I'm trying to adapt the drag and drop example in github to work for a class of divs not just a single element ID. https://github.com/Reactive-Extensions/RxJS/blob/master/examples/dragndrop/dragndrop.html

simple changes to give the div a class nor an ID dont work and i lose ability to drag the element

3 simple changes:

HTML line 7 i.e. <div class="dragTarget">Drag Me!</div>
CSS line 1 i.e. .dragTarget { style attributes unchanged }
JS line 4 i.e var dragTarget = document.getElementsByClassName('dragTarget');

Im not skilled enough to know if this is a bug in RXJS or that the example is not generalised enough. The documentation on RXJS events suggests these changes should be sufficient. Any help appreciated. Thanks.


回答1:


fromEvent will use the on and off methods of any Object you pass it, otherwise it will use addEventListener and removeEventListener. So if you're using jQuery, you can simply select all of them and use that (Observable.fromEvent($('.targetNode'), 'mouseup') for example).

Otherwise, you can use any object with an on and off method to subscribe or unsubscribe from the events, like I'm doing below.

Other than that, you can use the target property on the MouseEvent objects you get in each stream to get the actual DOM node you care to move...

Something like the example below should do the trick.

(function (global) {

  /**
    selectNodes is a method to select a NodeList, but convert it to 
    a type that has `on` and `off` methods RxJS 2 expects to see for `fromEvent`
  */
  function selectNodes(selector) {
    var nodes = document.querySelectorAll(selector);

    return {
      // the selected nodes
      nodes: [].slice.call(this.nodes),

      // subscribe to an event on every selected node
      on: function(eventName, handler) {
        this.nodes.forEach(function(node) { node.addEventListener(eventName, handler); });
      },

      // unsubscribe from the event on every selected node
      off: function(eventName, handler) {
        this.nodes.forEach(function(node) { node.removeEventListener(eventName, handler); });
      }
    };
  }

  function main () {
    // IMPORTANT CHANGE: Use the selectNodes method we made
    var dragTargets = selectNodes('.dragTarget');

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

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

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

      // Calculate delta with mousemove until mouseup
      return mousemove.map(function (mm) {
        mm.preventDefault();

        return {
          left: mm.clientX - startX,
          top: mm.clientY - startY,
          target: mm.target, // IMPORTANT CHANGE: the element you care about
        };
      }).takeUntil(mouseup);
    });

    // Update position
    var subscription = mousedrag.subscribe(function (d) {
      d.target.style.top = d.top + 'px';
      d.target.style.left = d.left + 'px';
    });
  }

  main();

}(window));


来源:https://stackoverflow.com/questions/30080605/rxjs-drag-n-drop

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!