【问题标题】:jQuery Drag-and-Drop Flickering on Hover (Webkit only)悬停时的 jQuery 拖放闪烁(仅限 Webkit)
【发布时间】:2012-10-08 08:37:54
【问题描述】:

问题

我刚刚完成了一项功能,用户可以将文件拖放到浏览器中并放在支持文件上传插件上,该插件会处理拖放。

然而,为了给用户一个提示,他们甚至可以在第一时间放下东西,我实现了一个dragover 事件来显示一个类似于“Drop Here”的div。这反过来又隐藏了具有“选择文件...”按钮的div,并替换它,直到用户停止拖动。

但似乎,当我实现这一点时,在目标区域上拖动会导致闪烁。明确一点:

  • div 显示“选择文件”界面。
  • 拖动的项目(或拖动的选定文本);显示“放在这里”。
  • 项目被拖到“放在这里”区域;开始闪烁。

另外:

  • 在 Opera 12 或 Firefox 16 中没有问题。
  • 这个问题在 Chrome 23 和 Safari 5 中非常明显。
  • 问题部分存在于 IE 9 中(IE 10 未经测试);闪烁约 5 秒钟,然后停止。

jsFiddle

(警告:小提琴非常粗糙。)

只需选择一些文本并将其拖到蓝色框上,您就会看到会发生什么;它不应该表现出的行为很明显。

小提琴中使用的代码

var $dropTarget = $("#container");
$(document).bind("dragover", function(e) {
    if ($dropTarget.hasClass("highlight"))
        return;

    $dropTarget.addClass("highlight");
    $dropTarget.find("[name='drop']").show();
    $dropTarget.find("[name='drag']").hide();
}).bind("dragleave drop", function(e) {
    if (!$dropTarget.hasClass("highlight"))
        return;

    $dropTarget.removeClass("highlight");
    $dropTarget.find("[name='drop']").hide();
    $dropTarget.find("[name='drag']").show();
});​

我的解决方案...?

说实话,我不知道该尝试什么。没有关于dragoverdragleave 行为的大量文档,我什至不知道为什么会这样,所以我什至无法开始调试它。我觉得dragover 应该只触发一次,但即使在屏幕上拖动也会一遍又一遍地触发它。

我查看了 Google 图片和 Google 通讯录中的拖放行为,但它们的代码已完全缩小且不可读,我什至找不到任何指定的“拖动”行为。

那么,对于这种看似奇怪的行为有什么解决办法吗?如果这是我怀疑的 WebKit 中的错误,是否有一些出色的解决方法和/或我可以使用的 hack?

感谢大家的宝贵时间!

【问题讨论】:

    标签: jquery drag-and-drop


    【解决方案1】:

    经过一个多小时的打磨,我找到了someone who had a similar type of issue。似乎 Chrome 和 Safari(至少 5 个)在输入子元素时触发 dragleave(并且似乎在对该元素进行任何更改时,包括显示/隐藏子元素)。

    解决方案是检查pageXpageY 是否等于0dragleave(但 drop)。

    var $dropTarget = $("#container");
    $(document).bind("dragenter", function(e) {
        if (e.target == this) {
             return;
        }
                    
        $dropTarget.addClass("highlight");
        $dropTarget.find("[name='drop']").show();
        $dropTarget.find("[name='drag']").hide();
    }).bind("dragleave", function(e) {
        if (e.originalEvent.pageX != 0 || e.originalEvent.pageY != 0) {
            return false;
        }
        
        // Could use .trigger("drop") here.
        $dropTarget.removeClass("highlight");
        $dropTarget.find("[name='drop']").hide();
        $dropTarget.find("[name='drag']").show();
    }).bind("drop", function(e) {
        $dropTarget.removeClass("highlight");
        $dropTarget.find("[name='drop']").hide();
        $dropTarget.find("[name='drag']").show();
    });​
    

    【讨论】:

    • 天啊,三连。为此,我已经在互联网上搜索了几个小时。谢谢
    • 不错!我只改了||到 && 并且工作得很好。谢谢。
    【解决方案2】:

    我有一些项目使用拖放文件,在我的项目中发现了同样的问题, 这是针对您的问题的解决方案,并在您的案例中进行了测试,这是 100% 的工作

    这是神奇的代码:

    <style type="text/css">
        .drag * {
            pointer-events: none;
        }
    </style>
    
    <div class="drag" id='container'>
    <div name='drop' style='display: none;'>DROP HERE</div>
    <div name='drag'>DRAG HERE</div>
    </div> 
    

    【讨论】:

      【解决方案3】:

      我发现使用 Eric 的解决方案,如果我在使用此解决方案后将 Win10 Google Chrome 上的屏幕拖出(到另一个窗口),它对我不起作用。将条件更改为 AND 反而起作用了。

      var $dropTarget = $("#container");
      $(document).bind("dragenter", function(e) {
          if (e.target == this) {
               return;
          }
      
          $dropTarget.addClass("highlight");
          $dropTarget.find("[name='drop']").show();
          $dropTarget.find("[name='drag']").hide();
      }).bind("dragleave", function(e) {
          if (e.originalEvent.pageX != 0 || e.originalEvent.pageY != 0) {
              return false;
          }
      
          // Could use .trigger("drop") here.
          $dropTarget.removeClass("highlight");
          $dropTarget.find("[name='drop']").hide();
          $dropTarget.find("[name='drag']").show();
      }).bind("drop", function(e) {
          $dropTarget.removeClass("highlight");
          $dropTarget.find("[name='drop']").hide();
          $dropTarget.find("[name='drag']").show();
      });​
      

      【讨论】:

      • 您可以选择您的回复、控制查找并突出显示他的整个答案。这应该被删除 - 这是他答案的精确副本。如果您认为有条件修复,请修改您的回复以反映这一点。
      猜你喜欢
      • 2014-01-07
      • 1970-01-01
      • 2017-10-14
      • 1970-01-01
      • 2020-11-19
      • 1970-01-01
      • 1970-01-01
      • 2014-10-21
      • 1970-01-01
      相关资源
      最近更新 更多