スクロールバーがクリックされたときに検出することになっているカスタムイベントをJQueryで作成しようとしています1。
たくさんのテキストがあることは知っていますが、私の質問はすべて太字で示され、すぐに作業できるJSFiddleの例があります。
このための組み込み機能が見つからなかったため、要素にスクロールバーがあるかどうかを確認して、関数
を作成する必要がありました。hasScroll
$.fn.hasScroll = function(axis){
var overflow = this.css("overflow"),
overflowAxis;
if(typeof axis == "undefined" || axis == "y") overflowAxis = this.css("overflow-y");
else overflowAxis = this.css("overflow-x");
var bShouldScroll = this.get(0).scrollHeight > this.innerHeight();
var bAllowedScroll = (overflow == "auto" || overflow == "visible") ||
(overflowAxis == "auto" || overflowAxis == "visible");
var bOverrideScroll = overflow == "scroll" || overflowAxis == "scroll";
return (bShouldScroll && bAllowedScroll) || bOverrideScroll;
};
inScrollRange
実行されたクリックがスクロール範囲内にあるかどうかをチェックする関数。
var scrollSize = 18;
function inScrollRange(event){
var x = event.pageX,
y = event.pageY,
e = $(event.target),
hasY = e.hasScroll(),
hasX = e.hasScroll("x"),
rX = null,
rY = null,
bInX = false,
bInY = false
if(hasY){
rY = new RECT();
rY.top = e.offset().top;
rY.right = e.offset().left + e.width();
rY.bottom = rY.top +e.height();
rY.left = rY.right - scrollSize;
//if(hasX) rY.bottom -= scrollSize;
bInY = inRect(rY, x, y);
}
if(hasX){
rX = new RECT();
rX.bottom = e.offset().top + e.height();
rX.left = e.offset().left;
rX.top = rX.bottom - scrollSize;
rX.right = rX.left + e.width();
//if(hasY) rX.right -= scrollSize;
bInX = inRect(rX, x, y);
}
return bInX || bInY;
}
すべてのスクロールバーのサイズは均一ですか?たとえば、FirefoxとIEでは18pxです。
カスタマイズされたスクロールバーがないと仮定すると、一部のブラウザに余分なパディングやサイズはありますか?
これらの機能はすべて意図したとおりに機能します(私が認識できることから)。
カスタムイベントの作成は少しトリッキーでしたが、ある程度機能するようになりました。唯一の問題は、クリックされた要素にmousedown / upイベントがアタッチされている場合、それもトリガーされることです。
他のイベントのトリガーを停止すると同時に、私が呼んでいる、mousedownScroll/mouseupScrollイベントを同時にトリガーすることはできないようです。
$.fn.mousedownScroll = function(fn, data){
if(typeof fn == "undefined" && typeof data == "undefined"){
$(this).trigger("mousedownScroll");
return;
}
$(this).on("mousedownScroll", data, fn);
};
$.fn.mouseupScroll = function(fn, data){
if(typeof fn == "undefined" && typeof data == "undefined"){
$(this).trigger("mouseupScroll");
return;
}
$(this).on("mouseupScroll", data, fn);
};
$(document).on("mousedown", function(e){
if(inScrollRange(e)){
$(e.target).trigger("mousedownScroll");
}
});
$(document).on("mouseup", function(e){
if(inScrollRange(e)){
$(e.target).trigger("mouseupScroll");
}
});
$("selector").mousedown(function(e){
console.log("Clicked content."); //Fired when clicking scroller as well
});
$("selector").mousedownScroll(function(e){
console.log("Clicked scroller.");
});
他の「クリック」イベントのトリガーを停止するにはどうすればよいですか?
お願いしますが、できるだけコードを最適化してください。
私がこれを作っている理由は、私が開発しているより大きなプラグインのためです。スクローラーの1つを右クリックすると表示されるカスタムコンテキストメニューがあります。私はそれを望んでいません。そこで、スクロールクリック(マウスアップ/ダウン)をチェックするイベントを作成して、コンテキストメニューが表示されないようにする必要があると思いました。ただし、これを行うには、スクロールクリックを通常のクリックの前に配置し、可能であれば通常のクリックの発生を停止する必要があります。
ここで大声で考えているだけですが、要素にバインドされているすべての関数を取得して、それらが追加された順序を切り替える方法があるのではないでしょうか。関数は追加された順序(最初に追加された最初の呼び出し)で実行されることを知っているので、そのプロセスを利用できれば、JQueryへのイベントの「登録」全体をクリックイベントの前に挿入できます。
1は、スクロールバーをクリックしてもクリックがトリガーされないため、mousedown/mouseupのみを使用できます。これが誤りの場合は、実用的な例/コードを提供してください