- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我目前正在为在线发布商开发第三方小部件,并希望跟踪其在不同网站上的表现。我想到了实现 Upworthy 的代码 ( http://upworthy.github.io/2014/06/implementing-attention-minutes-part-1/ ) 来计算每个用户在我的小部件上花费的平均时间。所以我决定分 3 个步骤实现它:
我已经实现了上面的代码,源代码可以在这里找到:http://jsfiddle.net/q21gzjmf/13/
//simple jquery function to detect when my widget is visible
function widgetFocus(){
$(window).scroll(function () {
if ($(window).scrollTop() + $(window).height() > $('.footer').offset().top) {
alert('visible');
return true;
}
else{
return false;
}
});
}
function merge(stream1, stream2) {
return stream1.merge(stream2);
}
function eventStream(eventName) {
return $(window).asEventStream(eventName);
}
var isFocused = eventStream("focus").map(widgetFocus)
.merge(eventStream("blur").map(false))
.toProperty(true);
var EVENT_NAMES = ["focus", "click", "scroll", "mousemove", "touchstart", "touchend", "touchcancel", "touchleave", "touchmove"];
var streams = _.map(EVENT_NAMES, eventStream);
var interactionStream = _.reduce(streams, merge);
var recentlyActive = interactionStream
.map(true)
.flatMapLatest(function() {
return Bacon.once(true).merge(Bacon.once(false).delay(DECAY));
})
.toProperty(false);
var isActive = (recentlyActive.and(isFocused));
var secondsActive = Bacon.mergeAll(isActive.changes(), isActive.sample(1000))
.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 x / 1000; }) // milliseconds
.map(Math.floor);
secondsActive.assign($("#seconds"), "text");
但是,如果您在底部向下滚动,您会发现花费的时间计算为 0,并且不会像此处显示的 Upworthy 实现那样动态更新自身 http://jsfiddle.net/zanes/mbGBr/ .我对函数式响应式编程的概念还很陌生,并且仍在努力了解 Bacon.JS,所以我确定我一定犯了一个非常愚蠢的概念性错误,但我是来这里学习的。任何帮助将不胜感激。
最佳答案
要重复这些步骤在窗口小部件可见时启动焦点事件:
为此我们需要一个谓词来返回小部件是否可见:
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 以获取指示是否显示小部件的 bool 值流。
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 的简单版本):
var DECAY = 1000;
function decayingStream() {
return Bacon.once(true).merge(Bacon.once(false).delay(DECAY));
}
var isActive$ = scrollEvents
.flatMapLatest(decayingStream)
.toProperty(true);
接下来我们可以组合 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);
工作 jsfiddle:http://jsfiddle.net/xkn3sc6y/3/
关于javascript - 实现 Bacon.JS 以查找每个用户在第三方小部件上花费的平均时间的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27641419/
我正在学习使用神奇的 Bacon.js用于函数式响应式(Reactive)编程的库。向属性或流添加处理程序很容易: handler = function(value){... do something
我有以下 PHP 代码来生成 QR 码并显示到浏览器。 以下代码有效: $renderer = new \BaconQrCode\Renderer\Image\Png(); $
我有以下 PHP 代码来生成 QR 码并显示到浏览器。 以下代码有效: $renderer = new \BaconQrCode\Renderer\Image\Png(); $
在试验 Bacon.js 时,我遇到了以下意外行为: var email = $("#email") .asEventStream("k
my_Stream 是我想要累积并分配给变量以供进一步处理的数据。我的问题:一旦流完成,如何将变量 the_string 的内容获取到 console.log? my_Stream.onValue(f
我有一个定期触发的事件: let periodicEvent = Bacon.interval(1000, {}); periodicEvent.onValue(() => { doStuff
假设如下代码(当前状态可以查看 here ): function scrollTopFromEvent(evt) { return $(evt.target).scrollTop(); } f
我无法理解什么是 Bacon.js 中的惰性求值。 我使用 map 和 flatMap 编写了 Bacon 提供的示例,我得到了相同的结果。 这是HTML 这是使用 map 的代码的JS var
正如标题所说,我正在寻找一些组合器 collect,它将同时发出的事件收集到一个列表中,类似于 Reactive-Banana 中的那个。所以换句话说: collect :: EventStream
当按下 ENTER 时,我有一个事件流 var enter = $('#text') .asEventStream('keydown') .filter(function(e){
我想在 Bacon.js 中缓冲 EventStream 的值,就像 buffer(closingSelector) 一样在 RxJava 中表现。当“ Controller 流”(RxJava 方法
我有一个要向其发出 get 请求的 url 数组。我从 urls 数组和 flatMap ajax 请求创建一个流,如下所示:响应 = Bacon.fromArray(url_arr) .flatMa
我想在以下场景中使用 bacon.js: 1.读取目录下的文件 2.每个文件由一个url组成,向该url发起http请求 3.将每个响应写入另一个目录中的相应文件 从文档中,我了解到,即使所有值都被过
使用 Bacon.js 处理 POC 并遇到一些属性值问题。 我能够在 onValue 回调中检索所有新的属性值,但是我想知道设置此新值之前旧的属性值是什么。到目前为止,我还没有找到任何简单或优雅的解
我一直在尝试为流行的 kevin bacon 游戏创建图形表示。我已经创建了图形和顶点类,但在创建广度优先搜索方法来遍历图形并找到从 Kevin Bacon 到 Actor 的最短路径并在途中打印出边
我正在尝试为 requestAnimationFrame 生成类似于 Bacon.fromPoll 的流 为什么以下代码会产生“超出最大调用堆栈”错误? function rafSequence()
关于响应式编程的大部分资源,例如“A Survey on Reactive Programming”(Bainomugisha 等人,2012 年),介绍了几个可以对不同的响应式(Reactive)解
作为 bacon.js 的新手,我似乎无法理解事件流和属性之间的区别。 属性是从流构建的(使用 .constant 构建的属性除外?) 他们有大多数共同的方法 以同样的方式订阅它们 有人可以解释差异以
我有一个表单,当前有 2 个输入(数量将会增加),用户可以在其中添加/编辑数字。更改任何字段后,我想用这两个数字进行计算。 使用基本的 jQuery,这将是轻而易举的事情: var f1 = $(".
我正在尝试深入研究响应式编程。因此,我决定使用 Bacon javascript 库创建一个使用 RSA 加密的简单聊天。 我的问题:使用 Bacon 创建随机数流的最佳方法是什么?之后我想将随机数流
我是一名优秀的程序员,十分优秀!