2012-01-24 145 views
4

我使用圖像地圖創建圖像,並且我想設置拖動 並放下,以便我知道該圖像的哪個部分丟棄了 。圖像地圖區域上的jquery droppable

它的工作方式,但當我把一個項目放到其中一個區域時,它會觸發所有區域的功能。有沒有辦法讓 工作?

請幫助...

+0

你應該提供一個例子,你如何實現它,這將使它更容易回答你的問題。 – OlafW

回答

2

我假設你有這樣的事情:

<img src="image.gif" width="145" height="126" alt="Elements" usemap="#elementmap" /> 

<map name="elementmap"> 
    <area id="element1" shape="rect" coords="0,0,82,126" alt="Element 1"/> 
    <area id="element2" shape="circle" coords="90,58,3" alt="Element 2"/> 
</map> 

我認爲,你可以叫$('#element1')在jQuery代碼來獲取對象和做一些事情(我認爲可能工作,因爲如果你把在第一個元素中發出警報的click事件,它可以工作!)

另一方面,也許這可以幫助你,如果你需要的元素被丟棄的座標或只是想要的元素是stabli放在一個div上。看看這個例子和編輯它根據你所需要的:

看看這個第一: http://www.placona.co.uk/166/javascript/a-more-elaborated-jquery-drag-drop-cloning/

活生生的例子: http://examples.placona.co.uk/drag_drop

最後一個建議是不工作100%,COORDS因爲當用戶調整瀏覽器窗口大小時,座標會發生變化,如果您在將來需要它們來恢復位置並將其全部收取到瀏覽器中,它將無法正常工作。

顯然我不知道你是否需要他們,但我只是說。

希望這會有所幫助。

4

所以,這是一個老問題,但這是我本週遇到的一個問題,找不到任何有用的答案。上面的答案並沒有直接解決從html圖像地圖上的區域元素進行放置的問題 - 它提供了一個答案,但這個答案實際上並不工作,因爲製作一個「區域」可以將整個圖像映射到可放下的物品,因此當物品被丟棄時,您無法確定哪個區域處於活動狀態。

這裏是(使用聚區),我最終實現了我的問題的解決方案:

<div id="content"> 
<div id="targetImage"><img src="images/interactive_bg_triColored.png" usemap="#targetOverlay" alt="Strategic Action Chart"/> 
    <map id="targetOverlay" name="targetOverlay"> 
    <area id="slice_0" shape="poly" coords="47, 294, 82, 178, 236, 267, 224, 293" /> 
    <area id="slice_1" shape="poly" coords="87, 171, 168, 89, 258, 235, 240, 254" /> 
    <area id="slice_2" shape="poly" coords="177, 82, 295, 48, 297, 228, 265, 234" /> 
    <area id="slice_3" shape="poly" coords="302, 49, 419, 81, 334, 232, 303, 227" /> 
    <area id="slice_4" shape="poly" coords="428, 84, 514, 170, 360, 258, 338, 239" /> 
    <area id="slice_5" shape="poly" coords="364, 266, 516, 186, 546, 292, 373, 294" /> 
    <area id="slice_6" shape="poly" coords="546, 307, 518, 412, 363, 333, 373, 305" /> 
    <area id="slice_7" shape="poly" coords="512, 427, 428, 508, 340, 361, 360, 343" /> 
    <area id="slice_8" shape="poly" coords="421, 515, 304, 549, 302, 375, 334, 365" /> 
    <area id="slice_9" shape="poly" coords="295, 550, 180, 517, 266, 366, 295, 371" /> 
    <area id="slice_10" shape="poly" coords="170, 512, 86, 431, 240, 340, 259, 360" /> 
    <area id="slice_11" shape="poly" coords="80, 422, 51, 304, 228, 305, 235, 332" /> 
    </map> 
</div> 
<div id="word_list"> 
    <div id="instructions">Drag these action words into the appropriate category on the left.</div> 
    <div id="word_6" class="draggable_word answer_o">Adjust</div> 
    <div id="word_7" class="draggable_word answer_m">Infer</div> 
    <div id="word_8" class="draggable_word answer_m">Synthesize</div> 
    <div id="word_4" class="draggable_word answer_o">Summarize</div> 
    <div id="word_5" class="draggable_word answer_o">Maintain<br /> Fluency</div> 
    <div id="word_9" class="draggable_word answer_m">Make<br />Connections</div> 
    <div id="word_11" class="draggable_word answer_p">Critique</div> 
    <div id="word_10" class="draggable_word answer_m">Predict</div> 
    <div id="word_2" class="draggable_word answer_o">Monitor <br />and Correct</div> 
    <div id="word_3" class="draggable_word answer_o">Search & Use<br /> Information</div> 
    <div id="word_0" class="draggable_word answer_p">Analyze</div> 
    <div id="word_1" class="draggable_word answer_o">Solve Words</div> 

</div> 

的CSS:

.draggable_word 
{ 
    font-weight: bold; 
    padding: 5px; 
    width: 100px; 
    display: inline-block 
} 

.draggable_word:hover 
{ 
    cursor: pointer; 
} 

注意,你必須有在你的.draggable類中設置的寬度(你可以任意命名它,但是它需要被應用到你可以拖動的項目,在我的情況下是一個內部有少量文本的div)

var x1, y1 = 0; 
var area = []; //set of area objects 
var myDropTarget = 'invalid'; 

$(document).ready(function() { 
for (i = 0; i < 12; i++) { 
    $('#word_' + i).draggable({ 
     cursor: "move", 
     revert: function (socketObj) { 
      //if false then no droppable target was found 
      if (socketObj === false) { 
       //revert the draggable by returning true 
       return true; 
      } 
      else { //the drop location was a droppable zone, now test it for answer validity 

       var offset = $(this).offset(); //gets the x,y position of the dragged object when it stops 
       x1 = offset.left + ($(this).width()/2); //establishes the center of the object to use for testing x,y 
       y1 = offset.top + ($(this).height()/2); 

       var result = dropTarget(x1, y1); //returns id of area or 'invalid' 
       //logic to validate answers 
       if (result === 'invalid') { 
        return true; 
       } else { //evaluate for answer correctness 
        var testSlice = result.split('_'); 

        if ((testSlice[1] > -1) && testSlice[1] < 6) { //first 6 slices are 'orange' 
         if ($(this).hasClass('answer_o')) { //correct answer 
          return false; //slice matches word answer class so do NOT revert 
         } 
        } else if ((testSlice[1] > 5) && testSlice[1] < 10) { //next 4 slices are 'maroon' 
         if ($(this).hasClass('answer_m')) { //correct answer 
          return false; //slice matches word answer class so do NOT revert 
         } 
        } else if ((testSlice[1] > 9) && testSlice[1] < 12) { //last 2 slices are 'purple' 
         if ($(this).hasClass('answer_p')) { //correct answer 
          return false; //slice matches word answer class so do NOT revert 
         } 
        } else return true; 


       } 

       console.log('drop ' + x1 + ', ' + y1); 
       console.log(result); 

       //if no correct answer was found then it will still need to revert; 
       return true; 
      } 
     } 
    }); 
} 

$('map area').each(function (i) { 
    //this creates an array of area polygon objects so that we can test when an item has been dropped inside of one 
    area[i] = {}; // creates a new object which will have properties for id, x coordinates, and y coordinates 
    area[i].id = $(this).attr("id"); 
    area[i].x = []; 
    area[i].y = []; 
    var coords = JSON.parse('[' + $(this).attr("coords") + ']'); 
    var totalPairs = coords.length/2; 
    var coordCounter = 0; //variable to double iterate 
    for (ix = 0; ix < totalPairs; ix++) { //fill arrays of x/y coordinates for pnpoly 
     area[i].x[ix] = coords[coordCounter]; 
     area[i].y[ix] = coords[coordCounter + 1]; 
     coordCounter += 2; 
    } 
}); 

$('#targetImage').droppable({ 
    // maps or areas don't work well as droppable targets so we make image's container div into the droppable 
    tolerance: 'pointer' 
}); 
}); 


function dropTarget(dropX, dropY) { 
var target = 'invalid'; 

for (i = 0; i < area.length; i++) { //iterate through all of our area objects 
    if (pnpoly(area[i].x.length, area[i].x, area[i].y, dropX, dropY)) { 
     for (ix = 0; ix < area[i].x.length; ix++) { 
      console.log(area[i].x[ix] + ', ' + area[i].y[ix]); 
     } 
     target = area[i].id; 
     break; 
    } 
} 
return target; 
} 

function pnpoly(nvert, vertx, verty, testx, testy) { //Point in Poly Test http://www.ecse.rpi.edu/~wrf/Research/Short_Notes/pnpoly.html 
var i, j, c = false; 
for (i = 0, j = nvert - 1; i < nvert; j = i++) { 
    if (((verty[i] > testy) != (verty[j] > testy)) && 
     (testx < (vertx[j] - vertx[i]) * (testy - verty[i])/(verty[j] - verty[i]) + vertx[i])) { 
     c = !c; 
    } 
} 
return c; 
} 

基本上它所做的是生成一個對象數組來表示每個'區域'元素。這些對象有一個ID屬性,一個X點數組和一個Y點數組。可拖動項目報告它們的中心點,然後使用點中多邊形函數(pnpoly)測試它的中心點是否落入特定的多邊形內。如果找到匹配,則返回該區域的ID,從而允許我們在可拖動的還原函數定義中應用邏輯。在這種情況下,我應用了一個虛擬類來表示不同的可接受答案類型。

不管怎麼說,希望這可以幫助別人的未來...