神策埋点

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/a1390033590/article/details/100554512

log.js

import sa from 'sa-sdk-javascript'
let Log = {}

/**
 * 发送 1 条统计事件,把这条统计事件分发到神策
 *
 */
Log.push = function (args) {
    // debug('log.push', args);
    // if (isBrowser === false) { return; }
    if (args[1] == '') {
        sa.track(args[0])
    } else {
        try {
            let paramObj = compileParam(args[1])
            sa.track(args[0], paramObj)
        } catch (e) {

        }
    }


    // sa.track(args[0], args[3])
};

let compileParam = function (param) {
    if (param == '' || param == null || param == undefined) return param;
    let arr = param.split("&");
    let obj = {}
    arr.forEach(function (v, i) {
        let arr1 = v.split("=");
        obj[arr1[0]] = arr1[1];
    })
    return obj;
}

/**
 * 生成1个统计事件监听函数,要么是focus、要么是click,更多的事件需要的时候再支持
 *
 * @param {String} _eventType 需要处理哪种类型的事件
 * @param {Boolean} isGaEnabled 透传的参数
 * @return Function
 */
var getEventHandler = function (_eventType) {
    return function (eventTarget) {
        // // 拿到事件发生的节点
        // var eventTarget = e.target,
        var eventType = eventTarget.getAttribute('vd-event-type') || 'click',
            eventParam = eventTarget.getAttribute('vd-event-param') || '',
            eventName = eventTarget.getAttribute('vd-event-name').replace(/(^\s*)|(\s*$)/g, '');
        if (eventName && eventType === _eventType) { // vd-event-name 是否为空,并且类型匹配
            // 获取页面层级属性
            var scopes = [eventName];
            var event = getParents(eventTarget, 'vd-event-scope')
            if (event !== undefined) {
              var scope = event.getAttribute('vd-event-scope').replace(/(^\s*)|(\s*$)/g, '')
              if (scope) { // vd-event-scope 是否为空
                scopes.push(scope);
              }
              // scopes [scope,name]
              scopes.reverse();
              Log.push([scopes.join('_'), eventParam]);
            }

        }
    };
};
/**
 * 原生获取父元素
 * @param {*} el 
 * @param {*} attr 属性,符合条件的属性
 */
function getParents(el, attr) {
    var parent = el.parentNode
    if (parent && parent.nodeName == 'BODY') {
        if (parent.hasAttribute(attr)) {
            return parent
        } else {
            return
        }
    } else {
        if (parent) {
            // list.push(parent)
            // 避免有多个vd-event-scope
            if (parent.hasAttribute(attr)) {
                return parent
            } else {
                return getParents(parent, attr)
            }
        } else {
            return
        }
    }
}

/**
 * 利用事件委托对所有需要自动发送统计事件的节点进行监听,只能初始化一次
 */
var isInitialized = false;
Log.init = function () {
    var ndBody = document.querySelector('body');
    var ndNoBubble = document.querySelectorAll('[vd-event-no-bubble]');
    // 处理可以冒泡的节点
    console.log(ndBody);
    console.log(ndNoBubble);
    ndBody.addEventListener('click', function (e) {
        // 处理选择符(这样不好,如果一个a标签里面有图片和文字,点击到其他应该触发到a标签的)
        if (e.target.hasAttribute('vd-event-name')) {
            getEventHandler('click')(e.target)
        } else {
            var event = getParents(e.target, 'vd-event-name')
            if (event !== undefined) {
                getEventHandler('click')(event)
            }
        }
    });

    // 处理无法冒泡到顶层的结点点击
    if (ndNoBubble && ndNoBubble.length > 0) {
        ndNoBubble.addEventListener('click', getEventHandler('click'));
    }

    // }

};

export default Log

main,js

import Vue from 'vue'
import App from './App';
import router from './router';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import sa from 'sa-sdk-javascript'
import Log from './common/log';
// const user_id = VueCookies.get('id') // 这个是必须要有唯一的id,可以取用户id
sa.init({
  server_url: '/sensors/api/v1/default/53f48d27f5ed6e701241d7548093274533d0af3d9d2ae80740a629836897900d', // 替换成自己的神策地址
  heatmap: {
     //是否开启点击图,默认 default 表示开启,自动采集 $WebClick 事件,可以设置 'not_collect' 表示关闭
     clickmap:'not_collect',
     show_log: true, // 打印console,自己配置,可以看到自己是否踩点成功,以及
     //是否开启触达注意力图,默认 default 表示开启,自动采集 $WebStay 事件,可以设置 'not_collect' 表示关闭
     scroll_notice_map:'not_collect'
  },
  // is_track_single_page:true,
  send_type: 'ajax',
});
const user_id = sa.store.getDistinctId();
sa.login(user_id);
// if (window.$config.env == 'prod') { // 这个地方是看自己的需求加判断添加
  // 神策路由监控页面跳转
  router.afterEach((to,from) => {
    Vue.nextTick(() => {
        sa.quick("autoTrackSinglePage");
    });
  })
  // 点击事件统计
  Log.init()
// }

Vue.config.productionTip = false
Vue.use(ElementUI);
/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

login.vue

<template>
  <div class="login" vd-event-scope="login">
    <h1>登录页面</h1>
    <el-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
      <el-form-item label="用户名" prop="useName">
        <el-input v-model="ruleForm.useName"></el-input>
      </el-form-item>
      <el-form-item label="密码" prop="pass">
        <el-input type="password" v-model="ruleForm.pass" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item>


// 需要埋点的地方写下这些代码

        <el-button type="primary" @click="submitForm('ruleForm')"
        vd-event-name="WebClick_submit" vd-event-type="click">提交</el-button>
        <el-button @click="resetForm('ruleForm')" 
        vd-event-name="WebClick_reset" vd-event-type="click">重置</el-button>




      </el-form-item>
    </el-form>
  </div>
</template>

index.vue

<template>
  <div class="index" vd-event-scope="index">
    <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
      <el-form-item label="活动名称" prop="name">
        <el-input v-model="ruleForm.name"></el-input>
      </el-form-item>
      <el-form-item label="活动区域" prop="region">
        <el-select v-model="ruleForm.region" placeholder="请选择活动区域">
          <el-option label="区域一" value="shanghai"></el-option>
          <el-option label="区域二" value="beijing"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="活动时间" required>
        <el-col :span="11">
          <el-form-item prop="date1">
            <el-date-picker type="date" placeholder="选择日期" v-model="ruleForm.date1" style="width: 100%;"></el-date-picker>
          </el-form-item>
        </el-col>
        <el-col class="line" :span="2">-</el-col>
        <el-col :span="11">
          <el-form-item prop="date2">
            <el-time-picker placeholder="选择时间" v-model="ruleForm.date2" style="width: 100%;"></el-time-picker>
          </el-form-item>
        </el-col>
      </el-form-item>
      <el-form-item label="即时配送" prop="delivery">
        <el-switch v-model="ruleForm.delivery"></el-switch>
      </el-form-item>
      <el-form-item label="活动性质" prop="type">
        <el-checkbox-group v-model="ruleForm.type">
          <el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox>
          <el-checkbox label="地推活动" name="type"></el-checkbox>
          <el-checkbox label="线下主题活动" name="type"></el-checkbox>
          <el-checkbox label="单纯品牌曝光" name="type"></el-checkbox>
        </el-checkbox-group>
      </el-form-item>
      <el-form-item label="特殊资源" prop="resource">
        <el-radio-group v-model="ruleForm.resource">
          <el-radio label="线上品牌商赞助"></el-radio>
          <el-radio label="线下场地免费"></el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="活动形式" prop="desc">
        <el-input type="textarea" v-model="ruleForm.desc"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitForm('ruleForm')"
        vd-event-name="WebClick_submit" vd-event-type="click">立即创建</el-button>
        <el-button @click="toTable()"
        vd-event-name="WebClick_toTable" vd-event-type="click" :vd-event-param="param">前往table页</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>
<script>
//  import sensors from'../common/sensors';
export default {
  data() {
      return {
        start: new Date(),
        path: this.$route.path,
        ruleForm: {
          name: '',
          region: '',
          date1: '',
          date2: '',
          delivery: false,
          type: [],
          resource: '',
          desc: ''
        },
        rules: {
          name: [
            { required: true, message: '请输入活动名称', trigger: 'blur' },
            { min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
          ],
          region: [
            { required: true, message: '请选择活动区域', trigger: 'change' }
          ],
          date1: [
            { type: 'date', required: true, message: '请选择日期', trigger: 'change' }
          ],
          date2: [
            { type: 'date', required: true, message: '请选择时间', trigger: 'change' }
          ],
          type: [
            { type: 'array', required: true, message: '请至少选择一个活动性质', trigger: 'change' }
          ],
          resource: [
            { required: true, message: '请选择活动资源', trigger: 'change' }
          ],
          desc: [
            { required: true, message: '请填写活动形式', trigger: 'blur' }
          ]
        }
      };
    },
    created() {
      console.log(this.$route.path)
      this.loadHandler();
      // if ('onpageshow' in window) {
      //   this.addEvent(window, 'pageshow', this.loadHandler);
      //   this.addEvent(window, 'pagehide', this.unloadHandler);
      // } else {
      //   this.addEvent(window, 'load', this.loadHandler);
      //   this.addEvent(window, 'unload', this.unloadHandler);
      // }
    },
    computed() {
      // param() {
      //   return {
      //     pageStayTime: this.unloadHandler(),
      //     pageUrl: this.$route.path
      //   }
      // }
    },
    methods: {
      submitForm(formName) {
        this.$refs[formName].validate((valid) => {
          if (valid) {
            alert('submit!');
          } else {
            console.log('error submit!!');
            return false;
          }
        });
      },
      toTable(formName) {
        //跳转前调用页面停留时间函数
        this.unloadHandler();
        this.$router.push({ name: 'table' });
      },

      // 页面停留时间
      loadHandler(e) {
        console.log("start")
        this.start = new Date();
      },
      unloadHandler (e) {
        var end = new Date();
        // 如果用户一直不关闭页面,可能出现超大值,可以根据业务需要处理,例如设置一个上限
        var duration = (end.getTime() - this.start.getTime()) / 1000;
        return duration;
        // 定义一个记录页面停留时间的事件pageView,并且保存需要的属性(停留时间和当前页面的地址)
        console.log(this.$route.path)
        // sensors.track('pageclose', {
        //   pageStayTime: duration,
        //   pageUrl: this.$route.path
        // });
      },
      // addEvent(target, type, listener) {
      //   if (window.addEventListener) {
      //     target.addEventListener(type, listener, false);
      //   } else {
      //     target.attachEvent('on' + type, listener);
      //   }
      // },
    }
}
</script>

<style>
 .demo-ruleForm {
   width: 500px;
   margin: 100px auto; 
   border: 1px solid #ccc;
   padding: 20px;
   text-align: left;
 }
</style>

猜你喜欢

转载自blog.csdn.net/a1390033590/article/details/100554512