72 votes

empêcher le défilement de l'élément vers la fenêtre

J'ai une fenêtre modale (pop-up) qui contient une iframe,
et à l'intérieur de cela iframe il y a un div qui peut défiler.

Lorsque je fais défiler le DIV interne de l'iframe, et qu'il a atteint sa limite supérieure ou inférieure,
la fenêtre du navigateur elle-même commence à défiler. il s'agit d'une comportement indésirable .

J'ai essayé quelque chose comme ceci, qui tue le défilement de la fenêtre principale lorsque
onMouseEnter lorsque la souris entre dans la zone de la boîte pop-up :

e.preventDefault() ne fonctionne pas comme il le devrait pour une raison quelconque...

$("#popup").mouseenter(function(){
   $(window).bind("scroll", function(e){
        e.preventDefault();
   }); 
}).mouseleave(function(){
    $(window).unbind("scroll");
});

Mise à jour

On dirait que maintenant, en 2013 e.preventDefault(); est suffisant...

0 votes

@RoatinMarth - puisque personne ne m'a demandé quand ils ont créé le navigateur, alors je suis laissé pour corriger leur mauvaise UX moi-même. si ce n'est pas évident pourquoi ce problème est indésirable alors je ne sais pas quoi vous dire .

28voto

bobince Points 270740

Désolé, pour autant que je sache, il est impossible d'annuler un quelconque événement de défilement.

Les deux sites W3 y MSDN dites :

Cancelable  No
Bubbles     No

Je pense qu'il faut laisser aux auteurs de navigateurs le soin de régler ce problème. Firefox (3.5 sous Linux, en tout cas) semble avoir un meilleur comportement pour moi : il ne fait défiler le parent que si l'enfant se trouve déjà en haut ou en bas de la page à ce moment-là. commencer en utilisant la molette de défilement.

4 votes

C'est possible - et relativement facile : stackoverflow.com/questions/5802467/

0 votes

En fonction de votre mise en page, vous pouvez définir le conteneur en position:fixed lorsque la souris entre dans la cible déroulante et le réinitialiser à ce qu'il était lorsque la souris quitte la cible déroulante. Mais n'oubliez pas que les périphériques tactiles ne peuvent pas faire de survol.

0 votes

Je peux annuler l'événement dans Chrome et FF maintenant.

17voto

Dr. Kohlschütter Points 1751

Si nous ne pouvons pas empêcher le défilement de la fenêtre, pourquoi ne pas l'annuler ? En d'autres termes, il s'agit d'intercepter l'événement de défilement et de revenir à une position fixe.

Le code suivant verrouille l'axe des Y tant que l'on passe la souris sur cet axe. $("#popup") :

// here we store the window scroll position to lock; -1 means unlocked
var forceWindowScrollY = -1;

$(window).scroll(function(event) {
  if(forceWindowScrollY != -1 && window.scrollY != forceWindowScrollY) {
    $(window).scrollTop(forceWindowScrollY);    
  }
});

$("#popup").hover(function() {
  if(forceWindowScrollY == -1) {
    forceWindowScrollY = $(window).scrollTop();
  }
}, function() {
  forceWindowScrollY = -1;
});

J'utilise ceci pour la boîte de suggestion de requête sur http://bundestube.de/ (entrez quelques caractères dans le champ de recherche supérieur pour rendre le volet défilant visible) :

Screenshot

Cela fonctionne parfaitement dans Chrome/Safari (Webkit) et avec quelques problèmes de défilement dans Firefox et Opera. Pour une raison quelconque, il ne fonctionne pas avec mon installation IE. Je suppose que cela a à voir avec la méthode de survol de jQuery, qui semble ne pas fonctionner correctement dans 100 % des cas.

0 votes

J'ai essayé votre site et il ne fonctionne pas pour moi avec Chrome / Firefox / Safari sur Mac.

0 votes

C'est étrange. Cela fonctionne parfaitement sur mon Mac (10.6.6). Parlons-nous de la même chose ? J'ai ajouté une capture d'écran pour plus de clarté. Les barres de défilement de la fenêtre ne sont désactivées que lorsque le pointeur de la souris se trouve sur la boîte à suggestions.

0 votes

@zaius Pourriez-vous réessayer ?

3voto

psycho brm Points 2298

Mon plugin jQuery :

$('.child').dontScrollParent();

$.fn.dontScrollParent = function()
{
    this.bind('mousewheel DOMMouseScroll',function(e)
    {
        var delta = e.originalEvent.wheelDelta || -e.originalEvent.detail;

        if (delta > 0 && $(this).scrollTop() <= 0)
            return false;
        if (delta < 0 && $(this).scrollTop() >= this.scrollHeight - $(this).height())
            return false;

        return true;
    });
}

0 votes

Semble, au moins le this.on('mousewheel DOMMouseScroll', function(){}) partie ( avis on au lieu de bind )

3voto

ghaxx Points 424

Je sais que c'est une vieille question, mais comme c'est l'un des premiers résultats dans Google... J'ai dû en quelque sorte annuler le scroll bubbling sans jQuery et ce code fonctionne pour moi :

function preventDefault(e) {
  e = e || window.event;
  if (e.preventDefault)
    e.preventDefault();
  e.returnValue = false;  
}

document.getElementById('a').onmousewheel = function(e) { 
  document.getElementById('a').scrollTop -= e. wheelDeltaY; 
  preventDefault(e);
}

3 votes

@vsync bien sûr, cela ne fonctionne pas, car l'iframe dans votre exemple est inter-domaine, et vous ne pouvez pas obtenir des événements pour le défilement et autres sur un iframe inter-domaine.

0voto

Dan F Points 7777

Apparemment, vous pouvez régler overflow:hidden pour empêcher le défilement . Je ne sais pas comment cela se passe si le document est déjà défilé. Je suis également sur un ordinateur portable sans souris, donc pas de test de la molette pour moi ce soir :-) Mais ça vaut probablement le coup d'essayer.

0 votes

J'ai besoin qu'il défile (long texte) la question ne tourne pas autour de ça.

0 votes

Oui, je pense qu'il faut définir overflow:hidden sur la fenêtre PARENT. Pas sur la iframe elle-même. Par conséquent, la fenêtre parent n'est plus déroulable, mais le contenu de l'iframe l'est.

2 votes

La barre de défilement disparaîtrait alors soudainement, et les objets se déplaceraient sur le côté ce n'est pas une bonne idée

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X