【发布时间】:2021-06-17 13:58:00
【问题描述】:
问题
我在编写一些代码时遇到了一个小问题,其中我已经自动化了一个脚本来跟踪用户与 UI 的交互,包括 mousemove 和 click 事件。如果我不必担心让它响应,那么我可能会收工并交付我已经完成的工作,但是我的大脑正在寻找一些魔法知识,我正在努力让它变得超级响应.这只是我正在处理的那种事情的快速示例,这不是天才,如果有的话,我主要是 heatmap.js 正在做繁重的工作。目前,我只是在看看我是否可以将其作为概念证明而不是其他任何事情......
代码
所以目前,我正在跟踪 event.pageX 和 event.pageY 值以存储确切事件发生的位置,我还将 window.innerWidth 和 window.innerHeight 值存储到尝试并制定一些功能,让我可以根据其他设备的大小来偏移位置。
例如如果您查看上面的示例图片,这对于静态页面来说是完美的,但如果我说让页面更窄一点,您可以在这里看到它与上面的图片不符:
不管怎样,废话不多说,这里有一些示例代码:
// A lot of other code...
var setupHeatMaps = function (pages, heatMaps) {
pages.forEach(function (page) {
page.addEventListener("click", function (event) {
heatMaps.push({ x: event.pageX, y: event.pageY, value: 10000 });
onStateChange();
});
// Don't collect ALL mouse movements, that'd be crazy, so collect
// every 1/10 mouse movements.
var counter = 0;
page.addEventListener("mousemove", function (event) {
if (counter === 10) {
heatMaps.push({ x: event.pageX, y: event.pageY, value: 20 });
onStateChange();
counter = 0;
} else {
counter ++;
}
});
});
};
// A lot of other code...
// Curried function so that it can be passed around without exposing the state...
var renderHeatMaps = function (heatMaps) {
return function () {
var max = heatMaps.length;
var points = heatMaps;
var parent = getParentElement();
var styleObj = window.getComputedStyle(parent);
var div = document.createElement("div");
var body = document.querySelector("body");
var background = document.createElement("div");
// This element needs to sit in front of the
// background element, hence the higher z-index value.
div.style.position = "absolute";
div.style.zIndex = 9;
div.style.left = "0px";
div.style.top = "-80px";
div.style.width = "100vw";
// Even though this element will sit behind the element
// that's created above, we will still want this element to
// sit in front of 99% of the content that's on the page.
background.style.position = "fixed";
background.style.top = "0px";
background.style.left = "0px";
background.style.height = "100vh";
background.style.width = "100vw";
background.style.zIndex = 5;
background.style.backgroundColor = "rgba(255, 255, 255, 0.35)";
background.setAttribute("id", "quote-customer-heat-map-background");
var heightInPx = styleObj.getPropertyValue("height");
var rawHeight = parseInt(heightInPx.replace("px", ""));
var newHeight = parseInt((rawHeight + 80));
div.style.height = newHeight + "px";
div.setAttribute("id", "quote-customer-heat-map-foreground");
body.style.paddingBottom = "0px";
body.appendChild(background);
body.appendChild(div);
var heatMap = h337.create({
container: div,
radius: 45
});
heatMap.setData({ max: max, data: points });
};
};
// A lot of other code...
由于您可以看到在setupHeatMaps 中使用的pages 元素的宽度发生了变化,因此查看此数据的偏移非常严重。老实说,我昨天花了很多时间思考这个问题,但我仍然没有想到任何似乎合理的事情。
或者
我想知道我是否应该以某种方式只是将页面存储为图像,并过度播放热图,这样我就不会真的担心热图反应灵敏。但后来我需要弄清楚其他一些事情......例如对这些数据进行版本控制,因此如果用户在手机上查看页面,它将将该数据与从之前会话中收集的数据分开存储,在该会话中他们在笔记本电脑或台式设备上。
结论
老实说,我不完全确定最好的行动方案是什么,你们中有人遇到过这样的事情吗?你们有没有想到什么天才可以解决这样的问题?
PS我会分享更多代码,但是这个整体解决方案中包含大量的代码,所以我有点无法分享所有内容,我很确定 Stackoverflow 的人会因此而讨厌我! ??? - 您也可以说我是作为 POC 执行此操作的,因为通常我只是将 background 元素和 div 元素的渲染卸载到底层框架,而不是像这样以编程方式进行,保留它请注意,这只是一个POC。
【问题讨论】:
-
一般来说,我希望响应式布局可以改变布局,使其难以传递有意义的热图数据。但是,在您展示的情况下,它可能是可行的。内容大小看起来是固定的。这是否意味着只有边距发生变化?由于您存储了屏幕尺寸,当您偏移左边距的预期变化时会发生什么?或者,我想知道如果您收集相对于底层 HTML 元素的位置测量值并根据显示之前的当前 el 偏移量锚定它是否会更好。
-
@user650881 很遗憾地通知您,everything 都是响应式的,我承认上面的示例可能不是最好的说明页面 &里面的一切都是响应式的,足够公平! ??? - 但是,是的,这一切都是响应式的。至于底层 DOM 元素的偏移量,这是我想到的,但是当我尝试这种方法时,出现了一些问题,尽管我会再试一次,因为为什么不呢? ...
-
这确实使它更具挑战性。我已经成功地覆盖了相对于响应式页面布局中底层元素位置的内容。 (在我的例子中,我并不关心保持与不同元素相关的叠加层之间的相对位置。)我可以补充的是,我必须跟踪原点的位置,因为绝对和相对定位的元素会改变测量原点。跨度>
-
跟踪点击了什么,而不是点击发生的位置。然后在此基础上构建热图。
-
我想我无法解决您的问题,但可能有不同的方法:您可以跟踪页面上的单个元素被输入、向左和用光标单击。这样您就不会获得热图,但您可以在每个可能的响应场景中获得与不同元素的所有交互。
标签: javascript performance heatmap