Dart 通过在省道中拖动来移动元素

Dart 通过在省道中拖动来移动元素,dart,dart-html,Dart,Dart Html,我正在尝试使用拖放来移动元素。我希望能够将元素拖放到不同的位置,当我拖放它时,元素会移动到拖放的位置。超基本的,没什么特别的。这就是我到目前为止所做的: html: 这不完全符合我的要求。元素与我放置它的位置有点偏离。我在javascript中看到了appendChild、clone()和parentNode的示例,但我所看到的示例中没有一个可以在Dart中复制。实现这一目标的最佳方式是什么?我不想使用DND包,因为我真的想亲自更好地理解这些概念。index.html <!doctype

我正在尝试使用拖放来移动元素。我希望能够将元素拖放到不同的位置,当我拖放它时,元素会移动到拖放的位置。超基本的,没什么特别的。这就是我到目前为止所做的:

html:


这不完全符合我的要求。元素与我放置它的位置有点偏离。我在javascript中看到了appendChild、clone()和parentNode的示例,但我所看到的示例中没有一个可以在Dart中复制。实现这一目标的最佳方式是什么?我不想使用DND包,因为我真的想亲自更好地理解这些概念。

index.html

<!doctype html>
<html>
  <head>
    <style>
      #dropzone {
        position: absolute;
        top: 50px;
        left: 50px;
        width: 300px;
        height: 150px;
        border: solid 1px lightgreen;
      }
      #dropzone.droptarget {
        background-color: lime;
      }
    </style>
  </head>
  <body>
    <input type='button' id='drag' class='draggable' value='drag me'
           draggable='true'>

    <div id="dropzone"></div>
    <script type="application/dart" src="index.dart"></script>
    <script src="packages/browser/dart.js"></script>
  </body>
</html>

上面的答案是正确的,因此我不想编辑它。然而,我也想提供另一个答案,我从上面得到的。与上述内容相比,它更基本,因此初学者更容易理解基本概念。正如下面提到的,我不认为您可以移动元素,除非它们位于可拖放区域内

index.html:

<!DOCTYPE html>
<html>
<head>
  <style>
  #dropzone {
    position: absolute;
    top: 100px;
    left: 50px;
    width: 300px;
    height: 150px;
    border: solid 1px;
    color: lightgreen;
  }</style>
</head>
<body>
  <div  id="dropzone">
    <input type='button' id='drag' class='draggable' value='drag me'
     draggable='true'>
  </div>
  <script type="application/dart" src="main.dart"></script>
</body>
</html>

我有同样的问题,由于上述答案不符合我在以下方面的需要:

  • 图元自身拖动山墙(无放置区域)
  • 可重复使用
  • 对于基于包装器的解决方案,此包可能是答案:

    自定义基于元素的方法(当前光标样式不起作用):

    包括“依赖项”下的“可反射:^0.5.0”和“变压器”下的“可反射:入口点:web/index.dart”等
    在pubspec.yaml中,并扩展一个像上面那样的自定义类,而不是HtmleElement和selfMirror.invoke神奇地调用您的初始值设定项,只要它们的名称与给定的模式匹配。当你的类有相当多的能力时很有用。

    发布一个你试图移植的JS示例的链接会很有帮助。你发布的代码似乎没有任何作用。代码确实有效。真正地但它似乎不再。非常感谢。这是拖动的最基本形式吗?我上周刚学会了拖放,这看起来像是一个巨大的跳跃。我希望在没有落点的情况下拖动元素。可能吗?如果不是的话,那就解释了我缺乏初步的理解。你可以让身体标签成为下降的目标。我认为没有它是行不通的,但我不确定。您可以删除
    onDragLeave
    处理程序以及设置和删除
    droptarget
    类的行。这仅用于鼠标悬停效果。是可用的,并且是对
    dart:mirrors
    <!doctype html>
    <html>
      <head>
        <style>
          #dropzone {
            position: absolute;
            top: 50px;
            left: 50px;
            width: 300px;
            height: 150px;
            border: solid 1px lightgreen;
          }
          #dropzone.droptarget {
            background-color: lime;
          }
        </style>
      </head>
      <body>
        <input type='button' id='drag' class='draggable' value='drag me'
               draggable='true'>
    
        <div id="dropzone"></div>
        <script type="application/dart" src="index.dart"></script>
        <script src="packages/browser/dart.js"></script>
      </body>
    </html>
    
    library _template.web;
    
    import 'dart:html' as dom;
    import 'dart:convert' show JSON;
    
    main() async {
      dom.Element drag = dom.querySelector('.draggable');
      drag.onDragStart.listen((event) {
        final startPos = (event.target as dom.Element).getBoundingClientRect();
        final data = JSON.encode({
          'id': (event.target as dom.Element).id,
          'x': event.client.x - startPos.left,
          'y': event.client.y - startPos.top
        });
        event.dataTransfer.setData('text', data);
      });
    
      dom.Element dropTarget = dom.querySelector('#dropzone');
      dropTarget.onDragOver.listen((event) {
        event.preventDefault();
        dropTarget.classes.add('droptarget');
      });
    
      dropTarget.onDragLeave.listen((event) {
        event.preventDefault();
        dropTarget.classes.remove('droptarget');
      });
    
      dropTarget.onDrop.listen((event) {
        event.preventDefault();
        final data = JSON.decode(event.dataTransfer.getData('text'));
        final drag = dom.document.getElementById(data['id']);
        event.target.append(drag);
        drag.style
          ..position = 'absolute'
          ..left = '${event.offset.x - data['x']}px'
          ..top = '${event.offset.y - data['y']}px';
        dropTarget.classes.remove('droptarget');
      });
    }
    
    <!DOCTYPE html>
    <html>
    <head>
      <style>
      #dropzone {
        position: absolute;
        top: 100px;
        left: 50px;
        width: 300px;
        height: 150px;
        border: solid 1px;
        color: lightgreen;
      }</style>
    </head>
    <body>
      <div  id="dropzone">
        <input type='button' id='drag' class='draggable' value='drag me'
         draggable='true'>
      </div>
      <script type="application/dart" src="main.dart"></script>
    </body>
    </html>
    
    import 'dart:html';
    main() {
      Element drag = querySelector('.draggable');
      Element drop = querySelector('#dropzone');
      drag.onDragStart.listen((MouseEvent e) {
        var startPos = (e.target as Element).getBoundingClientRect();
        String xPos = "${e.client.x - startPos.left}";
        String yPos = "${e.client.y - startPos.top}";
        e.dataTransfer.setData('x', xPos);
        e.dataTransfer.setData('y', yPos);
      });
      drop.onDragOver.listen((MouseEvent e) {
        e.preventDefault();
      });
      drop.onDrop.listen((MouseEvent e) {
        e.stopPropagation();
        String xPos = e.dataTransfer.getData('x');
        String yPos = e.dataTransfer.getData('y');
        int x = num.parse(xPos);
        int y = num.parse(yPos);
        drag.style.position = 'absolute';
        drag.style
          ..left = '${e.offset.x - x}px'
          ..top = '${e.offset.y - y}px';
      });
    }
    
      main(){
      document.registerElement('draggable-element',
        DraggableElement);
      querySelector('body').append(new DraggableElement()..text='draggable');
      }
      class DraggableElement extends HtmlElement with Draggability{
      DraggableElement.created():super.created(){
        learn_custom_draggability();
      }
      factory DraggableElement(){
        return new Element.tag('draggable-element');
      }
    }
    class Draggability{
      bool __custom_mouseDown = false;
    
      //The Coordinates of the mouse click
      //relative to the left top of the
      //element.
      Point<int> __custom_relative_mouse_position;
      void learn_custom_draggability(){
        if(this is! HtmlElement ){
          throw ("Draggability mixin "
              "is not compatible with"
              ' non-HtmlElement.');
        }
        var self = (this as HtmlElement);
        self.onMouseDown.listen(mouseDownEventHandler);
        self.onMouseUp.listen(mouseUpEventHandler);
        //styling
        self.style.position = 'absolute';
    
        window.onMouseMove
            .listen(mouseMoveEventHandler);
      }
    
      void mouseMoveEventHandler(MouseEvent e){
        if(!__custom_mouseDown) return;
        int xoffset = __custom_relative_mouse_position.x,
          yoffset = __custom_relative_mouse_position.y;
    
        var self = (this as HtmlElement);
        int x = e.client.x-xoffset,
            y = e.client.y-yoffset;
        print(x);
        if(y == 0) return;
        self.style
          ..top = y.toString() +'px'
          ..left = x.toString()+'px';
      }
    
      void mouseDownEventHandler(MouseEvent e){
        print('mouse down');
        __custom_mouseDown = true;
        var self = (this as HtmlElement);
        self.style.cursor = 'grabbing';
    
        __custom_relative_mouse_position =
          e.offset;
      }
    
      void mouseUpEventHandler(MouseEvent e){
        print('mouse up');
        __custom_mouseDown = false;
        var self = (this as HtmlElement);
        self.style.cursor = 'default';
      }
    }
    
    import 'package:reflectable/reflectable.dart';
    class Reflector extends Reflectable{
      const Reflector():
            super(
              instanceInvokeCapability,
              declarationsCapability
          );
    }
    const reflector = const Reflector();
    @reflector
    class CustomBase extends HtmlElement{
      CustomBase.created():super.created(){
        learn();
      }
      learn(){
        InstanceMirror selfMirror = reflector.reflect(this);
        var methods = selfMirror.type.instanceMembers;
        RegExp pattern = new RegExp('^learn_custom_.*bility\$');
        for(var k in methods.keys){
          if(pattern.firstMatch(k.toString()) != null){
            selfMirror.invoke(k,[]);
          }
        }
      }
    }