はじめに
「カーソルにオリジナルの画像を入れたいけど.cur
の画像使えない!」
みたいなことがありまして、JS使ってカーソルに画像がついてくるようにしたんですが、、、
クリックが効かない!!!!
原因
カーソルの直下に画像のレイヤーが来てしまっているので、どこをクリックしてもその画像をClickしていることになってしまうんですね。
最新のやりかた
こういう時は画像のクリックイベントを無効にしてあげればいいわけで、CSS3だと下記のような指定をすれば良いわけです。
.cursor_img { pointer-events: none; }
しかし今回は、、、
大人の事情により
「IE9に対応してないんでそれはなしで」
ということになりました。
Oh...
そこでいろいろと検索したところ、こんなページにたどり着きました。
[JS/CSS] 背面にある要素のマウスイベントを発火する
http://nbnote.jp/blog/2012/04/mouse-enabled/
Forwarding Mouse Events Through Layers
http://www.vinylfox.com/forwarding-mouse-events-through-layers/
詳細
下記のような感じで処理をしています。
クリック後一時的に上のレイヤーを非表示にする
↓
クリックイベントが発火した場所の座標を取得
↓
その座標にある要素を取得
↓
その要素のクリックイベントを発火
↓
上のレイヤーを表示させる
document.elementFromPoint
を使うとその座標にある要素を取得できるようです。
【参考】document.elementFromPoint - MDN
https://developer.mozilla.org/ja/docs/Web/API/Document/elementFromPoint
JSはこんな感じです。
今回は特定のクラスを持ったレイヤーのクリックイベントを発火させたかったので、そのクラスを持ったレイヤーが出てくるまで親要素を遡るようにしています。
$cursor = $('.cursor_img');
$cursor.on( 'click', function( e ) {
$cursor.css( { display: 'none' } );
let elem = document.elementFromPoint( e.clientX, e.clientY );
let dig = ($node)=> {
if($node.hasClass('link')) return $node;
return dig($node.parent());
}
let $parent = dig($(elem));
$parent.trigger('click');
$cursor.css( { display: 'inline' } );
} );
参考元では
document.elementFromPoint( e.pageX, e.pageY );
としていますが、僕のところではうまくいかなかったのでclientX
とclientY
を使いました。