代码之家  ›  专栏  ›  技术社区  ›  Peter Smartt

dragStart事件中未设置DataTransfer对象

  •  3
  • Peter Smartt  · 技术社区  · 10 年前

    我正在尝试在文章调度系统中实现drag-n-drop来更改日期。我希望用户能够将文章条目从一个日期拖到另一个日期,然后自动更新时间表。这是我的代码:

    <script type="text/javascript">
        $(function () {
            $(".scheduledArticleRow").draggable({
                cursor: "move",
                cursorAt: { top: -12, left: -20 },
                opacity: 0.5,
                helper: function (event) {
                    return $("<div class='ui-widget-header'>" + $(this).data('title') + "</div>")
                }
            });
            $(".articleNeededRow").droppable();
            $(".reservedDateRow").droppable();
    
            $(".scheduledArticleRow").off("dragstart").on("dragstart", function (e) {
                console.log("dragstart");
                e.dataTransfer.setData("articleId", $(this).data("articleId"));    // Uncaught TypeError: Cannot call method 'setData' of undefined 
                e.dataTransfer.setData("oldDate", $(this).data("date"));        // Uncaught TypeError: Cannot call method 'setData' of undefined
                e.originalEvent.dataTransfer.setData("articleId", $(this).data("articleId"));    // Uncaught TypeError: Cannot call method 'setData' of undefined 
                e.originalEvent.dataTransfer.setData("oldDate", $(this).data("date"));            // Uncaught TypeError: Cannot call method 'setData' of undefined
            });
            $(".articleNeededRow").off("drop").on('drop', function (e) {
                console.log("drop");
                e.preventDefault();
                e.stopPropagation();
                changeScheduledDate(e);
            });
            $(".reservedDateRow").off("drop").on('drop', function (e) {
                console.log("drop");
                e.preventDefault();
                e.stopPropagation();
                changeScheduledDate(e);
            });
        });
    
        function changeScheduledDate(e) {
            debugger;
            var articleId = e.dataTransfer.getData("articleId");    // Uncaught TypeError: Cannot call method 'setData' of undefined 
            var oldDate = e.dataTransfer.getData("oldDate");        // Uncaught TypeError: Cannot call method 'setData' of undefined
            articleId = e.originalEvent.dataTransfer.getData("articleId", $(this).data("articleId"));    // Uncaught TypeError: Cannot call method 'setData' of undefined 
            oldDate = e.originalEvent.dataTransfer.getData("oldDate", $(this).data("date"));            // Uncaught TypeError: Cannot call method 'setData' of undefined
    
            var newDate = $(this).parents(".tr").data("date");
    
            // Do date-change stuff
        }
    
    
    </script>
    
    <div class="table tidytable" width="90%">
        <div class="thead">
            <div class="cell">Date</div>
            <div class="cell">Article title</div>
        </div>
        <div class="tbody" id="scheduleBody">
            <div class="tr articleNeededRow" data-date="2014-02-11">
                <div class="cell"><strong>Tue, 11th Feb</strong></div>
                <div class="cell articleNeeded">Article needed.</div>
            </div>
            <div class="tr articleNeededRow" data-date="2014-02-12">
                <div class="cell"><strong>Wed, 12th Feb</strong></div>
                <div class="cell articleNeeded">Article needed.</div>
            </div>
            <div class="tr reservedDateRow" data-date="2014-02-13">
                <div class="cell"><strong>Thu, 13th Feb</strong></div>
                <div class="cell articleNeeded"><strong>Reserved for an upcoming article.</strong></div>
            </div>
            <div class="tr scheduledArticleRow" data-date="2014-02-14" data-articleid="8789" data-title="This is the title"
                draggable="true">
                <div class="cell"><strong>Fri, 14th Feb</strong></div>
                <div class="cell">
                    <h3>This is the title</h3>
                </div>
            </div>
        </div>
    </div>
    

    我正在使用.css表。用户应该能够从“这是标题”行中的任何位置拖动到任何其他行。但是在dragStart事件处理程序中,e.dataTransfer设置为null,不可能将任何数据传递到drop事件。我不想求助于cookie、HTML5本地存储或全局变量——这件事应该会奏效。我让它使用dataTransfer在应用程序的其他部分运行得很好。一些帖子建议我需要使用e.originalEvent.dataTransfer,但这也是空的。我正在使用谷歌Chrome BTW。我创建了一个jsFiddle- http://jsfiddle.net/btA97/ -非常感谢任何帮助。

    2 回复  |  直到 10 年前
        1
  •  5
  •   Kai    10 年前

    您的.draggable()似乎做错了什么。你还需要 e.preventDefault() e.stopPropagation() 以确保发生跌落。

    此代码可正确获取所有事件:

       $(function () {
           /*
           $(".scheduledArticleRow").draggable({
               cursor: "move",
               cursorAt: {
                   top: -12,
                   left: -20
               },
               opacity: 0.5,
               helper: function (event) {
                   return $("<div class='ui-widget-header'>" + $(this).data('title') + "</div>")
               }
           });
            */
    
           $(".articleNeededRow").droppable(); // With this commented out the code still works
           $(".reservedDateRow").droppable(); // This one too
    
           $(".scheduledArticleRow").on("dragstart", function (e) {
               console.log("dragstart");
               console.dir(e);
               e.originalEvent.dataTransfer.setData("articleId", $(this).data("articleId"))
               e.originalEvent.dataTransfer.setData("oldDate", $(this).data("date"));
           });
           $(".articleNeededRow").on('dragover', function (e) {
               console.log("dragover");
               e.preventDefault();
               e.stopPropagation();
           });
           $(".articleNeededRow").on('drop', function (e) {
               console.log("drop");
               e.preventDefault();
               e.stopPropagation();
               changeScheduledDate(e);
           });
           $(".reservedDateRow").on('dragover', function (e) {
               console.log("dragover");
               e.preventDefault();
               e.stopPropagation();
           });
           $(".reservedDateRow").on('drop', function (e) {
               console.log("drop");
               e.preventDefault();
               e.stopPropagation();
               changeScheduledDate(e);
           });
       });
    
       function changeScheduledDate(e) {
           articleId = e.originalEvent.dataTransfer.getData("articleId");
           oldDate = e.originalEvent.dataTransfer.getData("oldDate");
           console.log("articleID: "+articleId);
           console.log("oldDate: "+oldDate);
    
           var newDate = $(this).parents(".tr").data("date");
           console.log("newDate: "+newDate);
    
           // Do date-change stuff
       }
    
        2
  •  2
  •   Alex Golovin    6 年前

    需要使用event.originalEvent对象。