2016-09-12 5 views
2

私が取り組んでいるイベントコードを修正しようとしています。この特別なケースでは、svg:circleclickイベントに登録できる必要があります。しかし、円をmousedown上のz-インデックスの先頭に移動して、要素を他の要素の上にドラッグできるようにする必要もあります。イベントを中断することなく要素を前に移動

これを行う方法は、DOMから要素を取り出し、私がhttp://bl.ocks.org/eesur/4e0a69d57d3bfc8a82c2から使用しているヘルパー関数を使用して正しい場所に再度挿入することです。これを行う際の問題は、イベントチェーンが、DOMから要素を取り除いて、clickイベントの発砲を妨げているように見えることです。

誰でもこれを行うためのより良い方法を考え出すことができますが、clickが正しく点火され、ドラッグライフサイクル中のどこかでZ-インデックスを変更できるようになるのでしょうか?

この小さな例は、Z-インデックスの変更方法を示していますが、クリックイベントはコンソールで発生しません。要素を一度上にクリックすると、クリックが正しく開始されます。

d3.selectAll("circle") 
 
    .on("mousedown", function() { 
 
    d3.select(this).moveToFront(); 
 
    }) 
 
    .on("click", function() { 
 
    var fill = d3.select(this).style("fill"); 
 
    console.log("You clicked on : " + fill); 
 
    }); 
 

 
d3.selection.prototype.moveToFront = function() { 
 
    return this.each(function() { 
 
    this.parentNode.appendChild(this); 
 
    }); 
 
};
.red { 
 
    fill: red; 
 
} 
 
.blue { 
 
    fill: blue; 
 
} 
 
.green { 
 
    fill: green; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.3.13/d3.min.js"></script> 
 
<svg width="600" height="600"> 
 
    <circle class="red" cx="50" cy="50" r="50" /> 
 
    <circle class="blue" cx="100" cy="100" r="50" /> 
 
    <circle class="green" cx="150" cy="150" r="50" /> 
 
</svg>

+0

チャージ()'と 'selection.lower()'。 –

+0

@GerardoFurtadoこの作業では、回答を追加していただければ幸いですが、残念ながらD3のv3を使用して解決策を見つける必要があります。しかし、レイズのコードを見ても、まったく同じ問題があるようです - https://github.com/d3/d3-selection/blob/master/src/selection/raise.js – Ian

+0

複雑です私は私の携帯電話にいるので、今書き込むが、私が書いたこの文書をチェックして、最後のフィドルは "下"と "上げ"を使用する:http://stackoverflow.com/documentation/d3.js/2537/core- svg-concepts-in-d3-js-visualization/18029/svg-the-drawing-order#t = 20160912084737911518である。残念ながら、これはv4です。 –

答えて

1

問題がd3とあった場合、私はので、私は純粋なJSに相当するものを書いて、あなたがd3で行ったようにクロームでまったく同じ結果を持っていた疑問に思いました。私はclickmouseupに置き換えて、それを私のコメントのようにmousedown要素と比較することで、動作させることができました。あなたは、あなたのコメントでは、他のプロジェクトの制限のために、この解決策があなたのケースでは不可能であると述べました。とにかく私のソリューションを投稿したいと思ったのは、FFとIEでは動作が違っていると言われていたからです。

const circles = Array.from(document.getElementsByTagName('circle')); 
 
let mousedown; 
 
for (let circle of circles) { 
 
    circle.addEventListener('mousedown', (e) => { 
 
    mousedown = e.target; 
 
    e.target.parentNode.appendChild(e.target); 
 
    }, false); 
 
    circle.addEventListener('mouseup', (e) => { 
 
    if (mousedown === e.target) { 
 
     console.log('You clicked on : ' + window.getComputedStyle(e.target).fill); 
 
    } 
 
    mousedown = null; 
 
    }, false); 
 
}
.red { 
 
    fill: red; 
 
} 
 
.blue { 
 
    fill: blue; 
 
} 
 
.green { 
 
    fill: green; 
 
}
<svg width="600" height="600"> 
 
    <circle class="red" cx="50" cy="50" r="50" /> 
 
    <circle class="blue" cx="100" cy="100" r="50" /> 
 
    <circle class="green" cx="150" cy="150" r="50" /> 
 
</svg>

V4及び使用 `selection.raiseに

+1

誰かに役立つように答えを加える価値があるので、私はあなたにアップヴォートを与えます。誰かがより良いD3の答えを持っていない限り、答えとして答えを受け入れる必要があります。 – Ian

1

私はDOM内の多くの要素がある場合は、パフォーマンスについて少し不安なんですが、私は、動作しているようです少し奇抜なアイデア、思い付くことができました。

アイデアは基本的に、マウスの下に置かれた要素の背後にある他のすべてのもの(この場合はsvg:circle)を移動するために、選択を(mousedown)に移動するのではなく、

d3.selectAll("circle") 
 
    .on("mousedown", function() { 
 
    var that = this; 
 
    d3.select(this.parentNode) 
 
     .selectAll("circle") 
 
     .filter(function() { return this !== that; }) 
 
     .moveBehind(that); 
 
    }) 
 
    .on("click", function() { 
 
    var fill = d3.select(this).style("fill"); 
 
    console.log("You clicked on : " + fill); 
 
    }); 
 

 
d3.selection.prototype.moveToFront = function() { 
 
    return this.each(function() { 
 
    this.parentNode.appendChild(this); 
 
    }); 
 
}; 
 

 
d3.selection.prototype.moveBehind = function(element) { 
 
    return this.each(function() { 
 
    this.parentNode.insertBefore(this, element); 
 
    }); 
 
};
.red { 
 
    fill: red; 
 
} 
 
.blue { 
 
    fill: blue; 
 
} 
 
.green { 
 
    fill: green; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.3.13/d3.min.js"></script> 
 
<svg width="600" height="600"> 
 
    <circle class="red" cx="50" cy="50" r="50" /> 
 
    <circle class="blue" cx="100" cy="100" r="50" /> 
 
    <circle class="green" cx="150" cy="150" r="50" /> 
 
</svg>

関連する問題