web-dev-qa-db-fra.com

jQuery récupère la position de la souris dans un élément

J'espérais créer un contrôle permettant à un utilisateur de cliquer à l'intérieur d'une div, de faire glisser la souris, puis de le relâcher pour indiquer la durée pendant laquelle il souhaite que quelque chose soit. (Ceci est pour un contrôle de calendrier, de sorte que l'utilisateur indiquera la durée, dans le temps, d'un certain événement)

Pour ce faire, la meilleure solution consiste à enregistrer un événement "mousedown" sur la division parent qui enregistre à son tour un événement "mousemove" sur la div jusqu'à ce qu'un événement "mouseup" soit déclenché. Les événements "mousedown" et "mouseup" définiront le début et la fin de la plage de temps et si je suis les événements "mousemove", je peux modifier dynamiquement la taille de la plage afin que l'utilisateur puisse voir ce qu'il fait. Je me suis basé sur la manière dont les événements sont créés dans Google Agenda.

Le problème que je rencontre est que l'événement jQuery semble ne fournir que des informations de coordonnées de souris fiables en référence à la page entière. Y a-t-il un moyen de discerner quelles sont les coordonnées en référence à l'élément parent?

Edit:

Voici une image de ce que j'essaie de faire: alt text

159
Chris Dutrow

Une méthode consiste à utiliser la méthode jQuery offset pour traduire les coordonnées event.pageX et event.pageY à partir de l'événement. position de la souris par rapport au parent. Voici un exemple pour référence future:

_$("#something").click(function(e){
   var parentOffset = $(this).parent().offset(); 
   //or $(this).offset(); if you really just want the current element's offset
   var relX = e.pageX - parentOffset.left;
   var relY = e.pageY - parentOffset.top;
});
_
297
jball

Pour obtenir la position du clic par rapport à l'élément cliqué actuel
Utilisez ce code

$("#specialElement").click(function(e){
    var x = e.pageX - this.offsetLeft;
    var y = e.pageY - this.offsetTop;
}); 
15
Sajjad Ashraf

J'utilise ce morceau de code, c'est plutôt sympa :)

    <script language="javascript" src="http://code.jquery.com/jquery-1.4.1.js" type="text/javascript"></script>
<script language="javascript">
$(document).ready(function(){
    $(".div_container").mousemove(function(e){
        var parentOffset = $(this).parent().offset();
        var relativeXPosition = (e.pageX - parentOffset.left); //offset -> method allows you to retrieve the current position of an element 'relative' to the document
        var relativeYPosition = (e.pageY - parentOffset.top);
        $("#header2").html("<p><strong>X-Position: </strong>"+relativeXPosition+" | <strong>Y-Position: </strong>"+relativeYPosition+"</p>")
    }).mouseout(function(){
        $("#header2").html("<p><strong>X-Position: </strong>"+relativeXPosition+" | <strong>Y-Position: </strong>"+relativeYPosition+"</p>")
    });
});
</script>
11
Maarten Hartman

La réponse de @AbdulRahim est presque correcte. Mais je suggère la fonction ci-dessous comme substitut (pour référence ultérieure):

function getXY(evt, element) {
                var rect = element.getBoundingClientRect();
                var scrollTop = document.documentElement.scrollTop?
                                document.documentElement.scrollTop:document.body.scrollTop;
                var scrollLeft = document.documentElement.scrollLeft?                   
                                document.documentElement.scrollLeft:document.body.scrollLeft;
                var elementLeft = rect.left+scrollLeft;  
                var elementTop = rect.top+scrollTop;

                x = evt.pageX-elementLeft;
                y = evt.pageY-elementTop;

                return {x:x, y:y};
            }




            $('#main-canvas').mousemove(function(e){
                var m=getXY(e, this);
                console.log(m.x, m.y);
            });
9
Paulo Bueno

Cette solution prend en charge tous les principaux navigateurs, y compris IE. Il prend également en charge le défilement. Tout d'abord, il récupère efficacement la position de l'élément par rapport à la page, sans utiliser de fonction récursive. Ensuite, il obtient le x et le y du clic de la souris par rapport à la page et effectue la soustraction pour obtenir la réponse qui correspond à la position par rapport à l'élément (l'élément peut être une image ou une div par exemple):

function getXY(evt) {
    var element = document.getElementById('elementId');  //replace elementId with your element's Id.
    var rect = element.getBoundingClientRect();
    var scrollTop = document.documentElement.scrollTop?
                    document.documentElement.scrollTop:document.body.scrollTop;
    var scrollLeft = document.documentElement.scrollLeft?                   
                    document.documentElement.scrollLeft:document.body.scrollLeft;
    var elementLeft = rect.left+scrollLeft;  
    var elementTop = rect.top+scrollTop;

        if (document.all){ //detects using IE   
            x = event.clientX+scrollLeft-elementLeft; //event not evt because of IE
            y = event.clientY+scrollTop-elementTop;
        }
        else{
            x = evt.pageX-elementLeft;
            y = evt.pageY-elementTop;
    }
7
Abdul Rahim Haddad

Si vous faites en sorte que votre élément parent soit "position: relative", il s'agira du "parent décalé" pour les éléments sur lesquels vous suivez les événements de la souris. Ainsi, la "position ()" de jQuery sera relative à celle.

3
Pointy

En voici un qui vous donne également la position en pourcentage du point au cas où vous en auriez besoin. https://jsfiddle.net/Themezly/2etbhw01/

function ThzhotspotPosition(evt, el, hotspotsize, percent) {
  var left = el.offset().left;
  var top = el.offset().top;
  var hotspot = hotspotsize ? hotspotsize : 0;
  if (percent) {
    x = (evt.pageX - left - (hotspot / 2)) / el.outerWidth() * 100 + '%';
    y = (evt.pageY - top - (hotspot / 2)) / el.outerHeight() * 100 + '%';
  } else {
    x = (evt.pageX - left - (hotspot / 2));
    y = (evt.pageY - top - (hotspot / 2));
  }

  return {
    x: x,
    y: y
  };
}



$(function() {

  $('.box').click(function(e) {

    var hp = ThzhotspotPosition(e, $(this), 20, true); // true = percent | false or no attr = px

    var hotspot = $('<div class="hotspot">').css({
      left: hp.x,
      top: hp.y,
    });
    $(this).append(hotspot);
    $("span").text("X: " + hp.x + ", Y: " + hp.y);
  });


});
.box {
  width: 400px;
  height: 400px;
  background: #efefef;
  margin: 20px;
  padding: 20px;
  position: relative;
  top: 20px;
  left: 20px;
}

.hotspot {
  position: absolute;
  left: 0;
  top: 0;
  height: 20px;
  width: 20px;
  background: green;
  border-radius: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box">
  <p>Hotspot position is at: <span></span></p>
</div>
1
Benn