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

Dojo DnD:如何在onDndDrop事件上访问新复制的节点?,dojo,drag-and-drop,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.pus

我正在编写如下代码

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: });
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 */ ] };
}
01:var c1=new dojo.dnd.Source('container1',{copyOnly:true});//container1是一个div
02:var c2=new dojo.dnd.Source('container2');//container2是一个div
03:var列表=[];
04:for(vari=0;i<3;i++){list.push(dojo.create('div'));}
05:c1.插入节点(false,list);
06: 
07:功能检查DndCopy(节点、目标){
08:dojo.forEach(节点,函数(节点){alert(node.id);});
09: }
10:dojo.subscribe(“/dnd/drop”,函数(){
11:var-mgr=dojo.dnd.manager();
12:checkDndCopy(管理节点、管理目标);
13: });
在第05行插入c1的节点的id为“dojoUnique1、donoUnique2、dojoUnique3”。 在将节点从c1拖放到c2的事件中,将触发onDndDrop事件并使用subscribe方法 调用第10-13行中定义的

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

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

我不确定这是否是唯一(也是最好)的方法,但您可以编写自己的节点创建者来覆盖丢弃的节点和化身创建。下面的示例扩展了您的代码并使删除的节点变为红色:

    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上找到更多关于编写自己的创建者的信息,首先,根据经验,尽量避免使用DnD主题,尤其是本地主题-它们使用起来很麻烦,因为在调用函数时,其他处理器可能会修改甚至破坏参数(正如你已经发现的那样)。使用本地事件和/或覆盖方法。如果要对新插入的节点执行某些操作,只需覆盖
onDrop
(或者
onDropExternal
,或者
onDropInternal
,如果只想处理特定的拖放)

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

让我们编码一下:

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),则应覆盖
OnProperternal
。代码将是相同的

因为本例不依赖于原始项,所以您可以使用主题,但如果您希望有条件地执行此操作,则可能需要一些额外的代码(例如,对于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");
  });
});

基于使用CustomCreator的方式,我发现了以下内容

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: });
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 */ ] };
}
vard;
d=dojo.doc.createElement('div');
var c01=new dojo.dnd.Source(d,{'copyOnly':true,'accept':[],'creator':myCreator});
var-arr=[];

对于(i=0;iThanks。使用自定义创建者是一个想法。这种方法的一个限制是不容易获取dnd事件的鼠标位置。有想法吗?谢谢。我不知道forInSelectedItems。我的测试表明,此循环拾取dnd事件之前c2中的项目。因此,第一个dnd没有任何内容。一个被丢弃的项目sencond dnd中的第一个dnd。在订阅函数结束时停止执行,可以找到新对象(它将是dnd节点的副本)此时尚未实例化。因此,在创建之后访问对象似乎很困难。您是否尝试了第一个或第二个代码段?仅第二个。我将尝试第一个。主题有一个问题——您永远不知道调用的顺序。有时(可能像在本例中)这很重要。我将撤回主题示例。我忘记在第2行和第13行之后添加dojo.place。