11487 sujets

JavaScript, DOM et API Web HTML5

Bonsoir
Je cherche à regarder si le curseur est ou non à l'intérieur d'un élément lorsqu'un évènement se produit.
Pour cela, j'utilise
1) les propriétés pageX et PageY
2) les propriétés left et top de element.getBoundingClientRect()

Je constate que le point de départ de ces deux séries de nombres ne semble pas exactement le même.
Je crois me souvenir que c'est plus ou moins "normal', si on peut dire, mais je ne me souviens plus très bien ce qu'il faut faire pour s'y retrouver.

Dans le temps, j'avais fait un objet "Rectangle" avec une fonction

this.refresh = function(){
    var curleft = 0, curtop = 0, obj = this.object;
    if (! this.object) return false;
    var innerWidth = 0, innerHeight = 0;
    with (this.object) {
        if (clientWidth) {
            this.width = clientWidth;
            this.height = clientHeight;
        } else if (innerWidth) {
            this.width = innerWidth;
            this.height = innerHeight;
        }
    }
    if (obj.offsetParent) {
        do {
            curleft += obj.offsetLeft;
            curtop += obj.offsetTop;
        }
        while (obj = obj.offsetParent);
    }
    this.left = curleft;
    this.top = curtop;
    this.right = this.left + this.width;
    this.bottom = this.top + this.height;
}


J'avais cru comprendre que element.getBoundingClientRect() donnait les mêmes résultats.
Dois-je reprendre ma vielle fonction ???
Je suis perplexe!
Modérateur
Smiley hum
La variable event permet de récupérer beaucoup d'infos. Au cas où tu utilises node.closest('..') ou un polifill qui le simule pour t'assurer que tu es bien dans l'élément.


window.addEventListener('DOMContentLoaded', ()=>{
        document.addEventListener('mousemove', (e)=>{
            console.log('>>>-------> ', e);
            console.log('>>>-------> ', e.target);
        });
        document.getElementById('message').addEventListener('mouseover', ()=>{
            console.log('Dans le textarea');
       });
});

Modifié par niuxe (09 Aug 2017 - 22:07)
Merci de ta réponse
Mon problème est en fait que je ne cherche pas seulement à savoir si le curseur est à l'intérieur d'un élément, mais également dans une zone précise à l'intérieur de cet élément.
Il s'agit en effet de gérer le changement de largeur d'une cellule de table, et les actions ne doivent se dérouler que si le curseur est à la limite droite de la cellule, c'est à dire que la position du curseur est entre rectangle.right ± 10px
Après réflexion nocturne, je vais changer mon design, mettre une balise <span> ou autre dans la cellule en relative et un autre élément <span> en absolute dans cette balise, qui sera calculée de telle sorte qu'elle matérialise la zone sensible.
Je pourrai alors, comme tu le proposes, utiliser les évènements, non pas sur la cellule, mais sur la zone sensible, pour effectuer les divers traitements nécessaires.
Il suffira de prendre note à chaque fois de la quantité de déplacement de la souris, sans trop se préoccuper de sa position absolue.
Comme quoi une nuit de sommeil vaut mieux que des heures de tâtonnement dans la journée (sauf que la nuit ne porte conseil que si on y a pensé au préalable)
Je dirai ce qu'il en est quand ça marchera... ou aura lamentablement échoué, ce qui est malheureusement possible!
Modifié par PapyJP (10 Aug 2017 - 09:43)
Hello !

Pas sûr que ça aide, mais tu pourrais d'abord récupérer l'élément cible de ton événement avec Event.target. Ensuite, tu peux calculer la position de ton curseur à l'intérieur de la cible à partir de Event.clientX/Y et des coordonnées de ta cible, que tu peux récupérer avec Element.getBoundingClientRect();

En gros :

function blabla(event) {
    let target = event.target;
    let mousePosX = event.clientX;
    let mousePosY = event.clientY;
    let targetPos = target.getBoundingClientRect();

    //Ici, checker si le point de coordonnées (mousePosX, mousePosY) se trouve bien dans le rectangle délimité par ((targetPos.left, targetPos.top), (targetPos.right, targetPos.bottom))
}
Merci de ta réponse
C'est bien ce que je fais, mais le résultat c'est que event.clientY me donnait une valeur qui n'était pas cohérente avec targetPos.top et targetPos.bottom
J'ai lancé l'outil de trace de FireFox, avec un point d'arrêt sur le début de la procédure et regardé les valeur: la valeur de clientY était plus grande que targetPos.bottom alors que le curseur était en plein milieu de la cellule en cause.
Le HTML était du genre

<body>
    <div id="container">
        <table>
            <tr><td id="cell">....</td>
    ...........

avec en CSS
#container {width:60%;margin:20px auto 0;}

quand j'ai remplacé le CSS par

body {padding-top:20px}
#container {width:60%;margin:auto;}

je n'ai plus constaté ce phénomène, mais je ne comprends toujours pas le premier code ne fonctionnait pas.
Je soupçonne un zombie du genre une cochonnerie dans la feuille de style implicite de FireFox qui contiendrait un padding caché de <body>, mais ça ne devrait pas être le cas, car j'ai fait un reset en tête de mon fichier CSS, qui force à 0 le padding de <body>, donc ça n'est sans doute pas ça...
Modifié par PapyJP (10 Aug 2017 - 18:07)
Salut !

Est-ce que tu es sûr que l'événement se déclenche bien sur la cellule de ton tableau et non sur un élément parent ? Sinon, tu peux tester dans une condition si le target est bien un td, ou s'il a une classe spécifique.
Dans mon design initial, l'événement était traité sur <body> et je testais la position par rapport à la cellule.
La raison de ce design, c'est que lorsque la souris est légèrement à droite de la cellule je dois traiter l'événement comme si elle était à l'intérieur. J'ai abandonné cette idée foireuse: il est beaucoup plus simple d'ajouter un "véritable élément" qui matérialise la zone sensible. Dans ce nouveau design je peux correctement exploiter les évènements sur cette zone.
Reste que je n'ai toujours pas compris pourquoi la position en y de la souris n'était pas cohérente avec le rectangle de la cellule, mais je laisse tomber, du moins pour le moment