IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Bibliothèques & Frameworks Discussion :

Une vrai fonction détectant la position du curseur ?


Sujet :

Bibliothèques & Frameworks

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné
    Avatar de FMaz
    Inscrit en
    Mars 2005
    Messages
    643
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 643
    Par défaut Une vrai fonction détectant la position du curseur ?
    Bonjour à tous.
    Je profite de mon heure de diner pour vous soumettre un problème qui me coupe beaucoup d'heures de sommeil ces derniers temps.


    Avant de commencer, note aux modo/admin:
    Pourquoi n'y a t-il pas une section javascript générale dans laquelle je peux poster ma question ? Ceci n'est ni une contribution, ni un article, ni rien qui puisse être classifié dans les catégories disponibles. Alors j'ai choisi Prototype, vu que je l'utilise, mais ca n'a aucun lien direct.


    Voici une fonction de détection de position du curseur que tout le monde semble vénéré à tort:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    findPosY = function(obj){
      var curtop =0;
      if(obj.offsetParent){
         while(obj.offsetParent){
           curtop += obj.offsetTop;
           obj.parentOffset;
         }
       }
       return curtop;
    }
    Je dis à tord pour 2 raisons qui me pose problème.
    La première est que cette fonction ne retournera pas un bon résultat si l'élément déclanchant l'évènement est situé à l'intérieur d'une ou plusieurs zones en position:absolute ou position:relative.

    Le second cas de figure que j'ai trouvé dans lequel cette fonction retournera une valeur incorrecte est lorsque l'élément déclanchant l'évènement est situé à l'intérieur d'une zone en overflow:scroll-y. Dès que la zone n'est plus en position scrollTop==0, la valeur scrollTop n'est pas soustraite du total, et PAF! la position de curseur est rendu 400px trop bas.

    Là où c'est un problème, c'est que dans plusieurs cas, la zone en overflow:scroll-y (ou auto) n'est pas un parentOffset. Pour être un parentOffset, il semble falloir que la zone représente aux yeux du navigateur une altération de l'offset. Si vous avez un DIV top:0, margin-top:0, padding-top:0, border-top:0, l'offset ne sera pas modifié par cet élément, et la boucle de récursion ne tombera pas sur le DIV avec le scroll.

    Alors j'ai essayé de remplacer obj.parentOffset par obj.parentNode, afin de boucler dans tous les éléments. Mais ma solution m'apporte un nouveau problème. Certe, le scrollTop requis est maintenant retiré, mais j'ai tout un tas d'éléments qui semblent avoir des valeurs offsetTop dont je me fout éperduement et qu'il ne devrait pas être prises en compte.


    Bref, comment puis-je RÉELLEMENT connaitre la position du curseur sur la page ? Ca m'importe peu de devoir utiliser une librairie de 50Kb, j'ai besoin d'une vrai solution.

  2. #2
    Membre Expert
    Avatar de gwyohm
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2007
    Messages
    925
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2007
    Messages : 925
    Par défaut
    Salut,
    Citation Envoyé par FMaz Voir le message
    Je profite de mon heure de diner pour vous soumettre un problème qui me coupe beaucoup d'heures de sommeil ces derniers temps.
    Faut pas que le javascript t'empêche de dormir ou te coupe l'appétit !

    Citation Envoyé par FMaz Voir le message
    Avant de commencer, note aux modo/admin:
    Pourquoi n'y a t-il pas une section javascript générale dans laquelle je peux poster ma question ?
    Euh... le forum javascript tout court ne te convient pas ?
    Citation Envoyé par FMaz Voir le message
    ... Alors j'ai choisi Prototype, vu que je l'utilise, mais ca n'a aucun lien direct... comment puis-je RÉELLEMENT connaitre la position du curseur sur la page.
    Donc vu que tu as mis dans le forum dédié à prototype, je te propose d'utiliser les apis standard de prototype. Dans cet exemple, j'ai essayé de reproduire tes cas (mais j'ai peut être pas compris ou tout faux parce que je n'ai pas de problème).

    Donc toutes les divs observent le click et executent le même listener qui affiche les coordonnées et positionne des divs pour montrer la position...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
     
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <title>Test cursor pos</title>
    <script src="http://www.google.com/jsapi"></script>
    <script type="text/javascript">
    google.load("prototype", "1.6.1.0");
    </script>
    <script type="text/javascript">
    function whereAmI(e) {
    	$("message").update("Capturé par " + e.element().identify() + ";X:" + e.pointerX() + ";Y:" + e.pointerY());
    	$("axisX").setStyle({left: e.pointerX() + "px"});
    	$("axisY").setStyle({top: e.pointerY() + "px"});
    	e.stop();
    }
     
    Event.observe(window, "load", function() {
    	$("axisX").setStyle({height: document.viewport.getHeight() + "px"});
    	$("axisY").setStyle({width: document.viewport.getWidth() + "px"});
    	$$("div").invoke("observe", "click", whereAmI);
    });
    </script>
    <style type="text/css">
     
    	.coord {
    		left:0;
    		top:0;
    		position:absolute;
    		background-color: blue;
    		z-index:1000;
    	}
     
    	#axisX {
    		width:1px;
     
    	}
    	#axisY {
    		height:1px;
    	}
     
    </style>
    </head>
    <body>
    <span id="message">Message</span>
    <div style="margin-top:20px;padding-left:30px;background-color:red;" id="red">
     
    	<div style="position:relative;top:20px;left;30px;background-color:yellow" id="yellow">
    	</div>
    	<div style="position:relative;width:300px;height:180px;background-color:orange;" id="orange">
    		<div style="position:absolute;bottom:20px;right:30px;background-color:green;width:50px;height:50px;" id="green">
    		</div>
    	</div>
    	<div style="position:relative;width:300px;height:180px;background-color:maroon;float:left" id="maroon">
    		<div style="background-color:gold;width:50px;height:50px;float:right;overflow:scroll" id="gold">
    			<div style="margin-top:50px;height:20px;width:20px;background-color:pink" id="pink">
    			</div>
    		</div>
    	</div>
    </div>
    <div id="axisX" class="coord"></div>
    <div id="axisY" class="coord"></div>
    </body>
    </html>

  3. #3
    Membre chevronné
    Avatar de FMaz
    Inscrit en
    Mars 2005
    Messages
    643
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 643
    Par défaut
    Hum, je crois que je suis parfois très distrait.

    Pour le forum javascript, je viens de vérifier et c'est bon. Je crois que je devais être dans TOUS... et là je ne trouvais plus d'icone pour créer un nouveau sujet.

    Je ne connaissais pas les fonctions pointerX(), c'est une sacré belle découverte. Et oui, ca doit fonctionner puisque prototype doit faire tout le travail à l'interne pour contourner le problème.

    Ceci étant dis, comme j'ai un expert de prototype sous la main, est-ce qu'il existe des fonction du genre:
    $('objet').getAbsoluteLeft();
    $('objet').getAbsoluteTop();
    $('objet').getWidth(); (Edit: http://www.tutorialspoint.com/protot...t_getwidth.htm )
    $('objet').getHeight(); (Edit: http://www.tutorialspoint.com/protot..._getheight.htm )

    ?


    Sérieusement, merci beaucoup, je crois que je vais pouvoir couper 5-10% de code juste avec les nouveaux pointerX et pointerY !


    Edit: Je pense que pour les getAbsoluteLeft et getAbsoluteTop, ce serait comme avec viewportOffset(), mais je suis pas certain, quelqu'un pourrait me confirmer ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
      var coordinates = $('visible').viewportOffset();
       alert("Distance from the Left : " +  coordinates[0] );
       alert("Distance from the Top  : " +  coordinates[1] );
    Src.: http://www.tutorialspoint.com/protot...portoffset.htm


    ps.: S'était pas une blague, j'ai eu droit à 3h de sommeil la nuit précédente quand j'avais posté le sujet initial. Pas étonnant que j'ai pas vu qu'il y avait un forum en dessous des catégories ! :p ... le problème n'était pas que javascript m'empêchait de dormir, c'est qu'il m'empêchait d'aller dormir, nuance

  4. #4
    Membre Expert
    Avatar de gwyohm
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2007
    Messages
    925
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2007
    Messages : 925
    Par défaut
    Citation Envoyé par FMaz Voir le message
    est-ce qu'il existe des fonction du genre:
    $('objet').getAbsoluteLeft();
    $('objet').getAbsoluteTop();
    Oui, en fait on peut obtenir les coordonnées des elements dans plusieurs repères :
    cumulativeOffset
    cumulativeScrollOffset
    positionedOffset
    et viewportOffset

    pour plus de détail, voir la doc de l'API
    Citation Envoyé par FMaz Voir le message
    je vais pouvoir couper 5-10% de code juste avec les nouveaux pointerX et pointerY !
    Oui, mais attention cependant, ce sont des méthodes de l'objet Event, il faut donc être dans le contexte d'un listener sur un évènement impliquant la souris

  5. #5
    Membre Expert
    Avatar de gwyohm
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2007
    Messages
    925
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2007
    Messages : 925
    Par défaut
    Citation Envoyé par FMaz Voir le message
    Edit: Je pense que pour les getAbsoluteLeft et getAbsoluteTop, ce serait comme avec viewportOffset(), mais je suis pas certain, quelqu'un pourrait me confirmer ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
      var coordinates = $('visible').viewportOffset();
       alert("Distance from the Left : " +  coordinates[0] );
       alert("Distance from the Top  : " +  coordinates[1] );
    Oui, c'est exactement ça. Cependant pour plus de lisibilité, je préfère :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
      var coordinates = $('visible').viewportOffset();
       alert("Distance from the Left : " +  coordinates.left );
       alert("Distance from the Top  : " +  coordinates.top );

  6. #6
    Membre chevronné
    Avatar de FMaz
    Inscrit en
    Mars 2005
    Messages
    643
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 643
    Par défaut
    Ah oui, en effet, c'est plus clair avec les attributs qu'avec un tableau.

    Cependant, ce que je lis dans la documentation ne semble pas bien fonctionner.


    Si je résume:
    cumulativeOffset
    Position de l'élément à partir du coin supérieur gauche (0,0) du document.

    viewportOffset
    Position de l'élément dans la zone affichable du navigateur, si l'élément est à la position absolue 0px,700px, et que le page est scrollée de 200px, la position affichée devrait être de 0px, 500px. Autrement dit, ca donne la position 'fixed' de l'élément.



    Sauf que lorsque je regarde l'exemple de viewportOffset():
    http://www.tutorialspoint.com/cgi-bi...e=prototype_46

    ... scroller ne change rien à la valeur affiché. De plus, l'élément est à bien plus de 50px de la gauche. Il devrait être à plus de 500px de la gauche !

    lorsque je regarde l'exemple de cumulativeOffset():
    http://www.tutorialspoint.com/cgi-bi...e=prototype_18

    ... encore une fois je m'attendrais à obtenir une valeur de plus de 500px pour la gauche, et je n'ai que 8px !

  7. #7
    Membre Expert
    Avatar de gwyohm
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2007
    Messages
    925
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2007
    Messages : 925
    Par défaut
    Attention ! sur le site que tu mentionnes, la zone de droite est une iframe !

Discussions similaires

  1. Réponses: 7
    Dernier message: 31/07/2008, 08h31
  2. Réponses: 4
    Dernier message: 12/03/2007, 19h15
  3. Position du curseur réinitialisée au survol d'une div (sur IE) :/
    Par Huntress dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 31/08/2006, 23h07
  4. [VB6] position du curseur dans une zone texte et insertion caractere
    Par tim69000 dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 05/05/2006, 09h52
  5. Obtenir la position du curseur dans une Image
    Par bastoune dans le forum Composants VCL
    Réponses: 6
    Dernier message: 14/11/2003, 21h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo