2016-07-28 69 views
1

我在另一个div内有div,当用户将鼠标悬停在父级上时,内部div跟随鼠标位置。然而,当鼠标在父母的边缘时,孩子的边界超出父母。我想做到这一点,所以孩子的边界始终保持在其父母身边。让div保留在其父级鼠标移动中

我做什么,我到目前为止已经取得了小提琴:https://jsfiddle.net/0ahqoycg

一个解决方案,我正在考虑是检查如果内部div的top属性是从外部的top一定的长度,如果是然后停止鼠标位置跟踪,左侧,右侧和底部也一样。

任何人都可以告诉我,如果有一种很好的方法可以将孩子的边界包含在其父母身上吗?

+0

您可能喜欢这个图书馆:http://tether.io/ – bruchowski

+0

u inner not child outer,becouse使用另一个理由positiion:绝对流。你想要什么信息到内心? –

+0

@AndreyFedorov那是什么? – MarksCode

回答

2
  • 使用.offset().width().height()计算 允许坐标。
  • 在 之外将变量中的所有选择器高速缓存并进行预计算,以提高性能,因为会生成大量的 mouseovermouseover事件。
  • 2段标记为//fine tune tweaks用于缓解最后几个漏过的事件 在跨界位置前的错过事件超越位置到 的边界限制。

var innerDiv = $('#inner'); 
 
var outerDiv = $('#outer'); 
 
var outDim = outerDiv.offset(); 
 
outDim.right = (outDim.left + outerDiv.width()); 
 
outDim.bottom = (outDim.top + outerDiv.height()); 
 
$(document).on('mousemove', function(e) { 
 
    var x = (e.clientX) - 15; 
 
    var y = (e.clientY) - 15; 
 
    var x_allowed = x >= outDim.left && x <= (outDim.right - innerDiv.width()); 
 
    var y_allowed = y >= outDim.top && y <= (outDim.bottom - innerDiv.height()); 
 
    if (y_allowed) { 
 
    innerDiv.css({ 
 
     top: y + 'px', 
 
    }); 
 
    } else { 
 
    //fine tune tweaks 
 
    if (y >= outDim.top) { 
 
     innerDiv.css({ 
 
     top: (outDim.bottom - innerDiv.height()) + 'px', 
 
     }); 
 
    } 
 
    if (y <= (outDim.bottom - innerDiv.height())) { 
 
     innerDiv.css({ 
 
     top: outDim.top + 'px', 
 
     }); 
 
    } 
 
    } 
 

 
    if (x_allowed) { 
 
    innerDiv.css({ 
 
     left: x + 'px' 
 
    }); 
 
    } else { 
 
    //fine tune tweaks 
 
    if (x >= outDim.left) { 
 
     innerDiv.css({ 
 
     left: outDim.right - innerDiv.width() + 'px', 
 
     }); 
 
    } 
 
    if (x <= (outDim.right - innerDiv.width())) { 
 
     innerDiv.css({ 
 
     left: outDim.left + 'px', 
 
     }); 
 
    } 
 
    } 
 

 

 
});
#wrap { 
 
    height: 200px; 
 
    width: 200px; 
 
    border: 2px solid black; 
 
} 
 
#outer { 
 
    height: 100px; 
 
    width: 100px; 
 
    border: 2px solid blue; 
 
    margin: 0 auto; 
 
} 
 
#inner { 
 
    height: 40px; 
 
    width: 40px; 
 
    border: 2px solid red; 
 
    position: absolute; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="wrap"> 
 
    <div id="outer"> 
 
    <div id="inner"> 
 

 
    </div> 
 
    </div> 
 
</div>

+0

这真的很棒,非常感谢。你知道是否有办法让内部div仍然移动,即使鼠标靠近外部div的边缘也会被容纳吗?当鼠标靠近外部div的边缘时,内部div被“卡住”时会感觉有点奇怪。 – MarksCode

+1

@MarksCode greedy huh:D,当你快速移动时,它会出现毛病。移动缓慢它的作品。 :D但是,我会尽力优化。但如果它解决了问题,请接受它。顺便说一句,我会不断更新代码。我有点被它迷住了。 – Iceman

+0

我接受了,我很高兴你觉得这很有趣。有人在一个叫做tether.io的评论中提到了一个图书馆,但是单独做这件事情会更酷。 – MarksCode

1

沿东西线...

var innerDiv = $('#inner'); 
    var outerDiv = $('#outer'); 
    innerDivWidth = innerDiv.outerWidth(); 
    innerDivHeight = innerDiv.outerHeight(); 
    var offset = outerDiv.offset(); 
    var l = offset.left + 15; 
    var t = offset.top + 15; 
    var h = outerDiv.outerHeight(); 
    var w = outerDiv.outerWidth(); 

    var maxx = l + w - innerDivWidth; 
    var maxy = t + h - innerDivHeight; 


    $(document).on('mousemove', function(e) { 
    if(e.clientY <= maxy && e.clientY >= t) { 
    $('#inner').css({ 
     top: (e.clientY - 15) + 'px' 
    }); 
    } 
    if(e.clientX <= maxx && e.clientX >= l) { 
    $('#inner').css({ 
     left: (e.clientX - 15) + 'px' 
    }); 
    } 
    }); 

JSFiddle

有一点要记住的是,你应该保持执行的代码在事件发生时,非常瘦。特别是因为像mousemove这样的事件每秒可能会触发数百次。

摘自Jquery Doc

请记住,只要鼠标指针移动(即使是像素),触发鼠标移动事件。这意味着可以在很短的时间内生成数百个事件 。如果处理程序有 执行任何重要处理,或者存在多个用于处理事件的处理程序,则这可能会严重影响浏览器的性能。 因此,重要的是优化mousemove处理程序,尽可能多地使用 ,并在不再需要时立即解除它们。

+0

对于你的查询*,允许内部div仍然移动,即使鼠标靠近外部div的边缘,也可以被包含。*此解决方案有效。 –