マウス移動イベントなしで(マウスを移動せずに)ページのロード後にJavaScriptでマウス位置を取得することは可能ですか?
mousemove
イベントを追加してブラウザーの速度を低下させたくない場合があります。
マウス移動イベントなしで(マウスを移動せずに)ページのロード後にJavaScriptでマウス位置を取得することは可能ですか?
mousemove
イベントを追加してブラウザーの速度を低下させたくない場合があります。
回答:
本当の答え:いいえ、それは不可能です。
OK、私は方法を考えました。ドキュメント全体をカバーするdivでページをオーバーレイします。その中に(たとえば)2,000 x 2,000の<a>
要素を作成します(:hover
疑似クラスがIE 6で機能するようにするため)。各要素のサイズは1ピクセルです。プロパティを変更する要素のCSS :hover
ルールを作成し<a>
ます(たとえば、としますfont-family
)。ロードハンドラーで、400万個の<a>
要素のそれぞれを循環させ、ホバーフォントの要素が見つかるまでcurrentStyle
/を確認しgetComputedStyle()
ます。この要素から外挿して、ドキュメント内の座標を取得します。
これをしないでください。
<a>
与えられた四角形をカバーする要素のペアを作成するループ(サイズ設定された<img>
要素の絶対配置を使用すると思います)、四角形を毎回縮小します。はい、ばかげていますが、最初のマウス移動の前にこの情報を取得することはできません。
編集2020:これは機能しなくなりました。ブラウザーベンダーがこれにパッチを適用したようです。ほとんどのブラウザはクロムに依存しているため、中核となる可能性があります。
以前の回答:mouseenterをフックすることもできます(このイベントは、ページのリロード後に、mousecursorがページ内にあるときに発生します)。Corruptedのコードを拡張することでうまくいくはずです。
var x = null;
var y = null;
document.addEventListener('mousemove', onMouseUpdate, false);
document.addEventListener('mouseenter', onMouseUpdate, false);
function onMouseUpdate(e) {
x = e.pageX;
y = e.pageY;
console.log(x, y);
}
function getMouseX() {
return x;
}
function getMouseY() {
return y;
}
mouseleave-eventでxとyをnullに設定することもできます。したがって、ユーザーがカーソルを使用してページ上にいるかどうかを確認できます。
mouseleave
設定した場合x
とy
裏面にnull
又は'undefined'
できることは、カーソルの座標x
とy
座標の変数を作成し、マウスが移動するたびに変数を更新し、間隔で関数を呼び出して、格納された位置で必要なことを行うことです。
もちろん、これの欠点は、マウスを機能させるために、マウスの最初の1回の動きが必要なことです。カーソルが少なくとも一度は位置を更新している限り、カーソルが再び移動するかどうかに関係なく、カーソルの位置を見つけることができます。
var cursorX;
var cursorY;
document.onmousemove = function(e){
cursorX = e.pageX;
cursorY = e.pageY;
}
setInterval(checkCursor, 1000);
function checkCursor(){
alert("Cursor at: " + cursorX + ", " + cursorY);
}
上記のコードは、カーソルの位置を示すメッセージで1秒に1回更新されます。これがお役に立てば幸いです。
cursorX/Y
イベントが発生する前にこれらの変数を埋める方法を探していたので、メリットはありませんでした。
2,000 x 2,000 <a>
要素をレンダリングする場合、@ Tim Downの回答は効果的ではありません。
OK、私は方法を考えました。ドキュメント全体をカバーするdivでページをオーバーレイします。その中に(たとえば)2,000 x 2,000の要素(:hover疑似クラスがIE 6で機能するようにする)を作成します。各要素のサイズは1ピクセルです。プロパティを変更する要素(たとえばfont-family)のCSS:hoverルールを作成します。ロードハンドラーで、400万個の要素のそれぞれを循環させ、ホバーフォントの要素が見つかるまでcurrentStyle / getComputedStyle()を確認します。この要素から外挿して、ドキュメント内の座標を取得します。
これをしないでください。
ただし、一度に400万個の要素をレンダリングする必要はなく、代わりにバイナリ検索を使用します。<a>
代わりに4つの要素を使用してください:
<a>
要素に分割する getComputedStyle()
関数を使用して、どの長方形のマウスがホバーするかを決定するこの方法では、画面が2048pxより広くないことを考慮して、これらの手順を最大11回繰り返す必要があります。
したがって、最大11 x 4 = 44 <a>
要素を生成します。
マウスの位置をピクセル単位で正確に決定する必要はないが、10pxの精度で問題ない場合。手順を最大8回繰り返すため、最大8 x 4 = 32 <a>
要素を描画する必要があります。
また<a>
、DOMは一般的に遅いため、要素を生成して破棄することはできません。代わりに、あなただけの最初の4つの再利用できる<a>
要素を、ちょうど彼らの調整top
、left
、width
およびheight
手順をあなたのようにループを。
さて、4を作成<a>
するのもやりすぎです。代わりに、各長方形で<a>
テストするときに、同じ1つの要素を再利用できgetComputedStyle()
ます。したがって、検索領域を2 x 2の<a>
要素に分割する代わりに<a>
、top
とleft
スタイルのプロパティを移動して、単一の要素を再利用します。
したがって、必要なのは、単一の<a>
要素の最大値width
とheight
最大値を11回変更しtop
、left
最大値と最大値を44回変更するだけです。これにより、正確なマウスの位置がわかります。
最もシンプルなソリューションですが、100%正確ではありません
$(':hover').last().offset()
結果:{top: 148, left: 62.5}
結果は最も近い要素のサイズに依存し、undefined
ユーザーがタブを切り替えたときに返されます
undefined
関係なく戻ります。これの使い方について詳しく教えていただけますか?
undefined
カーソルが要素の上に置かれていないとき(またはブラウザーがフォーカスを失ったとき)に戻ります。あなたのコンソールからしているテスト..場合は、時間間隔を設定する必要があるかもしれません
setTimeout
働いた。私はjsfiddleを使用していましたが、そうです。再生をクリックするたびにDOMを再描画するため、ホバーイベントにヒットすることはありません。他の人にこのヒントを追加することをお勧めします。
タイマー付きの親ページがあり、一定時間またはタスクが完了した後、ユーザーを新しいページに転送するとします。ここで、カーソルの位置が必要になります。これらは待機しているため、必ずしもマウスに触れているわけではありません。したがって、標準イベントを使用して親ページでマウスを追跡し、最後の値をgetまたはpost変数で新しいページに渡します。
親ページでJHardingのコードを使用して、最新の位置が常にグローバル変数で利用できるようにすることができます。
var cursorX;
var cursorY;
document.onmousemove = function(e){
cursorX = e.pageX;
cursorY = e.pageY;
}
これは、親ページ以外の方法でこのページに移動するユーザーには役立ちません。
上記のTim Downのアイデアのように、水平/垂直検索を実装しました(最初にdivを水平に配置された垂直線リンクでいっぱいにし、次にdivを垂直に配置された水平線リンクでいっぱいにし、ホバー状態になっているものを確認します)。それはかなり速く動作します。残念ながら、KDE上のChrome 32では機能しません。
jsfiddle.net/5XzeE/4/
@SuperNova の答えをリフィングしthis
て、コールバックでコンテキストを正しく保持するES6クラスを使用するアプローチを次に示します。
class Mouse {
constructor() {
this.x = 0;
this.y = 0;
this.callbacks = {
mouseenter: [],
mousemove: [],
};
}
get xPos() {
return this.x;
}
get yPos() {
return this.y;
}
get position() {
return `${this.x},${this.y}`;
}
addListener(type, callback) {
document.addEventListener(type, this); // Pass `this` as the second arg to keep the context correct
this.callbacks[type].push(callback);
}
// `handleEvent` is part of the browser's `EventListener` API.
// https://developer.mozilla.org/en-US/docs/Web/API/EventListener/handleEvent
handleEvent(event) {
const isMousemove = event.type === 'mousemove';
const isMouseenter = event.type === 'mouseenter';
if (isMousemove || isMouseenter) {
this.x = event.pageX;
this.y = event.pageY;
}
this.callbacks[event.type].forEach((callback) => {
callback();
});
}
}
const mouse = new Mouse();
mouse.addListener('mouseenter', () => console.log('mouseenter', mouse.position));
mouse.addListener('mousemove', () => console.log('mousemove A', mouse.position));
mouse.addListener('mousemove', () => console.log('mousemove B', mouse.position));
これが私の解決策です。これは、エクスポートwindow.currentMouseXとwindow.currentMouseYあなたはどこでも使用できるプロパティを。最初にホバーされた要素(存在する場合)の位置を使用し、その後マウスの動きをリッスンして正しい値を設定します。
(function () {
window.currentMouseX = 0;
window.currentMouseY = 0;
// Guess the initial mouse position approximately if possible:
var hoveredElement = document.querySelectorAll(':hover');
hoveredElement = hoveredElement[hoveredElement.length - 1]; // Get the most specific hovered element
if (hoveredElement != null) {
var rect = hoveredElement.getBoundingClientRect();
// Set the values from hovered element's position
window.currentMouseX = window.scrollX + rect.x;
window.currentMouseY = window.scrollY + rect.y;
}
// Listen for mouse movements to set the correct values
document.addEventListener('mousemove', function (e) {
window.currentMouseX = e.pageX;
window.currentMouseY = e.pageY;
});
}())
Composr CMSソース: https : //github.com/ocproducts/composr/commit/a851c19f925be20bc16bfe016be42924989f262e#diff-b162dc9c35a97618a96748639ff41251R1202
var x = 0;
var y = 0;
document.addEventListener('mousemove', onMouseMove, false)
function onMouseMove(e){
x = e.clientX;
y = e.clientY;
}
function getMouseX() {
return x;
}
function getMouseY() {
return y;
}
私はdivとピクセルを数えることなく合理的な解決策があるかもしれないと思います。
単にアニメーションフレームまたは関数の時間間隔を使用します。開始するだけの場合でも、マウスイベントは1回必要ですが、技術的には、好きな場所に配置できます。
基本的に、マウスを動かさずに常にダミーdivを追跡しています。
// create a div(#mydiv) 1px by 1px set opacity to 0 & position:absolute;
以下はロジックです。
var x,y;
$('body').mousemove(function( e ) {
var x = e.clientX - (window.innerWidth / 2);
var y = e.clientY - (window.innerHeight / 2);
}
function looping (){
/* track my div position 60 x 60 seconds!
with out the mouse after initiation you can still track the dummy div.x & y
mouse doesn't need to move.*/
$('#mydiv').x = x; // css transform x and y to follow
$('#mydiv)'.y = y;
console.log(#mydiv.x etc)
requestAnimationFrame( looping , frame speed here);
}