【问题标题】:Why does this CSS style interfere with HTML5 drag and drop? (position: absolute; left: -10000px)为什么这种 CSS 样式会干扰 HTML5 拖放? (位置:绝对;左:-10000px)
【发布时间】:2023-04-01 18:11:01
【问题描述】:

Dojo Dijit Buttons 使用 CSS 将“真实”按钮隐藏在屏幕外:

.dijitOffScreen { 
    position: absolute !important;
    left: -10000px !important;
    top: -10000px !important;
}    
  • 为什么这会导致 HTML5 拖放功能在 Chrome 和 FireFox 中无法正常工作?
  • 有哪些替代方法可以隐藏输入元素并保持相同的 Dojo Dijit 按钮行为?(将 display:none 添加到屏幕外输入元素似乎有效,但这在功能上会改变输入的行为吗?因此小部件?)

原问题:

有时,默认的“幽灵”HTML5 拖动图像尺寸较小或根本不呈现。它因浏览器而异,似乎与涉及的 Dojo Dijits 交互。

将 Dijit Button 添加到可拖动的 Dijit ContentPane 后,是什么导致拖动图标在 FireFox 中很小,而在 Chrome 中根本不呈现?

简单jsFiddle repro:

var cp1 = new ContentPane({
    style: "width: 400px; height: 124px; background:red",
    content: "cp1: 'ghost 'drag icon is tiny or not visible :(<br />",
});

// Make draggable
domProp.set(cp1.domNode, 'draggable', 'true');
cp1.on('dragstart', onDragStartHandler); // otherwise FF doesn't show drag icon

// PROBLEM -> adding button messes up drag icon
button = new Button({label: 'Dijit Button'});
button.placeAt(cp1.containerNode);

更新:

  • 除了不正确地呈现拖动图标之外,其他 HTML5 拖放事件也不再正常工作。在 Chrome 上,添加 dragover 和/或 end 事件后,整个文档就会消失。在 FireFox 上,拖动事件的处理速度要慢得多。
  • 添加通用 HTML 按钮输入而不是 Dijit 按钮不会导致任何这些副作用:Dojo Dijit 肯定会以某种方式干扰...

更新 2:

  • 根本原因:Dijit Button 通过 dijitOffScreen 类隐藏了 HTML 按钮输入元素。从元素中删除 left: 10000px !importanttop: 10000px !important 样式会恢复拖放,但会显示空白按钮。信用:Kenneth G. Franqueiro

【问题讨论】:

    标签: javascript html draggable dojo


    【解决方案1】:

    根据the spec,您可以使用“setDragImage”来指定要在拖动时使用的图像元素,如下所示:

          // First, create draggable ContentPane with weird drag icon
          var cp1 = new ContentPane({
            style: "width: 400px; height: 124px; background:red",
            content: "cp1: 'ghost 'drag icon is full-sized and visible :)<br />",
          });
          var img = document.getElementById("drag-image");
          onDragStartHandler1 = function (ev) {
            console.log(ev);
            console.log('DragStart:', ev.target.id);
            ev.dataTransfer.setData("Text", ev.target.id);
            // Define "ghost" image here, with proper offset
            ev.dataTransfer.setDragImage(img, ev.x, ev.y);
          }
          // PROBLEM -> adding button messes up drag icon
          button = new Button({
            label: 'Dijit Button'
          });
          button.placeAt(cp1.containerNode);
    
          // Make draggable
          domProp.set(cp1.domNode, 'draggable', 'true');
          cp1.on('dragstart', onDragStartHandler1); // otherwise FF doesn't show drag icon
    
          // Add to document
          cp1.placeAt(document.body);
          cp1.startup();
    

    这里是your fiddle, fixed.

    编辑:

    我想我不应该真的说“固定”,更像是变通方法......奇怪的是它在默认情况下在拖动过程中不显示元素,但是,正如你所说,也许这是一个奇怪的道场-相关的事情。无论如何,在这种情况下,似乎“setDragImage”可能会明确定义用户反馈......

    【讨论】:

      【解决方案2】:

      我从来没有找到这些 CSS 样式搞乱 HTML5 拖放的确切原因(我猜浏览器试图构建一个包含“屏幕外”元素的非常大的拖放图像)。

      但是,我找到了两种解决方法(CSS 样式附加到我想要拖放的元素的自动创建的子节点上):

      • 删除带有违规 CSS 样式的 dom 节点
      • display:none 样式添加到具有违规 CSS 样式的 dom 节点

      两种解决方法都恢复了预期的 HTML5 拖放行为;我还没有注意到任何不需要的副作用。


      更新: 将 z-index 设置为较大的负值似乎是一种更好的解决方法:
      .dijitOffScreen { 
          top: 0;
          left: 0;
          z-index: -9999;
      }
      

      【讨论】:

      • 关于更新:负 z-index 解决方法在某些情况下无济于事。设置 display: none 是更强大的解决方案,我认为。
      猜你喜欢
      • 2013-01-20
      • 1970-01-01
      • 2018-12-26
      • 2011-11-22
      • 2011-03-14
      • 1970-01-01
      • 2015-07-11
      • 2011-06-23
      • 1970-01-01
      相关资源
      最近更新 更多