2

我通过 theZillion ( http://thezillion.wordpress.com/2012/08/29/javascript-draggable-no-jquery/ ) 找到了这个脚本,它使 div 可拖动。我正在尝试使用此脚本按类名移动 div。而不是ID。

我有一个可以工作的事件处理程序,但在我添加脚本时没有......控制台也没有显示任何错误。关于如何使这项工作的任何想法?

这是我的代码:

function wrappmover(){
    var moveEvent = "dice-window-wrapper";
    var addClassArr= document.getElementsByClassName(moveEvent);
    for(var i=0; i<addClassArr.length; i++){
        var addClass = addClassArr[i];
        addClass.addEventListener("click", movewrapp, true);
    }       
    function movewrapp() {
        var classToMove = "dice-window-wrapper";
        var elems = document.getElementsByClassName(classToMove);
        var tzdragg = function(){
            return {
                 startMoving : function(evt){ 
                     evt = evt || window.event;
                     var posX = evt.clientX, 
                     posY = evt.clientY, 
                     a = document.getElementsByClassName(classToMove),
                     divTop = a.style.top,
                     divLeft = a.style.left;
                     divTop = divTop.replace('px','');
                     divLeft = divLeft.replace('px','');
                     var diffX = posX - divLeft, 
                     diffY = posY - divTop; 
                     document.onmousemove = function(evt){ 
                         evt = evt || window.event;
                         var posX = evt.clientX,
                         posY = evt.clientY, 
                         aX = posX - diffX,
                         aY = posY - diffY; 
                         tzdragg.move('elem',aX,aY);
                     }
                 },
                 stopMoving : function(){ 
                    document.onmousemove = function(){}
                 },
                 move : function(divid,xpos,ypos){ 
                     var a = document.getElementById(divid);
                     document.getElementById(divid).style.left = xpos + 'px';
                     document.getElementById(divid).style.top = ypos + 'px';
                 }
            }
        }();
4

1 回答 1

2

好的,所以你想在你的页面上有可拖动的元素?

看看下面的代码(这里是一个工作示例)。我希望你会发现它不言自明,但以防万一还有评论:

// Wrap the module in a self-executing anonymous function
// to avoid leaking variables into global scope:
(function (document) {
    // Enable ECMAScript 5 strict mode within this function:
    'use strict';

    // Obtain a node list of all elements that have class="draggable":
    var draggable = document.getElementsByClassName('draggable'),
        draggableCount = draggable.length, // cache the length
        i; // iterator placeholder

    // This function initializes the drag of an element where an
    // event ("mousedown") has occurred:
    function startDrag(evt) {

        // The element's position is based on its top left corner,
        // but the mouse coordinates are inside of it, so we need
        // to calculate the positioning difference:
        var diffX = evt.clientX - this.offsetLeft,
            diffY = evt.clientY - this.offsetTop,
            that = this; // "this" refers to the current element,
                         // let's keep it in cache for later use.

        // moveAlong places the current element (referenced by "that")
        // according to the current cursor position:
        function moveAlong(evt) {
            that.style.left = (evt.clientX - diffX) + 'px';
            that.style.top = (evt.clientY - diffY) + 'px';
        }

        // stopDrag removes event listeners from the element,
        // thus stopping the drag:
        function stopDrag() {
            document.removeEventListener('mousemove', moveAlong);
            document.removeEventListener('mouseup', stopDrag);
        }

        document.addEventListener('mouseup', stopDrag);
        document.addEventListener('mousemove', moveAlong);
    }

    // Now that all the variables and functions are created,
    // we can go on and make the elements draggable by assigning
    // a "startDrag" function to a "mousedown" event that occurs
    // on those elements:
    for (i = 0; i < draggableCount; i += 1) {
        draggable[i].addEventListener('mousedown', startDrag);
    }
}(document));

将其加载或包装在尽可能接近<script></script>的标签中,以免阻止浏览器获取其他资源。 </body>

实际上,如果您删除评论,这是一个非常小的功能。比您提供的网站上的那个更小、更高效。

可能的改进

考虑用CSS 选择器makeDraggable(selector);在哪里替换匿名包装器,这样你就可以做一些疯狂的事情,比如:selector

makeDraggable('#dragMe, #dragMeToo, .draggable, li:nth-child(2n+1)');

它可以通过使用document.querySelectorAll能够执行复杂的 CSS 查询而不是简单的类名查找来实现document.getElementsByClassName

需要注意的事项

  • 如果页面有任何滚动 - 拖动看起来会损坏;考虑通过scrollX和scrollY调整被拖动元素的定位
  • 这显然在 Internet Explorer 中不起作用(自己弄清楚)。
  • 可能存在内存泄漏(需要分析和测试)。

编辑:添加新的可拖动元素的解决方案

所以你希望能够添加更多的可拖动元素?有几种方法可以解决这个问题。例如,您可以编写一个makeDraggable(element);函数并在要添加到 DOM 的元素上调用它。它当然会起作用,但是让我们看看不同的东西,好吗?

与其在 DOM 中搜索可拖动元素并为其分配事件侦听器,不如为文档正文上的“mousedown”事件分配一个

触发时,事件对象将包含对目标元素的引用,该元素是已调度事件的对象(您鼠标按下的元素)。代码的相关部分现在将类似于:

// Performs a check if the current element is draggable and if yes,
// then the dragging is initiated:
function startDragIfDraggable(evt) {
    // Check if the target element (referenced by evt.target) contains a
    // class named "draggable" (http://stackoverflow.com/questions/5898656/):
    if (evt.target.classList.contains('draggable')) {
        // Invoke startDrag by passing it the target element as "this":
        startDrag.call(evt.target, evt);
    }
}

// Listen for any "mousedown" event on the document.body and attempt dragging
// the target element (the one where "mousedown" occurred) if it's draggable:
document.body.addEventListener('mousedown', startDragIfDraggable);

这是上述代码的一个工作示例。作为奖励,它具有向 DOM 添加新的可拖动元素的模拟。

除了能够拖动动态添加的可拖动元素之外,这种方法还可以为我们节省一些内存,因为我们现在可以避免将一堆事件监听器分配给一堆元素。但是,如果您正在开发的应用程序是点击密集型应用程序(例如游戏),那么您可能会因为每次点击都进行检查而浪费一点 CPU。

于 2013-02-05T00:49:59.983 回答