J'essaie de créer des événements personnalisés dans JQuery qui sont censés détecter le clic sur une barre de défilement. 1 .
Je sais qu'il y a beaucoup de texte, mais toutes mes questions sont en caractères gras et il y a un Exemple de JSFiddle sur lesquels vous pouvez travailler immédiatement.
Parce que je n'ai pas trouvé de fonctionnalité intégrée pour cela,
J'ai dû créer un hasScroll
qui vérifie si l'élément a une barre de défilement,
$.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;
};
et un inScrollRange
en vérifiant si le clic effectué se situe dans la plage de défilement.
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;
}
Les tailles des barres de défilement sont-elles toutes uniformes ? Par exemple, dans Firefox et IE, elle est de 18px.
En supposant qu'il n'y a pas de barres de défilement personnalisées, y a-t-il un rembourrage ou des tailles supplémentaires dans certains navigateurs ?
Ces fonctions fonctionnent toutes comme prévu (d'après ce que je peux discerner).
La création d'événements personnalisés était un peu plus délicate, mais j'ai réussi à la faire fonctionner quelque peu. Le seul problème est que si l'élément cliqué a un événement mousedown/up attaché à lui, il sera également déclenché.
Je ne parviens pas à empêcher les autres événements de se déclencher tout en déclenchant simultanément ce que j'appelle les événements 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.");
});
Comment puis-je empêcher les autres événements "clic" de se déclencher ?
Pendant que je vous le demande, n'hésitez pas à optimiser le code autant que possible.
Voici un JSFiddle avec lequel vous pouvez vous amuser.
La raison pour laquelle je fais ceci est à cause d'un plus gros plugin que je suis en train de développer. Il possède un menu contextuel personnalisé qui s'affiche lorsque je fais un clic droit sur l'un des dérouleurs. Je ne veux pas de ça. J'ai donc pensé que je devais créer un événement qui vérifie les clics de défilement (mouseup/downs) et qui empêche l'affichage du menu contextuel. Pour cela, il faut que le clic de défilement précède le clic normal et, si possible, qu'il empêche les clics normaux de se déclencher.
Je pense juste à voix haute ici mais Il y a peut-être un moyen de récupérer toutes les fonctions liées à l'élément et de changer l'ordre dans lequel elles ont été ajoutées ? Je sais que les fonctions sont exécutées dans l'ordre dans lequel elles ont été ajoutées (1ère ajoutée 1ère appelée), donc, si je pouvais exploiter ce processus, peut-être que l'ensemble de "l'enregistrement" de l'événement à JQuery pourrait simplement être inséré avant les événements de clic.
1 ne peut utiliser que le mousedown/mouseup parce que le click ne se déclenche pas en cliquant sur une barre de défilement. Si c'est faux, veuillez fournir un exemple de fonctionnement/code.
2 votes
Les tailles des barres de défilement ne sont pas uniformes. Dans webkit, vous pouvez les personnaliser assez fortement. css-tricks.com/examples/WebKitScrollbars
0 votes
Quel est votre objectif avec ce plugin ?
0 votes
@mrtsherman C'est juste une partie mineure d'un plus gros plugin, mais l'idée est de désélectionner un élément dans une liste lorsque l'utilisateur fait un clic de souris n'importe où dans le contenu, mais pas lorsque l'utilisateur clique sur le scroller. L'élément de la liste a déjà beaucoup d'événements de clics, mais je ne veux pas qu'ils se déclenchent lorsque le scroller est cliqué.
0 votes
@mrtsherman Comment puis-je obtenir la taille (si elle existe) de la barre de défilement personnalisée pour le webkit en JQuery/Javascript ?
1 votes
Veuillez ne pas modifier le comportement standard de
<select multiple>
contrôles. Il est profondément ennuyeux qu'elles ne se comportent pas comme les utilisateurs l'attendent. Par exemple, shift-clic pour sélectionner une plage, ctrl-clic pour sélectionner des éléments spécifiques. Dans certaines applications, chaque clic sur un élément fait basculer son état, ce qui n'est évidemment pas ce que l'on attend. Donc : gardez le comportement par défaut o utiliser un widget entièrement personnalisé qui ne ressemble pas à un contrôle ordinaire comme cela se produirait, par exemple, dans une application native2 votes
@ThiefMaster Je suis déjà au courant de cela, mais ce ne devrait pas affectent le comportement par défaut du défilement des navigateurs. Peut-être avez-vous mal compris ce que j'essaie de faire ? Le but est d'ajouter des événements supplémentaires à JQuery pour que je puisse faire en sorte que mes autres plugins fassent des choses lorsqu'ils sont cliqués. Plus de fonctionnalités -> plus d'options. Dans mon exemple, j'ai créé un menu contextuel personnalisé, mais je ne veux pas que le menu contextuel soit affiché si l'utilisateur fait un clic droit sur la barre de défilement (imiter le même comportement que le menu du navigateur). Pour résoudre ce problème, j'ai pensé que je pouvais ajouter un événement qui empêche le menu contextuel de s'afficher.
0 votes
@ThiefMaster De plus, quand je dis select, je veux dire supprimer/ajouté une classe appelée "select", rien d'autre.
0 votes
Je constate déjà que le fait de cliquer sur les barres de défilement ne déclenche pas d'événements. J'ai testé IE9, Chrome et FF. jsfiddle.net/dX5pm
1 votes
@mrtsherman Oui, mais ils se déclenchent sur
mousedown
ymouseup
. Je les appelle des événements de "clic" dans mon article, puis je l'explique également tout en bas.1 votes
Ahh, je vois. Merci de l'avoir clarifié pour moi. +1 et favorisé. J'espère voir une réponse (je suis sûr que vous aussi !)
0 votes
@ShadowScripter bonjour, pour les autres utilisateurs, j'ai ajouté une solution beaucoup plus courte ci-dessous.