Javascript 实现Bacon.JS以查找每个用户在第三方小部件上花费的平均时间存在问题
我目前正在为在线出版商开发一个第三方小部件,并希望跟踪它在不同网站上的表现。我想实现Upworthy的代码()来计算每个用户在我的小部件上花费的平均时间。所以我决定分三步实施:Javascript 实现Bacon.JS以查找每个用户在第三方小部件上花费的平均时间存在问题,javascript,functional-programming,bacon.js,Javascript,Functional Programming,Bacon.js,我目前正在为在线出版商开发一个第三方小部件,并希望跟踪它在不同网站上的表现。我想实现Upworthy的代码()来计算每个用户在我的小部件上花费的平均时间。所以我决定分三步实施: 当我的小部件仅在视口中可见时启动我的“焦点”事件(我的小部件通常嵌入在文章的底部) 接下来,如Upworthy的方法所示,我将把自定义的“聚焦”事件与模糊事件合并,以开发一个isFocused事件 然后,我可以实现他们的recentlyActive方法,以确定用户是否在单击小部件,即他们是否在与我的小部件交互 我已经实现
function widgetFocus(){
return $(window).scrollTop() + $(window).height() > $('.footer').offset().top;
}
为此,我们需要一个谓词来返回小部件是否可见:
function widgetFocus(){
return $(window).scrollTop() + $(window).height() > $('.footer').offset().top;
}
然后我们继续进行所有与滚动相关的事件,正如您所做的:
function eventStream(eventName) {
return $(window).asEventStream(eventName);
}
var EVENT_NAMES = ["focus", "click", "scroll", "mousemove", "touchstart", "touchend", "touchcancel", "touchleave", "touchmove"];
var streams = _.map(EVENT_NAMES, eventStream);
var scrollEvents = Bacon.mergeAll(streams)
.debounceImmediate(50); // we debounce here, so we didn't get too much events
接下来,您可以映射scrollEvents以获得一个Boolean流,该流指示是否显示小部件
var isVisible$ = scrollEvents
.map(function () {
return widgetFocus();
})
.toProperty(false);
var secondsVisible = isVisible$.changes()
.map(function(isActive) {
return {
isActive: isActive,
timestamp: new Date().getTime()
};
})
.slidingWindow(2,2)
.filter(function(span) { return span[0].isActive; })
.map(function(span) { return span[1].timestamp - span[0].timestamp; })
.scan(0, function(x,y) { return x + y;})
.map(function(x) { return Math.floor(x / 1000); }); // milliseconds
secondsVisible.log("visible: ");
这是第一步,可能已经对你有用了
下一步是创建一个属性或流,说明页面是否处于活动状态(Upworthy的简单版本):
接下来,我们可以组合isActive$
和isVisible$
属性。我们只对小部件可见和页面处于活动状态的时间感兴趣
var secondsVisibleAndActive = isActive$.and(isVisible$).changes()
.map(function(isActive) {
return {
isActive: isActive,
timestamp: new Date().getTime()
};
})
.slidingWindow(2,2)
.filter(function(span) { return span[0].isActive; })
.map(function(span) { return span[1].timestamp - span[0].timestamp; })
.scan(0, function(x,y) { return x + y;})
.map(function(x) { return Math.floor(x / 1000); }); // milliseconds
secondsVisibleAndActive.log("active & visible: ");
secondsVisibleAndActive.assign($("#seconds"), "text");
一如既往,从简单开始
或者,您可以举例说明Upworthy实现的优点:最后一行:
var hasAttention = (recentlyActive.and(isFocused)).or(videoIsPlaying);
在您的情况下,您可以将其更改为:
var widgetHasAttention = recentlyActive.and(isFocused).and(widgetIsVisible);
工作JSFIDLE:太棒了,感谢您详细解释。我必须承认,我应该想到Upworthy的实现。
var widgetHasAttention = recentlyActive.and(isFocused).and(widgetIsVisible);