Это кажется удивительным вопрос, но есть ПОЧТИ продублировать здесь: How to get the MouseEvent coordinates for an element that has CSS3 Transform? но никто не смотрит на мой ответ там, и это, кажется, гораздо более общий характер, так что я» ll опубликуйте его здесь, с несколькими изменениями, чтобы сделать его более понятным:
В основном, это работает, делая это: разделите элемент, на который вы пытаетесь найти относительные координаты, и разделите его на 9 меньших элементов. Используйте document.elementFromPoint, чтобы узнать, находится ли координата над этим мини-элементом. Если это так, разделите этот элемент на еще 9 элементов и продолжайте делать это до тех пор, пока не станет достаточно точной координаты. Затем используйте getBoundingClientRect, чтобы найти экранные координаты этого мини-элемента. БУМ!
jsfiddle: http://jsfiddle.net/markasoftware/rA27K/8/
Вот функция JavaScript:
function convertPointFromPageToNode(elt,coords){
///the original innerHTML of the element
var origHTML=elt.innerHTML;
//now clear it
elt.innerHTML='';
//now save and clear bad styles
var origPadding=elt.style.padding=='0px'?'':elt.style.padding;
var origMargin=elt.style.margin=='0px'?'':elt.style.margin;
elt.style.padding=0;
elt.style.margin=0;
//make sure the event is in the element given
if(document.elementFromPoint(coords.x,coords.y)!==elt){
//reset the element
elt.innerHTML=origHTML;
//and styles
elt.style.padding=origPadding;
elt.style.margin=origMargin;
//we've got nothing to show, so return null
return null;
}
//array of all places for rects
var rectPlaces=['topleft','topcenter','topright','centerleft','centercenter','centerright','bottomleft','bottomcenter','bottomright'];
//function that adds 9 rects to element
function addChildren(elt){
//loop through all places for rects
rectPlaces.forEach(function(curRect){
//create the element for this rect
var curElt=document.createElement('div');
//add class and id
curElt.setAttribute('class','offsetrect');
curElt.setAttribute('id',curRect+'offset');
//add it to element
elt.appendChild(curElt);
});
//get the element form point and its styling
var eltFromPoint=document.elementFromPoint(coords.x,coords.y);
var eltFromPointStyle=getComputedStyle(eltFromPoint);
//Either return the element smaller than 1 pixel that the event was in, or recurse until we do find it, and return the result of the recursement
return Math.max(parseFloat(eltFromPointStyle.getPropertyValue('height')),parseFloat(eltFromPointStyle.getPropertyValue('width')))<=1?eltFromPoint:addChildren(eltFromPoint);
}
//this is the innermost element
var correctElt=addChildren(elt);
//find the element's top and left value by going through all of its parents and adding up the values, as top and left are relative to the parent but we want relative to teh wall
for(var curElt=correctElt,correctTop=0,correctLeft=0;curElt!==elt;curElt=curElt.parentNode){
//get the style for the current element
var curEltStyle=getComputedStyle(curElt);
//add the top and left for the current element to the total
correctTop+=parseFloat(curEltStyle.getPropertyValue('top'));
correctLeft+=parseFloat(curEltStyle.getPropertyValue('left'));
}
//reset the element
elt.innerHTML=origHTML;
//restore element styles
elt.style.padding=origPadding;
elt.style.margin=origMargin;
//the returned object
var returnObj={
x: correctLeft,
y: correctTop
}
return returnObj;
}
ВАЖНО !!! Кроме того, необходимо включить этот CSS для его работы:
.offsetrect{
position: absolute;
opacity: 0;
height: 33.333%;
width: 33.333%;
}
#topleftoffset{
top: 0;
left: 0;
}
#topcenteroffset{
top: 0;
left: 33.333%;
}
#toprightoffset{
top: 0;
left: 66.666%;
}
#centerleftoffset{
top: 33.333%;
left: 0;
}
#centercenteroffset{
top: 33.333%;
left: 33.333%;
}
#centerrightoffset{
top: 33.333%;
left: 66.666%;
}
#bottomleftoffset{
top: 66.666%;
left: 0;
}
#bottomcenteroffset{
top: 66.666%;
left: 33.333%;
}
#bottomrightoffset{
top: 66.666%;
left: 66.666%;
}
ТАКЖЕ: Я изменил немного вашего CSS, давая «дед» Див идентификатор и ссылки на него в вашем CSS, используя #div1
вместо div
, потому что мой код генерирует divs, а ваши стили div также применяются к тем, которые использует мой код, и испортили его.
ОДИН ПОСЛЕДНИЙ: Я не знаю CoffeeScript, поэтому я скорректировал ваш код, чтобы сделать его чистым JavaScript. Извини за это.
Вы в порядке, если он не может вычислить координаты элемента? например он работает только если мышь находится на элементе? – Markasoftware
Я знаю, что это старый вопрос, но можете ли вы взглянуть на него. Я отправил ответ. – Markasoftware
Я разговаривал с моими коллегами о вашем решении на днях, @Markasoftware! Дайте мне время, чтобы успокоиться на работе, и тогда я хорошо посмотрю! – steveluscher