Dojo DnD:如何在onDndDrop事件上访问新复制的节点?

时间:2009-10-27 18:13:55

标签: dojo drag-and-drop

我正在处理以下代码。

01: var c1 = new dojo.dnd.Source('container1', {copyOnly:true}); // container1 is a div
02: var c2 = new dojo.dnd.Source('container2');                  // container2 is a div
03: var list = [];
04: for (var i = 0; i < 3; i++) { list.push( dojo.create('div') ); }
05: c1.insertNodes(false, list);
06: 
07: function checkDndCopy(nodes, target){
08:  dojo.forEach(nodes, function(node){ alert(node.id); } );
09: }
10: dojo.subscribe("/dnd/drop", function(){
11:   var mgr = dojo.dnd.manager();
12:   checkDndCopy(mgr.nodes, mgr.target);
13: });

在05行插入c1的节点的id为“dojoUnique1,donoUnique2,dojoUnique3”。 在将节点从c1拖放到c2的事件中,会触发onDndDrop事件并且订阅方法 调用第10-13行中定义的内容。

我预计新复制的节点会出现在第08行的节点中(例如)。但事实并非如此。 当dojoUnique1是拖放目标时,第08行的节点仅包含dojoUnique1。

我想修改onDndDrop事件中新复制节点的一些属性。请让我 知道如何实现这样的事情。

3 个答案:

答案 0 :(得分:1)

我不确定,如果它是唯一(也是最好的)方式,但您可以编写自己的节点创建者来覆盖已删除的节点和头像创建。下面的示例扩展了您的代码并使删除的节点变为红色:

    var c1 = new dojo.dnd.Source('container1', {copyOnly:true }); // container1 is a div
    var c2 = new dojo.dnd.Source('container2', { creator: nodeCreator }  );   // container2 is a div

    function nodeCreator(item, hint) {
      var node = dojo.create("div", { innerHTML: item }); 
      if (hint != "avatar") {
        dojo.style(node, 'color', 'red');
      }
      return { node: node, data: item };
    }

您可以在Google中找到有关编写自己的创作者here的更多信息

答案 1 :(得分:1)

首先,根据经验,尝试避免使用DnD主题,特别是对于本地事物 - 它们使用起来很麻烦,因为在调用函数时,参数可以被其他处理器修改甚至销毁(如您已经发现的那样) 。使用本地事件和/或覆盖方法。如果您想对新插入的节点执行某些操作,只需覆盖onDrop(或onDropExternalonDropInternal,如果您只想处理特定的丢弃。)

另一个有用的提示:选择新插入的节点。

让我们编写代码:

var c1 = new dojo.dnd.Source('container1', {copyOnly:true});
var c2 = new dojo.dnd.Source('container2');

// ...

// the decorator technique
function paintRed(source){
  var old_onDrop = source.onDrop;
  source.onDrop = function(){
    // we don't care about actual parameters
    // (we will pass them in bulk)
    // let's do a drop:
    old_onDrop.apply(this, arguments);
    // now all dropped items are inserted and selected in c2
    // let's iterated over all selected items:
    this.forInSelectedItems(function(item, id){
      // print the id
      console.log(id);
      // paint it red
      dojo.style(id, "color", "red");
    });
  };
}

// now let's decorate c2
paintRed(c2);
// now c2 paints all dropped nodes red

如果您允许重新排列列表并且只想对外部删除进行修改(例如,从c1到c2),则应覆盖onDropExternal。代码将是相同的。

由于此示例不依赖于原始项目,因此您可以使用主题进行操作,但如果您想要有条件地执行此操作,则可能需要一些额外的代码(例如,对于c2,但不是c1)。如果你不关心任何其他事情,它实际上也很容易:

dojo.subscribe("/dnd/drop", function(source, nodes, copy, target){
  // warning: by the time this function is called nodes
  // can be copied/modified/destroyed --- do not rely on them!
  // but we don't need them here
  target.forInSelectedItems(function(item, id){
    // print the id
    console.log(id);
    // paint it red
    dojo.style(id, "color", "red");
  });
});

答案 2 :(得分:0)

根据使用自定义创建者的方式,我找到了以下内容。

var d;
d = dojo.doc.createElement('div');
var c01 = new dojo.dnd.Source(d, { 'copyOnly': true, 'accept': [], 'creator': myCreator});

var arr = [];
for(i=0; i<3; i++){ 
  d = dojo.create('div'); // dnd items
  // define contents and properties of d
  arr.push( d );
}
c01.insertNodes(false, divArr);

d = dojo.doc.createElement('div');
var c02 = new dojo.dnd.Source(d, { 'creator': myCreator});

function myCreator(item, hint){
  var node = dojo.doc.createElement('div');
  node.id = dojo.dnd.getUniqueId();
  var mgr = dojo.dnd.manager();
  // from dojo.dnd.manager(), it is possible to find which one to create 
  // the follwoing condition is just a sample
  if(hint != 'avatar' && 
     mgr.source && mgr.target // these are null when creating newly inserted one
     mgr.source.node && mgr.target.node // by inspecting these nodes, one can know
                                        // whether the item is newly copied one
  ){
    dojo.style(node, 'color', 'red');
    // one can get mouse position from mgr and set the node position
  }
  var copyItem = createCopyItem( item );
  dojo.place(copyItem, node, 'last');

  return { node: node, data: copyItem, type:[ /* what you want */ ] };
}

函数createCopyItem()超出范围。有必要复制item并修改新对象,因为item不能放在其原始parentNode下和myCreator()中创建的node下。