(初学JavaScript)
目的:子元素在父元素中移动且不越界
初始代码:
var wall = document.getElementById('wall'); // 父元素
$('#wall').on('mousedown', '.popVideoView', popVideoViewMouseDown); // 动态绑定
/**
* popVideoView 鼠标按下事件
* @param e
*/
function popVideoViewMouseDown(e) {
let popVideoView = this;
//设置鼠标样式
popVideoView.style.cursor = 'move';
// 鼠标在控件上的相对位置
let left = e.clientX - popVideoView.offsetLeft;
let top = e.clientY - popVideoView.offsetTop;
// 鼠标移动事件
document.onmousemove = function(event) {
// 提前计算鼠标移动后控件的新坐标
let newLeft = event.clientX - left;
let newTop = event.clientY - top;
// 判断控件的新坐标是否在父控件范围内
if (positionLeftJudge(newLeft, popVideoView.offsetWidth)) {
popVideoView.style.left = newLeft + 'px';
}
if (positionTopJudge(newTop, popVideoView.offsetHeight)) {
popVideoView.style.top = newTop + 'px';
}
}
// 鼠标松开事件
document.onmouseup = function() {
popVideoView.style.cursor = 'default';
document.onmousemove = null;
document.onmouseup = null;
};
}
/**
* 判断元素左边距是否在范围内
* @param left
* @param width
* @returns {boolean}
*/
function positionLeftJudge(left, width) {
if (left >= wall.offsetLeft && (left + width) <= (wall.offsetLeft+ wall.offsetWidth)) {
return true;
}
return false;
}
/**
* 判断元素上边距是否在范围内
* @param top
* @param height
* @returns {boolean}
*/
function positionTopJudge(top, height) {
if (top >= wall.offsetTop&& (top + height) <= (wall.offsetTop+ wall.offsetHeight)) {
return true;
}
return false;
}
问题:控件不能完全移动到父控件边缘
原因:鼠标移动过快时,控件无法跟上,在控件到达边缘前,positionLeftJudge() / positionTopJudge() 已返回 false
代码修改:
// 鼠标移动事件
document.onmousemove = function(event) {
// 提前计算鼠标移动后控件的新坐标
let newLeft = event.clientX - left;
let newTop = event.clientY - top;
// 将新坐标进行处理
newLeft = calculatePositionLeft(newLeft, popVideoView.offsetWidth);
newTop = calculatePositionTop(newTop, popVideoView.offsetHeight);
// 设置坐标
popVideoView.style.left = newLeft + 'px';
popVideoView.style.top = newTop + 'px';
}
/**
* 计算元素左边距
* @param left
* @param width
* @returns {number|*}
*/
function calculatePositionLeft(left, width) {
if (left < wall.offsetLeft)
return wall.offsetLeft;
let parentRight = wall.offsetLeft + wall.offsetWidth;
if ((left + width) <= parentRight)
return left;
return parentRight - width;
}
/**
* 计算元素上边距
* @param top
* @param height
* @returns {number|*}
*/
function calculatePositionTop(top, height) {
if (top < wall.offsetTop)
return wall.offsetTop;
let parentBottom = wall.offsetTop + wall.offsetHeight;
if ((top + height) <= parentBottom)
return top;
return parentBottom - height;
}
仍存在问题:偶尔会出现鼠标拖动事件捕捉失败