2

我在使用 jQuery animate 为某些 div 设置位置的函数时遇到了一些问题。我用 jQuery 做了一个测验,并希望正确的“已回答”具有数字 id 的可拖动 div 自动转到具有相同 id 的目标位置 div。这是用于导航(每次只显示 12 个问题)。

html看起来像这样

<div id="container"> //floats left
    <div class="answer" id="1"></div> //droppables
    <div class="answer" id="2"></div>
    <div class="answer" id="3"></div>
    <div class="answer" id="4"></div>
    <div class="answer" id="5"></div>
    <div class="answer" id="6"></div>
    <div class="answer" id="7"></div>
    <div class="answer" id="8"></div>
    <div class="answer" id="9"></div>
    <div class="answer" id="10"></div>
    <div class="answer" id="11"></div>
    <div class="answer" id="12"></div>
</div>
<div id="container>
    <div class="drag" id="3"></div> //draggables are in random order
    <div class="drag" id="1"></div>
    <div class="drag" id="2"></div>
    <div class="drag" id="6"></div>
    <div class="drag" id="5"></div>
    <div class="drag" id="12"></div>
    <div class="drag" id="4"></div>
    <div class="drag" id="8"></div>
    <div class="drag" id="7"></div>
    <div class="drag" id="11"></div>
    <div class="drag" id="9"></div>
    <div class="drag" id="10"></div>
</div>

每次有人将右边的可拖动对象放在右边的 droppable 上时,id 都会存储在一个名为 的数组中rightIds

可以说 rightIds 是array(0=>3, 1=>7 2=>9)

我还有一个名为的数组currentIds,其中包含现在显示的 id。 currentIds就是现在array(0=>1 to 11=>12)

我做了这个功能:

function resetAnimation(currentIds, rightIds) {
    $.each(currentIds, function (index, value) {
        $.each(rightIds, function(ind, val) {
        console.log('currentIds value: ' + value);
        console.log('rightIds val: ' + val);
        if (val == value) {
            var target = $('#' + value + '.answer');
            console.log(target);
            var targetTop = target.offset().top;
            console.log('targetTop: ' + targetTop);
            var targetLeft = target.offset().left;
            console.log('targetLeft: ' + targetLeft);
            var drag = $('#' + value + '.drag');
            console.log(drag);
            var dragTop = drag.offset().top;
            console.log('dragTop: ' + dragTop);
            var dragLeft = drag.offset().left;
            console.log('dragLeft: ' + dragLeft);
            drag.animate({
                'top': -target.offset().top,
                    'left': -target.offset().left
            }, 3000);
        }
    });
});
}

但是当我运行它时,拖动 div 不会到目标位置,而是到其他位置。当我检查动画元素时,偏移量与目标偏移量相同,只是在值之前有一个“-”。我希望有人能告诉我我做错了什么以及如何解决这个问题。

谢谢

4

3 回答 3

1

在您的代码中,如果您的拖动元素位于同一个偏移父项中,并且两者都是绝对定位的,则应该像替换一样简单:

drag.animate({
  'top': -target.offset().top,
  'left': -target.offset().left
}, 3000);

和:

drag.animate({
  'top': target.offset().top,
  'left': target.offset().left
}, 3000);

如果它不是绝对定位,那么它与设置偏移不太一样,jQuery 足够聪明地计算出正确的相对定位,但 animate 不使用相同的功能。如果失败,您可以使用:

$drag.animate(
    { top: $target.position().top - $drag.position().top
    , left: $target.position().left - $drag.position().left }, 3000);

示例用法

版本 1 - jQuery 匹配

HTML 已更新,使其按照nnnnnn的正确建议有效(没有重复的 id):

<div class="container">
    <div class="answer" id="answer-1"></div>
    <div class="answer" id="answer-2"></div>
    <div class="answer" id="answer-3"></div>
    <div class="answer" id="answer-4"></div>
    <div class="answer" id="answer-5"></div>
    <div class="answer" id="answer-6"></div>
    <div class="answer" id="answer-7"></div>
    <div class="answer" id="answer-8"></div>
    <div class="answer" id="answer-9"></div>
    <div class="answer" id="answer-10"></div>
    <div class="answer" id="answer-11"></div>
    <div class="answer" id="answer-12"></div>
</div>
<div class="container">
    <div class="drag" id="drag-3"></div>
    <div class="drag" id="drag-1"></div>
    <div class="drag" id="drag-2"></div>
    <div class="drag" id="drag-6"></div>
    <div class="drag" id="drag-5"></div>
    <div class="drag" id="drag-12"></div>
    <div class="drag" id="drag-4"></div>
    <div class="drag" id="drag-8"></div>
    <div class="drag" id="drag-7"></div>
    <div class="drag" id="drag-11"></div>
    <div class="drag" id="drag-9"></div>
    <div class="drag" id="drag-10"></div>
</div>
<div>
    <a id="get-answers">Get answers</a>
</div>

有了这个,可以简化 JavaScript 以匹配 drag-[id] 到 answer-[id] 并使用position jQuery 方法将拖动元素移动到正确的位置:

// Animates right answered draggables 
// to the right answers
function resetAnimation() {

    // Iterate over all of the drag elements
    $(".drag").each(function() {

        var $drag = $(this)

            // Get the id of the drag element
            // by dropping "drag-" off the front
          , id = $drag.attr("id").replace("drag-", "")

            // Find the matching answer
          , $target = $('#answer-' + id);

        // The animation code, position gives
        // the coordinates of the element relative
        // to the offset parent, subtract the original
        // position from the target position to get the
        // correct translation deltas
        $drag.animate(
            { top: $target.position().top - $drag.position().top
            , left: $target.position().left - $drag.position().left}, 3000);
    });
}

$(function() {
    $("#get-answers").click(resetAnimation);
});

版本 2 - 数组匹配

如果您确实想坚持使用数组来支持它(我会使用对象文字并将数字视为字符串 id),则对代码的修改如下:

// Animates right answered draggables 
// to the right answers
function resetAnimation(answered, correct) {

    // Iterate over all of the drag elements
    for(var id in answered) {

        if(answered[id] !== correct[id]) {

            var $drag = $("#drag-" + id)

                // Find the matching answer
              , $target = $('#answer-' + correct[id]);

            // The animation code, position gives
            // the coordinates of the element relative
            // to the offset parent, subtract the original
            // position from the target position to get the
            // correct translation deltas
            $drag.animate(
                { top: $target.position().top - $drag.position().top
                , left: $target.position().left - $drag.position().left}, 3000);

        }

    }
}

$(function() {
    $("#get-answers").click(function() {
        resetAnimation({
            "1" : "3",
            "2" : "2",
            "3" : "1"
        }, {
            "1" : "2",
            "2" : "3",
            "3" : "1"
        });
    });
});

我用于这些测试用例的 CSS:

.answer { 
    float: left; 
    margin: 10px; 
    background: red; 
    width: 20px; 
    height: 20px;
}
.drag { 
    position: relative;
    float: left; 
    margin: 10px; 
    background: green; 
    width: 20px; 
    height: 20px; 
}
.container { 
    float: left;
    width: 100%;
}

这是一个小提琴

于 2013-05-17T12:33:53.547 回答
0

您可以使用 css 类不仅可以赋予样式,还可以指定元素。

你可以做类似的事情

<div class="answer" id="answer-2" class="answer q2"></div>
<div class="answer" id="answer-3" class="answer q3"></div>
...
<div class="drag" id="question-2" class="q2"></div>
<div class="drag" id="question-6" class="q6"></div>

现在,您可以使用他们的类匹配问题和答案。例如,对于每个问题,获取班级var myClass = $(this).prop('class');并找到匹配的答案$("div.answer."+myClass);

于 2013-05-17T12:09:57.720 回答
0

我会使用 jQuery 用于测试的模拟插件来“模拟”拖放;

https://github.com/jquery/jquery-ui

一些使用示例实际上可以在测试中查看:

https://github.com/jquery/jquery-ui/blob/master/tests/unit/draggable/draggable_core.js

https://github.com/jquery/jquery-ui/blob/master/tests/unit/draggable/draggable_events.js

于 2013-05-17T13:45:12.050 回答