【问题标题】:on drag change stylesheets for all dropzones (file upload)为所有拖放区拖动更改样式表(文件上传)
【发布时间】:2015-01-01 15:48:15
【问题描述】:

我有多个用于在网页上上传文件的放置区

如何在将文件拖入浏览器后立即突出显示所有 dropzone 元素,以便用户知道将文件放到哪里?当一个文件被拖到其中一个放置区时,我需要添加一个额外的类来指示用户可以释放文件

更新

kurideja 为我指出了 Dragster 的正确方向

https://github.com/bensmithett/dragster

现在它几乎可以工作了:)

  • 如果您拖过一个放置区并向后拖动而不释放文件,则所有放置区都被隐藏

http://jsfiddle.net/L7v2f96z/9/

html

<div class="dropzone"></div>
<div class="dropzone"></div>

javascript

//    Add/remove class when file is dragged over the dropzone. Hover effect
$('.dropzone').dragster({
    enter : function(){
        $(this).show().addClass('hover');
    },
    leave : function(){
        $(this).hide().removeClass('hover');
    }
});

//    Show/hide dropzones until a file is dragged into the browser window. Hide dropzones after file is dropped or dragging is stopped
var w = $(window).dragster({
    enter : function(){
        $('.dropzone').show();
    },
    leave : function(){
        $('.dropzone').hide();
    }
})
//    Prevent defaults (file is openened in the browser) if user drops file outside a dropzone
.on('dragover', function(e){
    e.preventDefault();
})
.on('drop', function(e){
    e.preventDefault();
    w.trigger('dragleave');
});

css

.dropzone {
    width:200px;
    height:200px;
    background:#fff;
    display:none;
    border:2px dashed rgba(0,0,0,0.5);
    box-shadow:0 2px 5px rgba(0,0,0,0.1), inset 0 0 40px rgba(0,0,0,0.1);
    border-radius:2px;
    margin:10px;
}

.dropzone.hover {
    background:#e3e3e3;
}

【问题讨论】:

  • 你在使用 JQuery UI 吗?我之所以这么问,是因为 JQuery UI 中的拖放功能允许您突出显示一个放置区域,并且我很确定您可以将其装配为允许放置多个突出显示。 jqueryui.com/droppable
  • IE 不喜欢哪个部分?闪烁可能是由超时引起的......您可能应该将其分配给一个变量,以便如果用户仍在拖动东西但碰巧触发了您的 dragout 计时器,您可以取消它。我曾在this answer over here 做过类似的事情。

标签: javascript jquery


【解决方案1】:

主要问题是:离开放置区后,dragster 触发了leave 两次,都在.dropzonewindow 上。只需添加 e.stopPropagation() 即可解决问题。还有一些修复(删除了 dropzone Dragster 中的 show() 和 hide())。您的code on Fiddle 以及以下:

// Add/remove class when file is dragged over the dropzone. Hover effect
$('.dropzone').dragster({
    enter: function() {
        $(this).addClass('hover');
    },
    leave: function(e) {
        e.stopPropagation(); //-- Critical point
        $(this).removeClass('hover');
    }
});

// Show/hide dropzones until a file is dragged into the browser window. Hide dropzones after file is dropped or dragging is stopped
var w = $(window).dragster({
    enter: function() {
        $('.dropzone').show();
    },
    leave: function() {
        $('.dropzone').hide();
    }
})
// Prevent defaults (file is openened in the browser) if user drop file outside a dropzone
.on('dragover', function(e) {
    e.preventDefault();
})
    .on('drop', function (e) {
    e.preventDefault();
    w.trigger('dragleave');
});

【讨论】:

    【解决方案2】:

    您可以在拖动时使用e.originalEvent.pageXe.originalEvent.pageY,并检查它是否在框的范围内。对于这个例子,我已经复制了 dropzone,并且我知道 div 的宽度和高度,所以我可以对条件进行硬编码。您必须想出一种方法来存储放置区域的位置(顶部和左侧)并使用它进行比较。

    var drag_timer;
    $(document).on('dragover', function (e) {
        var dt = e.originalEvent.dataTransfer;
    
        if (dt.types && (dt.types.indexOf ? dt.types.indexOf('Files') != -1 : dt.types.contains('Files'))) {
            if (e.originalEvent.pageX <= 200 && e.originalEvent.pageY <= 200) {
                $('.dropzone').removeClass('highlight');
                $('.dropzone:eq(0)').addClass('highlight');
            } else if (e.originalEvent.pageX <= 400 && e.originalEvent.pageY <= 400) {
                $('.dropzone').removeClass('highlight');
                $('.dropzone:eq(1)').addClass('highlight');
            } else {
                $('.dropzone').removeClass('highlight');
            }
    
            $('.dropzone').show();
            window.clearTimeout(drag_timer);
        }
    })
    .on('dragleave', function (e) {
      drag_timer = window.setTimeout(function () {
        $('.dropzone').hide();
      }, 50);
    });
    

    Demo Fiddle

    【讨论】:

      【解决方案3】:

      您可以使用事件的target 成员来获取正确的元素:

      var drag_timer;
      $(document).on('dragover', function(e){
          var dt = e.originalEvent.dataTransfer;
          if(dt.types && (dt.types.indexOf ? dt.types.indexOf('Files') != -1 : dt.types.contains('Files'))){
              $('.dropzone').show();
              window.clearTimeout(drag_timer);
          }
      })
      .on('dragleave', function(e){
          drag_timer = window.setTimeout(function(){
              $('.dropzone').hide();
          }, 50);
      });
      
      $('.dropzone')
      .on('dragenter', function(e){
          $(e.originalEvent.target).addClass('highlight');
      })
      .on('dragleave', function(e){
          $(e.originalEvent.target).removeClass('highlight');
      });
      

      小提琴:http://jsfiddle.net/mzcqxfq3/

      【讨论】:

        【解决方案4】:

        在每个元素上都会触发一些拖动事件,因此基本上不是一次连续拖动,而是在鼠标下方的所有元素上进行一系列拖动。

        只要使用这个插件:http://javascript.hew.io/bensmithett/dragster

        【讨论】:

        • 不错的插件! :) 已经创建了一个 jsfiddle .. 现在我的问题是文档上的拖动器只能在您第一次拖动到 dropzone jsfiddle.net/L7v2f96z/2 之前工作
        • 已经用更新的 jsfiddle 更新了问题,我没有使用 jquery 版本的 Dragster.. :)
        【解决方案5】:

        在我的情况下,我想在我输入的那一刻改变课程的风格 一个新文件,当 dropzone 被填满时,我做了以下事情:

        .dz-drag-hover , .dz-started {        
                border: 2px solid #0CB598;
            }
        

        【讨论】:

          【解决方案6】:

          我的解决方案与您的方法非常相似。 当一个文件被拖到窗口中时,添加一个 css 类到包含所有放置区域的元素(如果需要,为正文)。然后,您可以相应地设置拖放区域的样式:

          $(document).on('dragover', function(e){
              var dt = e.originalEvent.dataTransfer;
              if(dt.types && (dt.types.indexOf ? dt.types.indexOf('Files') != -1 : dt.types.contains('Files'))){
                  $('body').addClass('dragging'); // Adding a class to the body
              }
          })
          .on('dragleave', function(e){
              $('body').removeClass('dragging')
          });
          

          css 是:

          /* style the drop-zone */
          .dropzone {
              height:200px;
              width:200px;
              display:none;
              border:2px dashed black;
          }
          
          /* show the dropzone when file is dragged into window */
          body.dragging .dropzone{
              display:block;
          }
          
          /* highlight box when hovered but only when file is dragged */
          body.dragging .dropzone:hover{
              background:gray;
          }
          

          如果这不是你想要的,请在评论中告诉我;)

          编辑 当然你必须在删除文件时删除类

          $(document).on('drop', function(event) {
              $('body').removeClass('dragging');
          }
          

          【讨论】:

          • 创建了一个 jsfiddle.. 但它似乎不起作用jsfiddle.net/co53d9jf
          • @clarkk jeah 似乎在使用拖动时未应用悬停样式。对我来说,这是意想不到的行为。我希望有一天能解决这个问题,但现在它没有多大帮助......
          【解决方案7】:
          1. dt.types.indexOf引起的IE11 bug,e.originalEvent.dataTransfer.types是ie中的一个DOMStringList对象。 所以你应该使用dt.types.contains 而不是dt.types.indexOf

          以下作品:

          var drag_timer;
          
          $(document).on('dragover', function(e) {
            var dt = e.originalEvent.dataTransfer;
            if (dt.types != null &&
                (dt.types.indexOf ? dt.types.indexOf('Files') != -1 :
                   (dt.types.contains('Files') ||
                   dt.types.contains('application/x-moz-file')))) {
              $('.dropzone').show();
              window.clearTimeout(drag_timer);
            }
          })
          .on('dragleave', function(e) {
            drag_timer = window.setTimeout(function() {
              $('.dropzone').hide();
            }, 25);
          });
          .dropzone {
            height: 100px;
            width: 100px;
            background: red;
            display: none;
          }
          <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
          <div class="dropzone"></div>

          【讨论】:

          • 我发现这条线都适用于 chrome,即和 firefox..if(dt.types &amp;&amp; (dt.types.indexOf ? dt.types.indexOf('Files') != -1 : dt.types.contains('Files'))){ ... dt.types[0] 没有意义,因为 dt.types 是一个数组或 domstringlist,如果你使用dt.types[0]你只搜索数组/domstringlist的第一项
          • 我得到了更好的解决方案并更新了我的答案。 IE 应该使用dt.types.contains 来检查类型,就像 FF 一样。
          • 这也是我在第一条评论中写的:)
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-01-26
          • 1970-01-01
          • 2011-05-14
          • 2017-08-12
          • 2013-01-27
          相关资源
          最近更新 更多