【问题标题】:jQuery-UI Droppable "out" option firing on hover悬停时触发jQuery-UI Droppable“out”选项
【发布时间】:2018-09-20 14:46:09
【问题描述】:

我使用 jQuery UI 创建了一个拖放测验。答案被拖入方框中,数组随答案更新,当按下按钮时,根据数组的内容计算分数。

如果用户希望更改他们的答案,他们可以将其从框中拖动。 droppable 'out' 选项从数组中删除内容。

但是,如果已经填充了一个框,并且将答案拖到它上面,则会触发 'out' 选项并删除数组位置的内容。

重现问题:
1. 将两个答案拖入正确的方框中(最后两个答案分别是“命令”和“行”)
2.点击“检查”按钮——它会显示你的分数是“2”(这是正确的)
3. 将您的答案之一拖到另一个答案上,然后回到原来的位置,不要松开鼠标,直到它回到原来的位置。 4. 再次点击“check”按钮——它会显示你的分数是“1”

出现问题是因为“out”选项正在注册鼠标移出任何拖过它的东西,即使它没有被拖放到它上面。

out: function(event, ui) {
     var parent = $(this).attr("id");
     var child = $(ui.draggable).attr("id");
     removefromlist(parent, child);
     $(this).removeClass("full");
}

感谢您的任何帮助。这是我的代码:

$(function() {

  var position;

  // Actions for draggable object
  $(".draggable").draggable({
    start: function() {
      // Get start position. Object will return to this if drop is rejected
      position = $(this).offset();
    }
  });

  // Actions for droppable area
  $(".droppable").droppable({
    tolerance: "intersect",
    //Event to accept a draggable when dropped on the droppable
    drop: function(event, ui) {

      // Check if the droppable already has a draggable in it.
      // If so, move the draggable back to its last position.
      if ($(this).hasClass("full")) {
        $(ui.draggable).animate({
          "left": position.left + "px",
          "top": position.top + "px"
        }, 300);
      } else {
        // Snap the draggable into position
        ui.draggable.position({ of: $(this),
          my: 'left top',
          at: 'left top'
        });
        // Add a class to flag that droppable has a draggable.
        $(this).addClass("full");
        var parent = $(this).attr("id");
        var child = $(ui.draggable).attr("id");
        addtolist(parent, child);
      }
    },

    //Event to remove a draggable when dragged outside the droppable
    out: function(event, ui) {
      var parent = $(this).attr("id");
      var child = $(ui.draggable).attr("id");
      removefromlist(parent, child);
      $(this).removeClass("full");
    }
  });



});



// NO NEED TO WORRY ABOUT ANYTHING BELOW THIS LINE //



// Keeps a list of which elements have been dropped into which position

var totalAnswers = $(".droppable").length;
var droplist = new Array;

for (var i = 0; i < totalAnswers; i++) {
  droplist.push(-1);
  console.log(droplist[i]);
}

// Add dropped elements and parents to the array
function addtolist(parent, child) {
  console.log("ADD Received: " + parent + child);

  var convertedParent = parseInt(parent.substr(4));
  //console.log(convertedParent);

  var convertedChild = parseInt(child.substr(3));
  convertedChild = (convertedChild / 10) - 5;
  //console.log(convertedChild);

  droplist[convertedParent] = convertedChild;
  console.log(convertedParent + " : " + droplist[convertedParent]);
}

// Remove elements from the array
function removefromlist(parent, child) {
  console.log("REM Received: " + parent + child);

  var convertedParent = parseInt(parent.substr(4));

  droplist[convertedParent] = -1;
  console.log(convertedParent + " : " + droplist[convertedParent]);
}

function allAnswered(questions) {
  if (questions === droplist.length) {
    document.getElementById("output").innerHTML = "All questions answered. Press the button to find out how many are correct.";
    document.getElementById("checkButton").style.visibility = 'visible';
  } else {
    var remaining = questions - droplist.length;
    document.getElementById("output").innerHTML = remaining + " more to answer";
    //document.getElementById("checkButton").style.visibility = 'hidden';
  }
}

function checkAnswers() {
  // For now, this lists the contents of the array
  console.log("CHECKING");
  var score = 0;

  for (var i = 0; i < droplist.length; i++) {
    console.log(i + " / " + droplist[i]);

    if (i === droplist[i]) {
      score++;
    }

  }
  document.getElementById("output").innerHTML = "You scored " + score;
}
.clear {
  clear: both;
}

#textarea {
  position: absolute;
  top: 450px;
}

#checkButton {
  /*visibility: hidden;*/
}

.questiontext {
  font-family: sans-serif;
  font-size: 16px;
  display: inline-block;
  line-height: 45px;
  margin-bottom: 50px;
}

/* Drag and drop objects */

.draggable {
  width: 100px;
  height: 21px;
  float: left;
  margin: 3px;
  border: 1px #ddf solid;
  position: relative;
  right: 0;
  background-color: #eee;
  cursor: move;
  text-align: center;
  font-family: sans-serif;
  font-size: 16px;
  padding-top: 4px;
  overflow: hidden;
}

.droppable {
  width: 100px;
  height: 25px;
  display: inline-block;
  border: 1px dotted #ddd;
  margin: 0 10px -10px 10px;
}

.full {
  border: #aaecff solid 1px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div id="container">
  <div class="questiontext">The operating system provides an
    <div class="droppable ui-widget-header" id="drop1"></div> which allows the user to interact with the computer.
    <div class="droppable ui-widget-header" id="drop2"></div>
    <div class="droppable ui-widget-header" id="drop3"></div> Interfaces (
    <div class="droppable ui-widget-header" id="drop4"></div>) provide a visual, user-friendly way to use the system. They are often optimised for specific
    <div class="droppable ui-widget-header" id="drop5"></div> methods, such as touchscreens which use finger gestures. Prior to this, they were typically WIMP (
    <div class="droppable ui-widget-header" id="drop6"></div>,
    <div class="droppable ui-widget-header" id="drop7"></div>,
    <div class="droppable ui-widget-header" id="drop8"></div>,
    <div class="droppable ui-widget-header" id="drop9"></div>) based.</div>
  <div class="questiontext">A
    <div class="droppable ui-widget-header" id="drop10"></div>
    <div class="droppable ui-widget-header" id="drop11"></div> Interface (CLI) is text-based. They are not as user-friendly as GUI interfaces, but use less resources, making them more efficient and powerful
  </div>
  <div class="draggable ui-widget-content" id="ans60">interface</div>
  <div class="draggable ui-widget-content" id="ans70">Graphical</div>
  <div class="draggable ui-widget-content" id="ans80">User</div>
  <div class="draggable ui-widget-content" id="ans90">GUI</div>
  <div class="draggable ui-widget-content" id="ans100">input</div>
  <div class="draggable ui-widget-content" id="ans110">Windows</div>
  <div class="draggable ui-widget-content" id="ans120">Icons</div>
  <div class="draggable ui-widget-content" id="ans130">Menu</div>
  <div class="draggable ui-widget-content" id="ans140">Pointer</div>
  <div class="draggable ui-widget-content" id="ans150">Command</div>
  <div class="draggable ui-widget-content" id="ans160">Line</div>
</div>
<div id="textarea">
  <p id="output" class="clear">Output</p>
  <button type="button" onClick="checkAnswers();" id="checkButton">Check</button>
</div>

【问题讨论】:

    标签: javascript jquery html jquery-ui jquery-ui-droppable


    【解决方案1】:

    你可以在开始事件上保存当前的id。

    $(function() {
    
      var position;
      var currentChild;
    
      // Actions for draggable object
      $(".draggable").draggable({
        start: function(event, ui) {
          // Get start position. Object will return to this if drop is rejected
          position = $(this).offset();
          var child = $(ui.draggable).attr("id");
        }
      });
    
      // Actions for droppable area
      $(".droppable").droppable({
        tolerance: "intersect",
        //Event to accept a draggable when dropped on the droppable
        drop: function(event, ui) {
    
          // Check if the droppable already has a draggable in it.
          // If so, move the draggable back to its last position.
          if ($(this).hasClass("full")) {
            $(ui.draggable).animate({
              "left": position.left + "px",
              "top": position.top + "px"
            }, 300);
          } else {
            // Snap the draggable into position
            ui.draggable.position({ of: $(this),
              my: 'left top',
              at: 'left top'
            });
            // Add a class to flag that droppable has a draggable.
            $(this).addClass("full");
            var parent = $(this).attr("id");
            var child = $(ui.draggable).attr("id");
    
              addtolist(parent, child);
    
          }
        },
    
        //Event to remove a draggable when dragged outside the droppable
        out: function(event, ui) {
          var parent = $(this).attr("id");
          var child = $(ui.draggable).attr("id");
          if (child == currentChild) {
            removefromlist(parent, child);
          }
          $(this).removeClass("full");
        }
      });
    
    
    
    });
    

    【讨论】:

    • 感谢您的贡献。但是,currentChild 的值是未定义的。虽然这克服了任何可拖动的触发任何“out”选项的问题,但当实际从父级中删除可拖动时,它不会删除数组数据。
    猜你喜欢
    • 2011-10-29
    • 2012-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多