2013-08-22 23 views
10

我目前正在建設一個網站設計師,其中一個核心功能是能夠拖動&下拉來重新排列元素。我一直在努力研究這個功能幾天,並且已經解散了幾次。最重要的這個拖放系統是拖能夠元件可以在任何地方的容器內下降,這將卡入到位所以不會有絕對定位的元素否則元素贏得了」 t 卡入到位可以在所有可能的地方掉落

因此,我首先構建了可拖動元素的核心可拖動位,然後當您放下元素時,我使用document.elementFromPoint()來獲取光標位置所在的元素(注意:我必須隱藏可拖動的元素,否則它將返回)。

現在我有最接近光標的元素,主要問題是確定可拖動元素需要相對於該元素的位置,因爲有4個選項append - prepend - insertBefore - insertAfter。我已經設法得到append - prepend & insertBefore的工作,但它不夠可靠,因爲我要使用目標的高度和偏移量來確定append or prepend,並且我正在增加Y參數getFromPoint以查看我是否擊中了另一個元素短距離確定insertBefore。這是我迄今爲止的代碼。

box.addEventListener('mouseup', function (e) { 
    if (!dragging) return; 
    dragging = false; 
    var thisEl = this; // the drag-able element 

    // Hide 
    this.style.display = 'none'; // hide the element so we can get 
           // document.elementFromPoint 

    var el = document.elementFromPoint(e.pageX, e.pageY), // target 
     elH = el.offsetHeight, // height of target 
     elT = el.offsetTop; // offset of target 

    for (var i = 0; i < 15; i++) { // This is a weird part see the reference at the bottom 
     var newEl = document.elementFromPoint(e.pageX, e.pageY + i); 
     if (newEl !== el) { 
      this.style.display = 'block'; 
      this.style.position = 'static'; 
      return newEl.parentNode.insertBefore(thisEl, newEl); 
     } 
    } 

    if (e.pageY < elT + (elH/2)) { // if the pageY is less than the target offset + half of the height, that's how I am calculating prepend 
     el.appendChild(this); 
     el.insertBefore(this, el.firstChild); 
    } else { 
     el.appendChild(this); // else append; 
    } 

    this.style.display = 'block'; 
    this.style.position = 'static'; // Snap back in with 'static' 
}); 

這只是我的mouseup事件,一個做所有的工作。其他事件只是使元素可拖動,並不重要。

這裏是一個小提琴

http://jsfiddle.net/mLX5A/2/

因此,如果未那麼問題這裏有一個短版。

我的可拖拽元素需要能夠在任何地方放下並卡入。這樣做的最好方法是什麼,因爲我在小提琴中完成它的方式絕對不好。我如何檢測元素需要在mouseup上相對於目標的位置。

引用奇怪的部分。

下面是它如何工作(警告這不是好) 當我到達目標元素與elementFromPoint我再創建一個循環 是將循環15次,並增加了Y值進入elementFromPoint所以基本上elementFromPoint移動down 15px,如果它在該短空間內遇到新元素,我假設你不想在目標之前插入元素。

我非常樂意接受與此代碼無關的答案,因爲這也會讓其他用戶受益。

如果你覺得這篇文章很長並且令人困惑,那不是因爲我一直在這裏呆了幾天,它把我的頭擰了起來,讓我瘋了。

我想說明一下,可以拖拽的容器是設計師的主要部分。所以對我來說這不是一種選擇,我擁有所有絕對定位的元素,並且我不是一個將元素放在每個可能位置的好主意,這樣我就可以檢測到可拖動元素必須去的位置,因爲無論在哪裏該容器將是一個沒有不必要內容的高質量結果。

我也想指出,我的應用程序不會永遠支持老的瀏覽器,即IE6,IE7,IE8,IE9

+0

只是一般的問題:你避免像jQuery框架以任何理由?或者這是否必須是純JS? – Hless

+1

@Hless在我的項目中,我使用angular.js和jQlite。 jQuery的口號是***寫少,做得更好***這個問題不是代碼的數量,它是如何做到這一點。我的意思是,我用jQuery的答案很好,因爲一旦我看到答案的重點是什麼,那麼我將沒有問題寫在香草 – iConnor

+0

我看到你的代碼中有
,但沒有塊。這將是非常痛苦的處理。我會試着去看看我能做些什麼,但是,你需要一個「快照」效果還是我們可以使用絕對定位? – TecHunter

回答

3

ChaseMoskal具有使用CONTENTEDITABLE = 「真」 一個很好的解決問題的辦法:

HTML

<!--==== DragonDrop Demo HTML 
Here we have two contenteditable <div>'s -- they have a dashed bottom-border dividing them, and they contain various text content. The first <div> contains structured block content, and the second <div> contains Unstructured, unwrapped content. 
====--> 

<div contenteditable="true"> 
    <h1>Athenagora Lenoni Incommunicabile: Structured Content</h1> 
    <h2>Cellam modico illius ergo accipiet si non ait est Apollonius.</h2> 

    <a class="fancy"> 
     <img src="http://imageshack.us/scaled/landing/809/picture195z.jpg" /> 
     <caption>Hola!</caption> 
    </a> 

    <p>Volvitur ingreditur lavare propter increparet videns mihi cum. Tharsis ratio puella est Apollonius in deinde plectrum anni ipsa codicellos, jesus Circumdat flante vestibus lumine restat paralyticus audi anim igitur patriam Dianae. 'Iuraveras magnifice ex quae ad per te sed dominum sit Mariae Bone de his carpens introivit filiam. Plus damna nautis unum ad te. Puto suam ad quia iuvenis omnia. Etiam quantitas devenit regi adhibitis sedens loculum inveni.</p> 
</div> 

<div contenteditable="true"> 
    <strong>Unstructured Content:</strong> Toto determinata se est se ad te finis laeta gavisus, laetare quod una non ait mea ego dum est Apollonius. Intrarem puella est in deinde cupis ei Taliarchum in, tharsiam vis interrogat Verena est Apollonius eius ad suis. Antiochus ac esse more filiam sunt forma ait Cumque persequatur sic. Imas rebum accusam in fuerat est se sed esse ait Cumque ego. Secundis sacerdotem habemus ibi alteri ad quia, agere videre Proicite a civitas exulto haec. Supponite facultatibus actum dixit eos. Neminem habere litore in deinde duas formis. Quattuordecim anulum ad nomine Hesterna studiis ascende meae puer ut sua, eiusdem ordo quos annorum afferte Apollonius non ait in. 
    <br /><br /> 
    Deducitur potest contremiscunt eum ego Pentapolim Cyrenaeorum tertia navigavit volente in fuerat eum istam vero cum obiectum invidunt cum. Christe in rei sensibilium iussit sed, scitote si quod ait Cumque persequatur sic. Amet consensit cellula filia in rei civibus laude clamaverunt donavit potest flens non solutionem innocentem si quod ait. Una Christi sanguine concomitatur quia quod non coepit, volvitur ingreditur est Apollonius eius non potentiae. Coepit cenam inhaeret Visceribusque esocem manibus modi regiam iriure dolore. Filiam in rei finibus veteres hoc ambulare manu in fuerat eum istam provoces. 
</div> 

<button name="toggleContentEditable">disable contenteditable</button> 

CSS

/*====== DragonDrop Demo CSS 
Basically, user-select, and user-drag (and all their prefixes) need to be set in a way that lets the browser know which parts of our draggable element are selectable and draggable and which aren't. 
    So I guess this is that. 
        ======*/ 
@charset utf-8; 

/* these rules only apply to fancy boxes when contenteditable is true: they are necessary for the drag-and-drop demo to work correctly */ 
[contenteditable="true"] .fancy { 
    /**/-moz-user-select:none;-webkit-user-select:none; 
    user-select:none; /* without this line, element can be dragged within itself! No-no! */ 
    /**/-moz-user-drag:element;-webkit-user-drag:element; 
    user-drag:element; /* makes the whole fancy box draggable */ 
    cursor:move !important; } /* switches to the move cursor */ 
    [contenteditable="true"] .fancy * { 
     /**/-moz-user-drag:none;-webkit-user-drag:none; 
     user-drag:none; } /* hopefully disables the internal default dragging of the img */ 



/*======  Everything below this area 
       is STRICLY for STYLE 
       and VISUAL APPEAL. 
       It shouldn't concern you. ======*/ 

html,body{ height:100%; } 
[contenteditable] { 
    background:#f8f8f8; box-sizing:border-box; padding:2%; min-height:auto; 
    font-size:10px; font-family:sans-serif; color:#444; 
    border-bottom:2px dashed #888; } 
    .fancy { 
     display:inline-block; margin:10px; 
     color:#444; text-align:center; font-style:italic; 
     font-size:10px; font-family:sans-serif; 
     background:#fff; border:8px solid white; 
     box-shadow:1px 2px 8px #444; 
     cursor:pointer; } 
     .fancy img { 
      display:block; margin-bottom:2px; 
      border:1px solid white; 
      box-shadow:0 1px 6px #888; } 
     .fancy .caption { max-width:100px; } 
    h1 { font-weight:bold; font-size:1.4em; } 
    h2 { font-weight:bold; font-style:italic; text-indent:2px; } 
    p { text-indent:8px; } 
    strong { font-weight:bold; } 
button { display:block; margin:6px auto; } 

的Javascript

/* 

==== Dragon Drop: a demo of precise DnD 
      in, around, and between 
     multiple contenteditable's. 

================================= 
== MIT Licensed for all to use == 
================================= 
Copyright (C) 2013 Chase Moskal 

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
============ 

*/ 

function DRAGON_DROP (o) { 
    var DD=this; 

    // "o" params: 
    DD.$draggables=null; 
    DD.$dropzones=null; 
    DD.$noDrags=null; // optional 

    DD.dropLoad=null; 
    DD.engage=function(o){ 
     DD.$draggables = $(o.draggables); 
     DD.$dropzones = $(o.dropzones); 
     DD.$draggables.attr('draggable','true'); 
     DD.$noDrags = (o.noDrags) ? $(o.noDrags) : $(); 
     DD.$dropzones.attr('dropzone','copy'); 
     DD.bindDraggables(); 
     DD.bindDropzones(); 
    }; 
    DD.bindDraggables=function(){ 
     DD.$draggables = $(DD.$draggables.selector); // reselecting 
     DD.$noDrags = $(DD.$noDrags.selector); 
     DD.$noDrags.attr('draggable','false'); 
     DD.$draggables.off('dragstart').on('dragstart',function(event){ 
      var e=event.originalEvent; 
      $(e.target).removeAttr('dragged'); 
      var dt=e.dataTransfer, 
       content=e.target.outerHTML; 
      var is_draggable = DD.$draggables.is(e.target); 
      if (is_draggable) { 
       dt.effectAllowed = 'copy'; 
       dt.setData('text/plain',' '); 
       DD.dropLoad=content; 
       $(e.target).attr('dragged','dragged'); 
      } 
     }); 
    }; 
    DD.bindDropzones=function(){ 
     DD.$dropzones = $(DD.$dropzones.selector); // reselecting 
     DD.$dropzones.off('dragleave').on('dragleave',function(event){ 
      var e=event.originalEvent; 

      var dt=e.dataTransfer; 
      var relatedTarget_is_dropzone = DD.$dropzones.is(e.relatedTarget); 
      var relatedTarget_within_dropzone = DD.$dropzones.has(e.relatedTarget).length>0; 
      var acceptable = relatedTarget_is_dropzone||relatedTarget_within_dropzone; 
      if (!acceptable) { 
       dt.dropEffect='none'; 
       dt.effectAllowed='null'; 
      } 
     }); 
     DD.$dropzones.off('drop').on('drop',function(event){ 
      var e=event.originalEvent; 

      if (!DD.dropLoad) return false; 
      var range=null; 
      if (document.caretRangeFromPoint) { // Chrome 
       range=document.caretRangeFromPoint(e.clientX,e.clientY); 
      } 
      else if (e.rangeParent) { // Firefox 
       range=document.createRange(); range.setStart(e.rangeParent,e.rangeOffset); 
      } 
      var sel = window.getSelection(); 
      sel.removeAllRanges(); sel.addRange(range); 

      $(sel.anchorNode).closest(DD.$dropzones.selector).get(0).focus(); // essential 
      document.execCommand('insertHTML',false,'<param name="dragonDropMarker" />'+DD.dropLoad); 
      sel.removeAllRanges(); 

      // verification with dragonDropMarker 
      var $DDM=$('param[name="dragonDropMarker"]'); 
      var insertSuccess = $DDM.length>0; 
      if (insertSuccess) { 
       $(DD.$draggables.selector).filter('[dragged]').remove(); 
       $DDM.remove(); 
      } 

      DD.dropLoad=null; 
      DD.bindDraggables(); 
      e.preventDefault(); 
     }); 
    }; 
    DD.disengage=function(){ 
     DD.$draggables=$(DD.$draggables.selector); // reselections 
     DD.$dropzones=$(DD.$dropzones.selector); 
     DD.$noDrags=$(DD.$noDrags.selector); 
     DD.$draggables.removeAttr('draggable').removeAttr('dragged').off('dragstart'); 
     DD.$noDrags.removeAttr('draggable'); 
     DD.$dropzones.removeAttr('droppable').off('dragenter'); 
     DD.$dropzones.off('drop'); 
    }; 
    if (o) DD.engage(o); 
} 



$(function(){ 

    window.DragonDrop = new DRAGON_DROP({ 
     draggables:$('.fancy'), 
     dropzones:$('[contenteditable]'), 
     noDrags:$('.fancy img') 
    }); 

    // This is just the enable/disable contenteditable button at the bottom of the page. 
    $('button[name="toggleContentEditable"]').click(function(){ 
     var button=this; 
     $('[contenteditable]').each(function(){ 
      if ($(this).attr('contenteditable')==='true') { 
       $(this).attr('contenteditable','false'); 
       $(button).html('enable contenteditable'); 
      } else { 
       $(this).attr('contenteditable','true'); 
       $(button).html('disable contenteditable'); 
      } 
     }); 
    }); 

}); 

小提琴:

http://jsfiddle.net/ChaseMoskal/T2zHQ/

+0

很酷,我剛剛檢查過。我只看了它幾分鐘,第一次放置它後拖拽能力看起來有點小錯誤,但這是可以預料的,因爲我不是要求任何人的代碼。我會在一分鐘內好好看看並回復你。這可能是最好的答案。也許。 – iConnor

+0

當我無意中發現了Chase的這種不同的方法時,我正在處理你的代碼。似乎要走的路,因爲它還允許用戶將圖像放置在文本節點內的特定點處。結果與我們在文字處理和桌面出版所見即所得的應用程序中所獲得的結果更接近,與我們之前的方法相比。 –

+0

非常感謝您,這是一個非常有效的解決方案,我將重新編寫它,但至少我有這個想法。在你回答之前,我開始放棄希望。 – iConnor

-1

匹諾曹,我建議你創造一些在放下之前預覽可拖拽的設計(一個新的onmouseover/mouseenter預覽),我可以幫助你解決你的問題。我也會放棄使用getFromPoint(用於交叉瀏覽支持),而不是使用JQuery mouseenter/mouseleave來爲mouseup/drop分配懸停元素的時間。

通過將懸停元素放置在相對於文檔的位置(jQquery.position)中,您可以以某種方式基於光標位置進行計算,以便添加或預先添加元素。

希望它可以幫助

+0

好的,謝謝你的回答。我並不擔心瀏覽器支持,但無論如何'elementFromPoint'在** IE5 + FF3 + **中都受支持,並且我不太瞭解您的觀點。 :) – iConnor

+0

@Pinocchio alrighty,至極? –

+4

我不明白這是如何回答這個問題的。 – iConnor

8

我會考慮使用jQuery UI的Sortable widgetportlets example處理insertBeforeinsertAfter要求。我創建了一個基於Portlet示例的簡單的fiddle,並且還滿足prependappend的要求。

這只是您的一個開始,我相信您可以根據需要操作。 connectWith是重要的,取決於你想放置東西的地方。

Fiddle

JS

$(".column").sortable({ 
    items: ".portlet", 
    connectWith: ".column" 
}); 
$(".portlet").sortable({ 
    items: ".portlet-content", 
    connectWith: ".portlet" 
}); 
$(".column").disableSelection(); 

HTML

<div class="column"> 
    <div class="portlet ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"> 
     <div class="portlet-content">One. Lorem ipsum dolor sit amet, consectetuer adipiscing elit</div> 
    </div> 
    <div class="portlet ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"> 
     <div class="portlet-content">Two. Lorem ipsum dolor sit amet, consectetuer adipiscing elit</div> 
    </div> 
    <div class="portlet ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"> 
     <div class="portlet-content">Three. Lorem ipsum dolor sit amet, consectetuer adipiscing elit</div> 
    </div> 
</div> 
<div class="column"> 
    <div class="portlet ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"> 
     <div class="portlet-content">Four. Lorem ipsum dolor sit amet, consectetuer adipiscing elit</div> 
    </div> 
    <div class="portlet ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"> 
     <div class="portlet-content">Five. Lorem ipsum dolor sit amet, consectetuer adipiscing elit</div> 
    </div> 
</div> 
+2

感謝您的回答,這是一種可能性,但是當我在評論中說我不介意jQuery的答案,因爲我可以在香草中重新編寫它,我並不是說我很樂意重新編寫**' 1278 ** ** jQuery的線條 – iConnor

+1

@Pinocchio是的,我可以理解。我很猶豫提供這個答案,但在看到我必須提供的jqUI有多簡單之後。我相信別人可以提供一個更好,更無bug的普通JS解決方案,如果這500個賞金對他們來說足夠誘惑的話,那麼我可以提供一個更好的無bug純JS解決方案;-) – ryan

+0

感謝您的理解,我當然希望如此。我不誠實地認爲我會得到任何解決JS問題的答案,但是我們還有4天時間,我們只能拭目以待。再次感謝您的回答。 – iConnor

2

我試圖做我知道的事情。

<div class="container"> 
    <div id="box"></div> 
    <div class="draggable"> alsdf dsalf asdfsadf 
    dsaf sadfldsaf sadkf sadlfsadf 
    asdf safdsafdksadf sadf lasldkfjsaldf safdsa 
    dfsadflsadf asdlfsafdsafdsa 
    fsafdsadf safdls 
    </div> 
    <div class="draggable"> alsdf dsalf asdfsadf 
    dsaf sadfldsaf sadkf sadlfsadf 
    asdf safdsafdksadf sadf lasldkfjsaldf safdsa 
    dfsadflsadf asdlfsafdsafdsa 
    fsafdsadf safdls 
    </div> 
    <div class="draggable"> alsdf dsalf asdfsadf 
    dsaf sadfldsaf sadkf sadlfsadf 
    asdf safdsafdksadf sadf lasldkfjsaldf safdsa 
    dfsadflsadf asdlfsafdsafdsa 
    fsafdsadf safdls 
    </div> 
    <div class="draggable"> alsdf dsalf asdfsadf 
    dsaf sadfldsaf sadkf sadlfsadf 
    asdf safdsafdksadf sadf lasldkfjsaldf safdsa 
    dfsadflsadf asdlfsafdsafdsa 
    fsafdsadf safdls 
    </div> 
</div> 

腳本

var drag = new function(){ 
     this.box; 
     this._cnt; 
     this.hvEle; 
     this.trgEle; 
     this.initX; 
     this.initY; 
     this.dragging=false; 
}; 
$(document).on('mousedown','#box',function(){ 
    drag.box = $(this); 
    initX = drag.box.offset().left; 
    initY = drag.box.offset().top; 

    drag._cnt = drag.box.closest('.container'); 
    drag.hvEle = drag._cnt.find('.draggable'); 
    drag.box.css({position:"absolute"}); 

    drag.hvEle.mousemove(function(e){ 
     e.stopPropagation(); 
     drag.dragging=true; 
     drag.box.css({cursor:"move"}); 
     drag.hvEle.removeClass('dragHv'); 
     drag.trgEle = $(this); 
     drag.trgEle.addClass('dragHv'); 
     var x = e.pageX ||e.clientX; 
     var y = e.pageY ||e.clientY; 
     drag.box.css({left:x,top:y}); 

    }); 

    drag.box.mouseup(function(e){   
     drag.trgEle.append(drag.box); 
     /***** You can write your required logic here to either append or 
     insertBefore or insertAfter 
     ****/ 
     drag.box.css({position:'static',cursor:"move"}); 
     drag.hvEle.unbind('mousemove'); 
     drag.box.unbind('mouseup'); 
     drag.dragging=false; 
    }); 
}); 
$('.container').disableSelection(); 

這是額外的邏輯,以確保該元素沒有跌出容器元素

$(document).on('mousemove','html',function(){ 
    if(drag.dragging){ 
     drag.box.css({cursor:"no-drop"}); 
    } 
}); 
$(document).on('mouseup','html',function(){ 
    if(drag.dragging){ 
     drag.box.css({left:drag.initX,top:drag.initY,position:"static"}); 
     drag.box.css({cursor:"move"}); 
     drag.hvEle.unbind('mousemove'); 
     drag.box.unbind('mouseup'); 
     dragging=false; 
    } 
}); 
**Styles**** 

    .container{ 
     width:100%; 
     height:100%;  
     border:1px solid green; 
    } 
    .draggable{ 
    padding:10px 5px; 
    } 
    .draggable:nth-child(even){ 
     background:#efefef; 
     border-bottom:1px solid black; 
     border-top:1px solid black; 
    } 
    #box{ 
    height:50px; 
    width:200px; 
    background:red; 
    cursor:move; 
    } 
    .dragHv{ 
     background-color:yellow !important; 
    } 

這裏是fiddle
我希望它至少能以某種方式幫助你。

3

interact.js是一款支持與HTML和SVG元素交互的移動和桌面(包括IE8 +)獨立輕量級拖放和調整大小的JavaScript模塊。它只捕捉和計算拖動用戶輸入,並將所有樣式和視覺反饋留給您。

我已經更新了JS撥弄工作演示:http://jsfiddle.net/mLX5A/6/

var box = document.getElementById('box'), 
    container = document.getElementById('container'); 

// make an Interactable of the box 
interact(box) 
// make a draggable of the Interactable 
.draggable(true) 
    .on('dragmove', function (event) { 
     event.target.x |= 0; 
     event.target.y |= 0; 

     event.target.x += event.dx, 
     event.target.y += event.dy; 

     // translate the element by the change in pointer position 
     event.target.style[transformProp] = 
      'translate(' + event.target.x + 'px, ' + event.target.y + 'px)'; 
    }); 

// Then to make #container a dropzone dropzone: 
interact('#container')  // or interact(document.getElementById('container')) 
    .dropzone(true) 
    .on('drop', function (event) { 
     // target is the dropzone, relatedTarget was dropped into target 

     event.relatedTarget.x = 0; 
     event.relatedTarget.y = 0; 
     event.relatedTarget.style[transformProp] = ''; 

     var siblings = container.querySelectorAll('p'), 
      len = siblings.length; 

     for (var i = 0; i < len; i++) { 
      var rect = interact(siblings[i]).getRect(); 

      if (event.pageY < rect.top) { 
       return siblings[i].parentNode 
        .insertBefore(event.relatedTarget, siblings[i]); 
      } 
     } 

     return container.appendChild(event.relatedTarget); 
    }); 

// CSS transform vendor prefixes 
transformProp = 'transform' in document.body.style ? 
    'transform' : 'webkitTransform' in document.body.style ? 
    'webkitTransform' : 'mozTransform' in document.body.style ? 
    'mozTransform' : 'oTransform' in document.body.style ? 
    'oTransform' : 'msTransform'; 
-1

請不要投我的答案了,但我很驚訝,沒有人提到jQuery UI "Draggable"功能!它非常強大並且可以自定義,而不是試圖構建自己的。

+0

正如您在演示中看到的,我提供的功能非常強大,可以使某些功能可以拖拽,但這不是問題。無論如何感謝您的回答。 – iConnor

+0

@Pinocchio我檢查過,好像你花了很多時間做這件事(你已經在問題描述中提到過)。你「可以」(但它取決於你)利用jQuery UI「Draggable」或者「Sortable」來實現你正在嘗試做的事情。我的意思是,「可拖動」和「可排序」是非常發達的,可以爲您節省幾小時/幾天/每週的工作時間。 – evilReiko

1

看到這個例子中,這可能有助於

<html> 

<head> 



<script language="javascript" type="text/javascript"><!-- 

    var dragitem = undefined; 



    function setdragitem(item, evt) { 

     dragitem=item; 

     // alert('item: '+item); 

     // item is an HTML DIV element. 

     // evt is an event. 



     // If the item should not be draggable, enable this next line. 

     // evt.preventDefault(); 



     return true; 

    } 

    function cleardragitem() { 

     dragitem=undefined; 

     // alert('item: '+item); 

    } 

    function dodrag() { 

     // alert('item: '+dragitem); 

    } 



    // This is required---used to tell WebKit that the drag should 

    // be allowed. 

    function handledragenter(elt, evt) { 

     evt.preventDefault(); 

     return true; 

    } 

    function handledragover(elt, evt) { 

     evt.preventDefault(); 

     return true; 

    } 





    function handledragleave(elt, evt) { 



    } 



    function handledrop(elt, evt) { 

     // alert('drop'); 

     dragitem.style.display="none"; 

     var newid=dragitem.id + '_dest'; 

     var dest = document.getElementById(newid); 

     dest.innerHTML = dragitem.innerHTML; 

    } 





// --></script> 



<style type="text/css"><!-- 



    .wordbox { border: 1px solid black; text-align: center; width: 50px; float: left; -webkit-user-drag: element; -webkit-user-select: none; } 

    .spacer { clear: both; } 

    .target { margin-top: 30px; padding: 30px; width: 70px; border: 1px solid black; background: #c0c0ff; margin-bottom: 30px; -webkit-user-drop: element; } 

    .word { margin: 30px; min-height: 30px; border-bottom: 1px solid black; width: 50px; float: left; } 



--></style> 



</head> 

<body> 



<p>Drop words onto target area to put them in their places.</p> 



<div class='wordbox' id='this' ondragstart='setdragitem(this, event);' ondrag='dodrag();' ondragend='cleardragitem();'>This</div> 

<div class='wordbox' id='is' ondragstart='setdragitem(this, event);' ondrag='dodrag();' ondragend='cleardragitem();'>is</div> 

<div class='wordbox' id='a' ondragstart='setdragitem(this, event);' ondrag='dodrag();' ondragend='cleardragitem();'>a</div> 

<div class='wordbox' id='test' ondragstart='setdragitem(this, event);' ondrag='dodrag();' ondragend='cleardragitem();'>test</div> 



<div class='spacer'></div> 

<div class='target' ondragenter='handledragenter(this, event);' ondragover='handledragover(this, event);' ondragleave='handledragleave(this, event);' ondrop='handledrop(this, event);'>TARGET</div> 



<div class='words'> 

<div class='word' id='this_dest'></div> 

<div class='word' id='is_dest'></div> 

<div class='word' id='a_dest'></div> 

<div class='word' id='test_dest'></div> 

</div> 





</body> 

</html> 

您更see this link

否則see this link also

相關問題