简体   繁体   English

为什么这种CSS样式会干扰HTML5的拖放? (位置:绝对;左:-10000px)

[英]Why does this CSS style interfere with HTML5 drag and drop? (position: absolute; left: -10000px)

Dojo Dijit Buttons hide the "real" button offscreen using CSS: Dojo Dijit Buttons使用CSS在屏幕外隐藏“真实”按钮:

.dijitOffScreen { 
    position: absolute !important;
    left: -10000px !important;
    top: -10000px !important;
}    
  • Why does this cause HTML5 drag and drop to not function correctly in Chrome and FireFox? 为什么这会导致HTML5拖放在Chrome和FireFox中无法正常运行?
  • What are alternative methods to hide the input element and maintain the same Dojo Dijit Button behavior? 隐藏输入元素并保持相同的Dojo Dijit Button行为的替代方法是什么? (Adding display:none to the offscreen input element seems to work, but does that functionally alter the behavior of the input and thus widget?) (将display:none添加到屏幕外输入元素似乎可行,但这是否在功能上改变了输入的行为,进而改变了小部件的行为?)

Original question: 原始问题:

Sometimes the default 'ghost' HTML5 drag image is smaller in size or not rendered at all. 有时,默认的“重影” HTML5拖动图片尺寸较小或根本没有呈现。 It varies by browser and there seems to be an interaction with Dojo Dijits involved. 它因浏览器而异,并且似乎与Dojo Dijits涉及到交互。

After adding a Dijit Button to a draggable Dijit ContentPane, what causes the drag icon to be tiny in FireFox and not rendered at all in Chrome? 在将Dijit Button添加到可拖动的Dijit ContentPane之后,是什么导致拖动图标在FireFox中很小,而在Chrome中根本不呈现?

Simple jsFiddle repro : 简单的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);

update: 更新:

  • In addition to rendering the drag icon incorrectly, other HTML5 drag and drop events no longer function correctly. 除了错误地呈现拖动图标之外,其他HTML5拖放事件也不再正常起作用。 On Chrome, the entire document just disappears after dragover and/or end events are added. 在Chrome上,添加了dragover和/或end事件后,整个文档便消失了。 On FireFox, the processing of drag events is significantly slower. 在FireFox上,拖动事件的处理明显较慢。
  • Adding generic HTML button inputs instead of Dijit buttons does not result in any of these side effects: definitely Dojo Dijit interfering somehow... 添加通用HTML按钮输入而不是Dijit按钮不会导致任何这些副作用:绝对是Dojo Dijit会以某种方式进行干扰...

update 2: 更新2:

  • Root cause: Dijit Button hides an HTML button input element via the dijitOffScreen class. 根本原因:Dijit Button通过dijitOffScreen类隐藏HTML按钮输入元素。 Removing left: 10000px !important and top: 10000px !important styles from the element restores drag and drop at the expense of showing a blank button. 从元素中删除left: 10000px !importanttop: 10000px !important样式可恢复拖放操作,但要以显示空白按钮为代价。 credit: Kenneth G. Franqueiro 信用: 肯尼斯·弗朗克罗(Kenneth G. Franqueiro)

According to the spec , you can use "setDragImage" to specify an image element to use on drag, like this: 根据规范 ,您可以使用“ 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();

Here's your fiddle, fixed. 固定这是您的小提琴。

Edit: 编辑:

I guess I shouldn't really say 'fixed', more like work-arounded... It is odd that it doesn't display the element during drag by default, but, as you said, maybe it's a weird dojo-related thing. 我想我真的不应该说“固定”,更像是变通办法...很奇怪,默认情况下它不会在拖动过程中显示该元素,但是,正如您所说,这也许是与dojo相关的怪异事物。 Regardless, it seems that "setDragImage" is probably there to unambiguously define the user feedback in such cases... 无论如何,似乎在这种情况下“ setDragImage”可以明确定义用户反馈...

I never found the exact reason those CSS styles mess up HTML5 drag and drop (my guess is the browsers were trying to construct a very large drag and drop image that included the 'offscreen' elements). 我从来没有发现这些CSS样式弄乱HTML5拖放的确切原因(我猜想是浏览器试图构建一个包含“屏幕外”元素的非常大的拖放图像)。

However, I have found two work-arounds (the CSS styles were attached to automatically created sub-nodes of the element I wanted to drag and drop): 但是,我发现了两种解决方法(将CSS样式附加到我要拖放的元素的自动创建的子节点上):

  • Remove the dom nodes with offending CSS styles 删除具有不良CSS样式的dom节点
  • Add display:none styles to the dom nodes with offending CSS styles display:none样式添加到带有有害CSS样式的dom节点中

Both work-arounds restore expected HTML5 drag and drop behavior; 两种解决方法都可以恢复预期的HTML5拖放行为; I have not noticed any unwanted side effects, yet. 我还没有注意到任何有害的副作用。


update: Setting the z-index to a large negative value seems to be a better work-around: 更新:将z-index设置为较大的负值似乎是一个更好的解决方法:

 .dijitOffScreen { top: 0; left: 0; z-index: -9999; } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM