これをjQueryですばやく簡単に行う方法はありますか?
マウスオーバーイベントは他の目的で既に使用しているため、使用したくありません。マウスが特定の瞬間に要素の上にあるかどうかを知る必要があるだけです。
「IsMouseOver」関数があった場合のみ、私はこのようなことをしたいと思います。
function hideTip(oi) {
setTimeout(function() { if (!IsMouseOver(oi)) $(oi).fadeOut(); }, 100);
}
これをjQueryですばやく簡単に行う方法はありますか?
マウスオーバーイベントは他の目的で既に使用しているため、使用したくありません。マウスが特定の瞬間に要素の上にあるかどうかを知る必要があるだけです。
「IsMouseOver」関数があった場合のみ、私はこのようなことをしたいと思います。
function hideTip(oi) {
setTimeout(function() { if (!IsMouseOver(oi)) $(oi).fadeOut(); }, 100);
}
回答:
マウスアウトでタイムアウトを設定してフェードアウトし、戻り値をオブジェクトのデータに保存します。次に、データに値がある場合は、マウスオーバーでタイムアウトをキャンセルします。
フェードアウトのコールバック時にデータを削除します。
子のマウスオーバー/マウスアウトが発生したときにメニューに対して起動しないため、mouseenter / mouseleaveを使用する方が実際には安価です。
このコードは、ハッピータイムハリーと私が言おうとしていることを示しています。マウスが入るとツールチップが表示され、マウスが離れるとツールチップが消えるまでの遅延が設定されます。遅延がトリガーされる前にマウスが同じ要素に入ると、前に保存したデータを使用してトリガーが消える前に破棄します。
$("someelement").mouseenter(function(){
clearTimeout($(this).data('timeoutId'));
$(this).find(".tooltip").fadeIn("slow");
}).mouseleave(function(){
var someElement = $(this),
timeoutId = setTimeout(function(){
someElement.find(".tooltip").fadeOut("slow");
}, 650);
//set the timeoutId, allowing us to clear this trigger if the mouse comes back over
someElement.data('timeoutId', timeoutId);
});
クリーンでエレガントなホバーチェック:
if ($('#element:hover').length != 0) {
// do something ;)
}
警告:is(':hover')jquery 1.8以降では非推奨です。解決策については、この投稿を参照してください。
次の回答を使用することもできます:https : //stackoverflow.com/a/6035278/8843で、マウスが要素の上にあるかどうかをテストします。
$('#test').click(function() {
if ($('#hello').is(':hover')) {
alert('hello');
}
});
document.querySelectorAll(':hover')
jQueryのhoverイベントを使用して、手動で追跡できます。
$(...).hover(
function() { $.data(this, 'hover', true); },
function() { $.data(this, 'hover', false); }
).data('hover', false);
if ($(something).data('hover'))
//Hovered!
$.data文字列操作は含まれません。
私はこれとまったく同じものが必要だったので(少し複雑な環境で、「mouseenter」と「mouseleaves」の多くが適切に機能していなかったソリューションでは)、メソッドismouseoverを追加する小さなjqueryプラグインを作成しました。これまでのところ、かなりうまくいきました。
//jQuery ismouseover method
(function($){
$.mlp = {x:0,y:0}; // Mouse Last Position
function documentHandler(){
var $current = this === document ? $(this) : $(this).contents();
$current.mousemove(function(e){jQuery.mlp = {x:e.pageX,y:e.pageY}});
$current.find("iframe").load(documentHandler);
}
$(documentHandler);
$.fn.ismouseover = function(overThis) {
var result = false;
this.eq(0).each(function() {
var $current = $(this).is("iframe") ? $(this).contents().find("body") : $(this);
var offset = $current.offset();
result = offset.left<=$.mlp.x && offset.left + $current.outerWidth() > $.mlp.x &&
offset.top<=$.mlp.y && offset.top + $current.outerHeight() > $.mlp.y;
});
return result;
};
})(jQuery);
次に、ドキュメントの任意の場所で次のように呼び出して、trueまたはfalseを返します。
$("#player").ismouseover()
IE7 +、Chrome 1 +、Firefox 4でテストし、正常に動作しています。
jQueryでは.is( ':hover')を使用できるため、
function IsMouseOver(oi)
{
return $(oi).is(':hover');
}
OPで要求された機能を提供する最も簡潔な方法になります。
注:上記はIE8以下では機能しません
IE8で機能する簡潔な代替手段として(IE9のIE8モードを信頼できる場合)、$(...).hover(...)場所全体をトリガーせず、要素のセレクターを知る必要もありません(その場合、Ivoの回答の方が簡単です)。
function IsMouseOver(oi)
{
return oi.length &&
oi.parent()
.find(':hover')
.filter(function(s){return oi[0]==this})
.length > 0;
}
$(':hover') ん IE8で仕事を。これは有効なCSS2疑似セレクターなので、機能するはずです。
私はSLaksのアイデアを取り入れ、それを少人数のクラスにまとめました。
function HoverWatcher(selector){
this.hovering = false;
var self = this;
this.isHoveringOver = function() {
return self.hovering;
}
$(selector).hover(function() {
self.hovering = true;
}, function() {
self.hovering = false;
})
}
var box1Watcher = new HoverWatcher('#box1');
var box2Watcher = new HoverWatcher('#box2');
$('#container').click(function() {
alert("box1.hover = " + box1Watcher.isHoveringOver() +
", box2.hover = " + box2Watcher.isHoveringOver());
});
これの将来の発見者のためにちょうど参考にしてください。
私はこれとそれ以上のことができるjQueryプラグインを作成しました。私のプラグインでは、現在カーソルが置かれているすべての要素を取得するには、単に次のようにします。
$.cursor("isHover"); // will return jQ object of all elements the cursor is
// currently over & doesn't require timer
コメントできないので、これを答えとして書きます!
CSSセレクター ":hover"とホバーイベントの違いを理解してください!
":hover"はcssセレクターであり$("#elementId").is(":hover")、このように使用すると実際にイベントとともに削除されましたが、その意味ではjQueryイベントホバーとはまったく関係ありません。
コード化した$("#elementId:hover")場合、要素はマウスでホバーしたときにのみ選択されます。上記のステートメントは、純粋で正当なcss選択でこの要素を選択するときに、すべてのjQueryバージョンで機能します。
一方、イベントホバーは
$("#elementId").hover(
function() {
doSomething();
}
);
実際、jQuery 1.8として非推奨になりました。ここでは、jQuery Webサイトの状態です。
イベント名「hover」が使用されている場合、イベントサブシステムはイベント文字列で「mouseenter mouseleave」に変換します。これはいくつかの理由で迷惑です:
セマンティクス:ホバリングは、マウスが要素に出入りすることと同じではありません。発砲する前に、ある程度の減速または遅延があることを意味します。イベント名:添付されたハンドラーによって返されるevent.typeはホバーではなく、mouseenterまたはmouseleaveのいずれかです。他のイベントはこれを行いません。「hover」の名前の併用:「hover」という名前のイベントを添付して、.trigger( "hover")を使用してイベントを起動することはできません。ドキュメントはすでにこの名前を「新しいコードには強く非推奨」と呼んでいますが、正式には1.8で非推奨にし、最終的には削除したいと思います。
彼らが使用法を削除した理由is( ":hover")は不明ですが、まあ、あなたはまだ上記のように使用できます。
(function ($) {
/**
* :hover selector was removed from jQuery 1.8+ and cannot be used with .is(":hover")
* but using it in this way it works as :hover is css selector!
*
**/
$.fn.isMouseOver = function() {
return $(this).parent().find($(this).selector + ":hover").length > 0;
};
})(jQuery);
ああ、私はタイムアウトバージョンを推奨しません。これは非常に複雑になるためです。他に方法がない場合は、この種のものにタイムアウト機能を使用し、すべての場合の95%で別の方法があると信じてください。
私がそこのカップルの人々を助けることができれば幸いです。
グリーツアンディ
お二人に感謝します。ある時点で、マウスがまだ要素の上にあるかどうかを検出しようとするのをやめなければなりませんでした。私はそれが可能であることを知っていますが、達成するには多くのコードが必要になる場合があります。
少し時間がかかりましたが、私はあなたの両方の提案を受け入れ、私に役立つ何かを思いつきました。
簡単な(ただし機能的な)例を次に示します。
$("[HoverHelp]").hover (
function () {
var HelpID = "#" + $(this).attr("HoverHelp");
$(HelpID).css("top", $(this).position().top + 25);
$(HelpID).css("left", $(this).position().left);
$(HelpID).attr("fadeout", "false");
$(HelpID).fadeIn();
},
function () {
var HelpID = "#" + $(this).attr("HoverHelp");
$(HelpID).attr("fadeout", "true");
setTimeout(function() { if ($(HelpID).attr("fadeout") == "true") $(HelpID).fadeOut(); }, 100);
}
);
そして、これをいくつかのテキストで機能させるには、これが私がしなければならないすべてです:
<div id="tip_TextHelp" style="display: none;">This help text will show up on a mouseover, and fade away 100 milliseconds after a mouseout.</div>
This is a <span class="Help" HoverHelp="tip_TextHelp">mouse over</span> effect.
多くの豪華なCSSとともに、これはいくつかの非常に素晴らしいマウスオーバーヘルプツールチップを許可します。ちなみに、チェックボックスとテキストの間にわずかな隙間があるため、マウスを動かすとヘルプが点滅するため、マウスアウトの遅延が必要でした。しかし、これは魅力のように機能します。フォーカス/ぼかしイベントについても同様のことを行いました。
私はこれに使用されるタイムアウトをよく見ますが、イベントのコンテキストでは、次のように座標を見ることができませんか?:
function areXYInside(e){
var w=e.target.offsetWidth;
var h=e.target.offsetHeight;
var x=e.offsetX;
var y=e.offsetY;
return !(x<0 || x>=w || y<0 || y>=h);
}
コンテキストによっては、areXYInside(e)を呼び出す前に(this == e.target)を確認する必要がある場合があります。
fyi-私はdragLeaveハンドラー内でこのアプローチを使用して、子要素に移動することによってdragLeaveイベントがトリガーされなかったことを確認しています。まだ親要素内にいることを何らかの方法で確認しないと、本当に親を離れた場合にのみ意図されているアクションを誤って実行する可能性があります。
編集:これは良いアイデアですが、一貫して十分に機能しません。おそらく、いくつかの小さな調整が必要です。
jQuery子divに特定のクラスがあるかどうかをテストできます。次に、特定のdivの上にマウスを置いたり外したりしたときにそのクラスを適用することで、ページ上の別の要素の上にマウスを置いた場合でも、マウスがその上にあるかどうかをテストできます。ポップアップでdivの間にスペースがあったため、これを使用しました。ポップアップのスペースの上にマウスを移動しているときではなく、ポップアップから離れたときにポップアップを閉じたいだけでした。したがって、コンテンツdiv(ポップアップが終了した)でマウスオーバー関数を呼び出しましたが、コンテンツdivにマウスオーバーしたときにポップアップ関数の外側にあるときにのみ、閉じる関数がトリガーされました!
$( "。pop-up")。mouseover(function(e)
{
$(this).addClass( "over");
});
$( "。pop-up")。mouseout(function(e)
{
$(this).removeClass( "over");
});
$( "#mainContent")。mouseover(function(e){
if(!$( "。expanded")。hasClass( "over")){
Drupal.dhtmlMenu.toggleMenu($( "。expanded"));
}
});
jqueryに依存せず、ネイティブDOM matches APIを使用する手法を次に示します。ベンダープレフィックスを使用して、IE9に戻るブラウザーをサポートします。詳細については、caniuse.comのmatchselectorを参照してください。
まず、次のように、matchesSelector関数を作成します。
var matchesSelector = (function(ElementPrototype) {
var fn = ElementPrototype.matches ||
ElementPrototype.webkitMatchesSelector ||
ElementPrototype.mozMatchesSelector ||
ElementPrototype.msMatchesSelector;
return function(element, selector) {
return fn.call(element, selector);
};
})(Element.prototype);
次に、ホバーを検出するには:
var mouseIsOver = matchesSelector(element, ':hover');
私はあなたが必要とするかもしれないすべての詳細で、別の質問でこれに答えました:
jQueryを使用して要素にホバーしているIFを検出します(執筆時点では99の賛成票があります)。
基本的には、次のようなことができます。
var ishovered = oi.is(":hover");
これoiは、が1つの要素を含むjQueryオブジェクトである場合にのみ機能します。一致する要素が複数ある場合は、各要素に適用する必要があります。次に例を示します。
var hoveredItem = !!$('ol>li').filter(function() { return $(this).is(":hover"); });
// not .filter(':hover'), as we can't apply :hover on multiple elements
これはjQuery 1.7以降でテストされました。
マウスが要素内にあるかどうかを確認するのに役立つ関数を次に示します。あなたがしなければならない唯一のことは、ライブマウスに関連付けられたEventObjectを持つことができる関数を呼び出すことです。このようなもの:
$("body").mousemove(function(event){
element_mouse_is_inside($("#mycontainer", event, true, {});
});
ソースコードは、githubまたは投稿の下部にあります。
https://github.com/mostafatalebi/ElementsLocator/blob/master/elements_locator.jquery.js
function element_mouse_is_inside (elementToBeChecked, mouseEvent, with_margin, offset_object)
{
if(!with_margin)
{
with_margin = false;
}
if(typeof offset_object !== 'object')
{
offset_object = {};
}
var elm_offset = elementToBeChecked.offset();
var element_width = elementToBeChecked.width();
element_width += parseInt(elementToBeChecked.css("padding-left").replace("px", ""));
element_width += parseInt(elementToBeChecked.css("padding-right").replace("px", ""));
var element_height = elementToBeChecked.height();
element_height += parseInt(elementToBeChecked.css("padding-top").replace("px", ""));
element_height += parseInt(elementToBeChecked.css("padding-bottom").replace("px", ""));
if( with_margin)
{
element_width += parseInt(elementToBeChecked.css("margin-left").replace("px", ""));
element_width += parseInt(elementToBeChecked.css("margin-right").replace("px", ""));
element_height += parseInt(elementToBeChecked.css("margin-top").replace("px", ""));
element_height += parseInt(elementToBeChecked.css("margin-bottom").replace("px", ""));
}
elm_offset.rightBorder = elm_offset.left+element_width;
elm_offset.bottomBorder = elm_offset.top+element_height;
if(offset_object.hasOwnProperty("top"))
{
elm_offset.top += parseInt(offset_object.top);
}
if(offset_object.hasOwnProperty("left"))
{
elm_offset.left += parseInt(offset_object.left);
}
if(offset_object.hasOwnProperty("bottom"))
{
elm_offset.bottomBorder += parseInt(offset_object.bottom);
}
if(offset_object.hasOwnProperty("right"))
{
elm_offset.rightBorder += parseInt(offset_object.right);
}
var mouseX = mouseEvent.pageX;
var mouseY = mouseEvent.pageY;
if( (mouseX > elm_offset.left && mouseX < elm_offset.rightBorder)
&& (mouseY > elm_offset.top && mouseY < elm_offset.bottomBorder) )
{
return true;
}
else
{
return false;
}
}
'Happytime harry'の発言を拡張して、必ず.data()jquery関数を使用してタイムアウトIDを格納してください。これは、後で同じ要素で 'mouseenter'がトリガーされたときにタイムアウトIDを非常に簡単に取得できるようにするためであり、ツールチップが消えるトリガーを排除できます。
jQueryのmouseenterイベントとmouseleaveイベントを使用できます。マウスが目的の領域に入ったときにフラグを設定し、領域から離れたときにフラグを設定解除できます。
このトピックのアイデアを組み合わせてこれを思いつきました。これはサブメニューの表示/非表示に役立ちます。
$("#menu_item_a").mouseenter(function(){
clearTimeout($(this).data('timeoutId'));
$("#submenu_a").fadeIn("fast");
}).mouseleave(function(){
var menu_item = $(this);
var timeoutId = setTimeout(function(){
if($('#submenu_a').is(':hover'))
{
clearTimeout(menu_item.data('timeoutId'));
}
else
{
$("#submenu_a").fadeOut("fast");
}
}, 650);
menu_item.data('timeoutId', timeoutId);
});
$("#submenu_a").mouseleave(function(){
$(this).fadeOut("fast");
});
私のために働くようです。これが誰かを助けることを願っています。
編集:今、このアプローチの実現はIEで正しく機能していません。
上記の提案はどれも使用できませんでした。
なぜ私のソリューションを好むのですか?
このメソッドは、あなたが選択した任意の時点でマウスが要素上にあるかどうかをチェックします。
Mouseenterと:hoverは便利ですが、mouseenterは、要素がマウスの下に移動したときではなく、マウスを動かした場合にのみトリガーされます。
:ホバーはかなり甘いですが... IE
だから私はこれをします:
いいえ1.必要に応じて移動するたびにマウスのx、y位置を保存します。
いいえ2.クエリに一致する要素の上にマウスがあるかどうかを確認します... mouseenterイベントのトリガーなど
// define mouse x, y variables so they are traced all the time
var mx = 0; // mouse X position
var my = 0; // mouse Y position
// update mouse x, y coordinates every time user moves the mouse
$(document).mousemove(function(e){
mx = e.pageX;
my = e.pageY;
});
// check is mouse is over an element at any time You need (wrap it in function if You need to)
$("#my_element").each(function(){
boxX = $(this).offset().left;
boxY = $(this).offset().top;
boxW = $(this).innerWidth();
boxH = $(this).innerHeight();
if ((boxX <= mx) &&
(boxX + 1000 >= mx) &&
(boxY <= my) &&
(boxY + boxH >= my))
{
// mouse is over it so you can for example trigger a mouseenter event
$(this).trigger("mouseenter");
}
});
is(':visible');jqueryで使用でき、$( '。item:hover')の場合はJqueryでも機能します。
これはhtmコードのスニペットです:
<li class="item-109 deeper parent">
<a class="root" href="/Comsopolis/index.php/matiers"><span>Matiers</span></a>
<ul>
<li class="item-110 noAff">
<a class=" item sousMenu" href="/Comsopolis/index.php/matiers/tsdi">
<span>Tsdi</span>
</a>
</li>
<li class="item-111 noAff">
<a class="item" href="/Comsopolis/index.php/matiers/reseaux">
<span>Réseaux</span>
</a>
</li>
</ul>
</li>
そしてこれはJSコードです:
$('.menutop > li').hover(function() {//,.menutop li ul
$(this).find('ul').show('fast');
},function() {
if($(this).find('ul').is(':hover'))
$(this).hide('fast');
});
$('.root + ul').mouseleave(function() {
if($(this).is(':visible'))
$(this).hide('fast');
});
これは私が話していたものです:)