javascript - Tooltip moves further from mouseover location as I scroll HTML page
问题描述
I'm using JQuery mouseover and CSS with "position: absolute;"
to position the tooltip next to a particular matrix (x, y) location where the mouse is pointing to.
But as I scroll down, the tooltip moves further from the mouse pointer! :(
Here are the two images:
My fiddle: http://jsfiddle.net/kjx9z1uy/22/
My code snippet:
var colours = ['#F5F5F5', '#F5F5F5', '#F5F5F5', '#f4cd42', '#F5F5F5'];
var n = colours.length;
var w = 15;
var h = w * 4;
// create an offsreen canvas containing the desired coloured circles
var off = document.createElement('canvas');
off.width = n * w;
off.height = h;
var ctx = off.getContext('2d');
// request mousemove events
var tipCanvas = document.getElementById("tip");
var tipCtx = tipCanvas.getContext("2d");
$("#canvas").mousemove(function (e) {
handleMouseMove(e);
});
for (var i = 0; i < n; ++i) {
ctx.beginPath();
ctx.rect(i*w, 0, w, h)
// Fill
ctx.globalAlpha = "0.8"; // Opacity
ctx.fillStyle = colours[i];
ctx.fill();
// Stroke
ctx.globalAlpha = "1.0"; // Opacity reset
//ctx.lineWidth = "1";
ctx.strokeStyle = "black";
ctx.stroke();
}
// get handles to the on-screen canvas
var canvas = document.getElementById('canvas');
var ctx2 = canvas.getContext('2d');
// create 3000 random points
var points = [];
var num_boxes = Math.floor(canvas.width/w)
* Math.floor(canvas.height/h)
console.log("# boxes: " + num_boxes)
for (var i = 0; i < Math.floor(canvas.width/w); ++i) {
for (var j = 0; j < Math.floor(canvas.height/h); ++j) {
var point_left = Math.floor(i*w);
var point_top = Math.floor(j*h);
var point_right = point_left + w;
var point_bottom = point_top + h;
points.push({
c: i % n,
x: point_left,
y: point_top,
w: w,
h: h,
r: point_right,
b: point_bottom,
text: "Data: (" + i + ", " + j + ") at (" + point_left + ", " + point_top + ", " + point_right + ", " + point_bottom + ")"
});
}
}
// copy points from the offscreen canvas into the on-page canvas
var t0 = Date.now();
ctx2.font = "bold 15px sans-serif";
ctx2.fillStyle = "black";
for (var i = 0; i < points.length; ++i) {
var p = points[i];
ctx2.drawImage(off, p.c * p.w, 0, p.w, p.h, p.x, p.y, p.w, p.h);
ctx2.fillText(p.c, p.x, p.y+p.h);
//console.log("RECT:", p.x, p.y, p.w, p.h)
}
var t1 = Date.now();
console.log("Elapsed time: " + (t1 - t0) + "ms");
// show tooltip when mouse hovers over dot
function handleMouseMove(e) {
mouseX = parseInt(e.clientX);
mouseY = parseInt(e.clientY);
var hit = false;
var adjustY = 15 + tipCanvas.height
for (var i = 0; i < points.length; ++i) {
var p = points[i];
var withinX = (mouseX >= p.x) && (mouseX < p.r);
var withinY = (mouseY >= p.y) && (mouseY < p.b);
if (withinX && withinY) {
if ((mouseX + tipCanvas.width) < canvas.width) {
tipCanvas.style.left = mouseX + "px";
}
else {
if (tipCanvas.width < canvas.width) {
tipCanvas.style.left = (mouseX - tipCanvas.width) + "px";
}
else {
tipCanvas.style.left = mouseX + "px";
}
}
if (mouseY > adjustY) {
tipCanvas.style.top = (mouseY - adjustY) + "px";
}
else {
tipCanvas.style.top = (mouseY + adjustY) + "px";
}
tipCtx.clearRect(0, 0, tipCanvas.width, tipCanvas.height);
tipCtx.fillText(p.text, 5, 15);
tipCtx.fillText('Mouse: (' + mouseX + ', ' + mouseY + ")", 5, 30);
hit = true;
}
}
if (!hit) {
tipCanvas.style.left = 0 - tipCanvas.width - 40 + "px";
}
}
#tip {
background-color: white;
border: 1px solid blue;
position: absolute;
left: -200px;
top: -100px;
}
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<canvas id="tip" width=200 height=40></canvas>
<canvas id="canvas" width="1000" height="15000"> </canvas>
解决方案
因为您没有添加滚动高度。
在 handleMouseMove() 函数中,我将 window.scrollY 添加到 Y 轴值。
var colours = ['#F5F5F5', '#F5F5F5', '#F5F5F5', '#f4cd42', '#F5F5F5'];
var n = colours.length;
var w = 15;
var h = w * 4;
// create an offsreen canvas containing the desired coloured circles
var off = document.createElement('canvas');
off.width = n * w;
off.height = h;
var ctx = off.getContext('2d');
// request mousemove events
var tipCanvas = document.getElementById("tip");
var tipCtx = tipCanvas.getContext("2d");
$("#canvas").mousemove(function (e) {
handleMouseMove(e);
});
for (var i = 0; i < n; ++i) {
ctx.beginPath();
ctx.rect(i*w, 0, w, h)
// Fill
ctx.globalAlpha = "0.8"; // Opacity
ctx.fillStyle = colours[i];
ctx.fill();
// Stroke
ctx.globalAlpha = "1.0"; // Opacity reset
//ctx.lineWidth = "1";
ctx.strokeStyle = "black";
ctx.stroke();
}
// get handles to the on-screen canvas
var canvas = document.getElementById('canvas');
var ctx2 = canvas.getContext('2d');
// create 3000 random points
var points = [];
var num_boxes = Math.floor(canvas.width/w)
* Math.floor(canvas.height/h)
console.log("# boxes: " + num_boxes)
for (var i = 0; i < Math.floor(canvas.width/w); ++i) {
for (var j = 0; j < Math.floor(canvas.height/h); ++j) {
var point_left = Math.floor(i*w);
var point_top = Math.floor(j*h);
var point_right = point_left + w;
var point_bottom = point_top + h;
points.push({
c: i % n,
x: point_left,
y: point_top,
w: w,
h: h,
r: point_right,
b: point_bottom,
text: "Data: (" + i + ", " + j + ") at (" + point_left + ", " + point_top + ", " + point_right + ", " + point_bottom + ")"
});
}
}
// copy points from the offscreen canvas into the on-page canvas
var t0 = Date.now();
ctx2.font = "bold 15px sans-serif";
ctx2.fillStyle = "black";
for (var i = 0; i < points.length; ++i) {
var p = points[i];
ctx2.drawImage(off, p.c * p.w, 0, p.w, p.h, p.x, p.y, p.w, p.h);
ctx2.fillText(p.c, p.x, p.y+p.h);
//console.log("RECT:", p.x, p.y, p.w, p.h)
}
var t1 = Date.now();
console.log("Elapsed time: " + (t1 - t0) + "ms");
// show tooltip when mouse hovers over dot
function handleMouseMove(e) {
mouseX = parseInt(e.clientX);
mouseY = parseInt(e.clientY);
var hit = false;
var adjustY = 15 + tipCanvas.height;
var scrollY = window.scrollY;
for (var i = 0; i < points.length; ++i) {
var p = points[i];
var withinX = (mouseX >= p.x) && (mouseX < p.r);
var withinY = (mouseY >= p.y) && (mouseY < p.b);
if (withinX && withinY) {
if ((mouseX + tipCanvas.width) < canvas.width) {
tipCanvas.style.left = mouseX + "px";
}
else {
if (tipCanvas.width < canvas.width) {
tipCanvas.style.left = (mouseX - tipCanvas.width) + "px";
}
else {
tipCanvas.style.left = mouseX + "px";
}
}
if (mouseY > adjustY) {
tipCanvas.style.top = (mouseY - adjustY + scrollY) + "px";
}
else {
tipCanvas.style.top = (mouseY + adjustY + scrollY) + "px";
}
tipCtx.clearRect(0, 0, tipCanvas.width, tipCanvas.height);
tipCtx.fillText(p.text, 5, 15);
tipCtx.fillText('Mouse: (' + mouseX + ', ' + mouseY + ")", 5, 30);
hit = true;
}
}
if (!hit) {
tipCanvas.style.left = 0 - tipCanvas.width - 40 + "px";
}
}
#tip {
background-color: white;
border: 1px solid blue;
position: absolute;
left: -200px;
top: -100px;
}
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<canvas id="tip" width=200 height=40></canvas>
<canvas id="canvas" width="1000" height="15000"> </canvas>
推荐阅读
- list - 在 Dart 中,`List.unmodifiable` 是创建一个不可修改的视图,还是一个全新的独立列表?
- python - 如何修复 tensorflow.tools.api.generator.api.contrib' 没有 'layers' 成员?
- java - 如何将 mouseClicked() 与不规则对象一起使用
- haskell - 推断 lambda 表达式的类型
- php - 用于 json 字符串的多级 php 数组。输出错误
- php - PHP邮件功能不会发送到雅虎
- c++ - CMake - 在 Windows 上链接 exe
- c# - 在进入 Application.Run() 之后,如何强制调试器跳过方法及其调用的任何内容?
- c++ - 函数 new char[size] vs char[size] 上的动态内存
- ios - 无法在物理设备上获取联系人-iOS