【问题标题】:Javascript capturing user activity捕获用户活动的 Javascript
【发布时间】:2015-02-14 15:37:04
【问题描述】:

是否有现有的 js lib 用于捕获用户活动浏览器端?

即。滚动,鼠标移动,鼠标点击等。 我一直在谷歌搜索、搜索 stackoverflow 和 github,但我不断获得付费分析程序的链接,这些链接并不是我想要的。

我很想自己开始构建一些东西,但我想得越多,我就越难意识到它会变得更好,如果有的话,我最好使用一些现有的库。

我在想什么。这是一个合适的方法吗?

  • 我假设最好的方法是监听 body 或 window 元素并捕获所有未禁用冒泡的所需事件。
  • 最好在发送/发布到服务器之前对数据进行批处理和缩小。如删除模式或频繁出现的数据。如果用户滚动,我不需要所有的滚动事件,只需要它们开始、加速或停止的有意义的事件。
  • 可以每 X 个事件或 X 秒发出批次。并发送最后一批window.onbeforeunload

我发现了这两个问题herehere。但并不是我想要的。

我希望能够配置事件聚合以询问有关用户交互的问题。诚然,我已经过时了 Google Analytic,也许我错了,但乍一看自定义事件跟踪似乎不符合要求。记录特定的个人操作不是我所追求的。

【问题讨论】:

    标签: javascript html user-experience


    【解决方案1】:

    也许是这样的:

    DEMO

    相关代码(JS和HTML):

    <script type="text/javascript">
    // Array of events you want to capture
    var evnts=["mousedown","click","mouseup","focus","blur","keyup","keydown","keypressed"];
    // You can also Use mousemove, resize and scroll
    for(var i=0;i<evnts.length;i++){
    //Attach Listener for all events from array
    window.addEventListener(""+evnts[i]+"", function(e){ myFunction(e); }, false);
    }
    // Listener:- 
    function myFunction(e){
    //Check If event is passed
    var evt=e||window.event;
    if(evt){ // If event exists
    if(evt.isPropagationStopped&&evt.isPropagationStopped()){
    // if event's propagation(bubbling) is stopped then DO NOTHING simply return.
        return;
    }
    // Get Event Type (Click or Keyup or focus etc)
    var et=evt.type?evt.type:evt;
    // Get Events Target (Element from which event is bubbled)
    var trgt=evt.target?evt.target:window;
    // Timestamp of event you can also use evt.timeStamp if supported 
    var time=Math.floor(Date.now() / 1000);
    // Get Where Event Occured ? events X and Y co-ordinate on Page and Scrolltop of document
    var x=0, y=0, scrolltop=0;
    if(evt.pageX){
    x=evt.pageX;
    }
    if(evt.pageY){
    y=evt.pageY;
    }
    if(trgt.scrollTop){
    scrolltop=trgt.scrollTop;
    }
    // Get id and class of element
    if(trgt.className&&trgt.id){
    // BOTH id and class exists
    trgt="."+trgt.className+"#"+trgt.id;
    }
    else if(trgt.id){
    // only id exists
    trgt="#"+trgt.id;
    }
    else if(trgt.className){
    // only class exists
    trgt="."+trgt.className;
    }
    if(typeof(trgt)!="String"){
    // Neither Class nor Id is defined
    if(trgt.tagName){
    // If it is html tag display its tag name
     trgt=trgt.tagName;
    }
    else{
    // No class + No Id + Not a Html tag 
        trgt=trgt.toString().toLowerCase();
        trgt=trgt.replace("[object ","");
        trgt=trgt.replace("]","");
            trgt=trgt.replace("htmlbodyelement","BODY");
    
    }
    }
    // Get extra information about event
    var xtra="";
    if(evt.keyCode){
    // If keyboard Event? get Key code
    xtra+=" KeyCode: "+evt.keyCode;
    }
    if(evt.shiftKey){
    // was Shift key pressed during occcurance of event?
    xtra+=" ShiftKey ";
    }
    if(evt.altKey){
    // was alt key pressed during occcurance of event?
    xtra+=" altKey ";
    }
    if(evt.metaKey){
    // MetaKey is used on Mac instead of ctrl Key on PC
    xtra+=" metaKey ";
    }
    if(evt.ctrlKey){
    // was ctrl key pressed on pc during occcurance of event?
    xtra+=" ctrlKey ";
    }
    // Get windows dimensions for catching resize event
    var w = window,
        d = document,
        e = d.documentElement,
        g = d.getElementsByTagName('body')[0],
        xx = w.innerWidth || e.clientWidth || g.clientWidth,
        yy = w.innerHeight|| e.clientHeight|| g.clientHeight;
    xtra+=" RES:"+xx+"X"+yy;
    
    // pad output for displaying on console
    et=("          " + et).slice(-10);
    trgt=("               " + trgt).slice(-15);
    x=("               " + x).slice(-15);
    y=("               " + y).slice(-15);
    scrolltop=("               " + scrolltop).slice(-15);
    time=("              " + time).slice(-15);
    // Show output on console
    console.log("\n"+et+"\t"+trgt+"\t"+x+"\t"+y+"\t"+scrolltop+"\t"+time+"\t"+xtra);
    }
    }
    </script> 
    <!-- Some Xtra HTML To test -->
    <div class="mnp" style="overflow:auto;clear:both;width:150px;height:150px;" onMouseUp="event.stopPropagation();" onMouseDown="event.stopPropagation();">
    XXX<br />
    XXX<br />
    XXX<br />
    XXX<br />
    XXX<br />
    XXX<br />
    XXX<br />
    XXX<br />
    XXX<br />
    XXX<br />
    XXX<br />
    XXX<br />XXX<br />
    XXX<br />
    </div>
    

    对于下一部分,即定期将其发送到服务器,您可以使用AJAXsetTimeout,首先将数据保存在变量中(而不是填充和记录它)。并在每次成功的 ajax 操作(即readyState==200)上清除它(变量)。你也可以send ajax request onbeforeunload

    简而言之,这段代码实际上做了什么: 它attaches events 来自evnts 数组(您也可以在该数组中添加事件)全部到window 元素(这比将它附加到所有元素要快得多),然后它获取事件详细信息如果是propogation 不是stopped,有关如何获取事件描述的详细信息,请从代码中读取 cmets。

    希望它有所帮助:)!

    【讨论】:

    • 很好,但滚动似乎没有被记录。
    【解决方案2】:

    你必须自己写(或者至少我是这样做的)。

    备份问题:Is there any javascript library to capture mouse/keyboards events and send them to external server?

    这是一个有效的 jsfiddle:http://jsfiddle.net/94dd343y/

            $(document).ready(function(){
            $('html').mousemove(function(event){
                console.log("mouse move X:"+event.pageX+" Y:"+event.pageY);
            });
    
            $('html').click(function(event){
                console.log("mouse click X:"+event.pageX+" Y:"+event.pageY);
            });
    
            $('html').keyup(function(event){
                console.log("keyboard event: key pressed "+event.keyCode);
            });
        });
    

    等等。

    如果你想捕获所有事件,这里有一个列表:

    【讨论】:

    • 感谢您的回复。似乎不是一个受欢迎的问题:(我很惊讶那里已经没有任何东西了。在最后一个链接中很有趣,它们循环了所有 dom 元素并为所有事件附加了侦听器,这似乎真的过分了。
    • 是的。为所有事件附加监听器真的很有害。如果你想将此服务外部化,你可以使用intercom.io 之类的东西。 (但它不是免费的)
    • 在对讲机中,您可以声明许多要跟踪的较大事件。像这样工作:用户按下按钮(登录),您调用对讲 api 发送“pressloginevent”和一些元数据“用户名和密码”,之后您可以按位置/小时/用户/事件获取 Web 应用程序的统计信息。跨度>
    猜你喜欢
    • 2010-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-03
    • 1970-01-01
    相关资源
    最近更新 更多