2012-01-24 75 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,从而允许我们在可拖动的还原函数定义中应用逻辑。在这种情况下,我应用了一个虚拟类来表示不同的可接受答案类型。

不管怎么说,希望这可以帮助别人的未来...