以前の記事で、Elementに対するイベントの設定方法をご紹介しました。
その中で、event
属性をつけるとカスタムイベントを発行できることを紹介しました。
joint.shapes.standard.Rectangle.define('example.MyRectangle', {
size : { width: 100, height: 40 },
attrs: {
body: {
stroke: "#999",
fill: "#999",
event: 'myrect:click',
},
label: {
stroke: "#EEE",
fill: "#EEE",
'font-size': 4
}
}
});
paper.on('myrect:click', function() {
console.log("クリックされました");
});
このevent
属性に設定したイベントはクリックイベント(正確にはmousedown
/ touchstart
イベント)のときにのみ発行されます。では、クリックイベント以外のイベントを処理させるにはどうすればよいのか、について紹介します。
カスタム要素を作成してclassをつける
イベントを処理したい要素に対してclassを付与しておきます。
joint.shapes.standard.Rectangle.define('example.MyRectangle', {
size : { width: 100, height: 40 },
attrs: {
body: {
stroke: "#999",
fill: "#999",
class: "myrect-body" // ←追加
},
label: {
stroke: "#EEE",
fill: "#EEE",
'font-size': 4
}
}
}
addEventListener
を使用する
JointJSのElementであっても、addEventListener
でイベントリスナーを追加することができます。JointJSの描画が終わった後であれば要素にアクセスできますので、前述のclassを利用してJavaScriptでイベントリスナーを追加していきます。
const mouseoverFunc = function() {
console.log("mouseover")
}
const myrects = document.getElementsByClassName("myrect-body");
for (i = 0; i < myrects.length; i++) {
myrects[i].addEventListener("mouseover", mouseoverFunc);
}
条件等がある場合はattr
に設定しておく
addEventListener
を使用する方法だと、標準のJavaScriptのためJointJSの用意しているmodelにアクセスすることができません。これがevent
で発生させたイベントのイベント処理との差異となります。
これはデータ属性を設定することである程度の回避策を立てられます。
イベントの発生後に条件文などを扱う場合は、attr()
メソッドを使用して条件に使用するデータをデータ属性に入れておくと、
// データ属性に値を設定
const rect1 = joint.shapes.example.MyRectangle.create('四角形1', 10, 10);
rect1.attr('root/data-price', 300);
const rect2 = joint.shapes.example.MyRectangle.create('四角形2', 150, 10);
rect2.attr('root/data-price', 500);
// マウスオーバー時の処理
const mouseoverFunc = function(evt) {
// データ属性を参照して条件を判定できる
if(Number(evt.target.dataset["price"]) < 500) {
console.log("セール中");
}
}
for (i = 0; i < myrects.length; i++) {
myrects[i].addEventListener("mouseover", mouseoverFunc);
}
まとめ
今回はevent
以外のイベントを処理するための小技を紹介しました。JointJSのAPI経由で処理できるイベントは他にもありますが、HTMLのイベントをそのまま使えるようにはなっておりません。HTMLから図を以降する際にJointJSのイベント処理でまかないきれないイベントが出てきてしまう場合は、今回のような方法での回避を検討してみてください。
※この記事は JointJS Advent Calendar 2023 の記事です。他の記事を読む場合はカレンダーのページを参照してください。