监听点击谷歌广告、iframe跨域问题


公司需求,需要监听谷歌点击统计!

想了几种方案:

方案一 事件委托(不可取)、

给iframe里面监听方法,通过contentWindow 去执行事件委托;

这种方案,不可取~因为同源策略,iframe下面引入了谷歌的第三方的URL,出现了跨域问题;

除非你可以在广告生成页里面下个调用方法,来调取你当前页写的方法;

var ifr = document.querySelectorAll('iframe');
ifr.forEach(item =>{
  let ctw = item.contentWindow;
  ctw.addEventListener('click',function(e){
    console.log(e.srcElement)
  })
})

那给包裹广告的ins标签或者div标签,监听事件?

好像还是不行,iframe框架在当前页面展示层,

方案二 事件穿透(不可取)、

在外层谷歌广告外层添加一个遮罩,那么用户点击行为的时候,可以实现用户行为采集,也是很棒的想法;

在广告容器下面,做个div遮罩,<div class="mask" style="position:absolute;top:0px;right:0px;width:100%;height:100%;z-index:99;"></div>;

(1)、然后根据事件 mousedown -> mousemove -> mouseup -> click / touchstart -> touchmove -> touchend -> tap 的优先顺序

(2)、或者用css3的 pointer-events:none用在mask上面

(3)、在遮罩下面绑定事件,从而触发,这又回到第一个问题,跨域问题,谷歌广告是不可能让你写方法的,那么这个方案又不行

方案三 轮训与事件监听(可取)

上面方案不行,总得找出一个出路解决监听的方案~

不能动谷歌的ins\iframe的document,那么就去监听当前页,总可以吧~

这里用到了h5新增方法activeElement,这个是用来监听当前执行元素

然后通过一个轮询方法,监听这个document.activeElement对象,做iframe匹配;

终于可以监听到iframe这也是个进步,那么点击谷歌广告时,至少可以给你个响应,并且不报错了

var IframeOnClick = {

  istrack:null,

  resolution: 200,

  iframes: [],

  interval: null,

  Iframe: function() {

    this.element = arguments[0];

    this.cb = arguments[1];

    this.hasTracked = false;

  },

  track: function(element, cb) {

    this.iframes.push(new this.Iframe(element, cb));

    if (!this.interval) {

      var _this = this;

      this.interval = setInterval(function() {

         _this.checkClick();

      }, this.resolution);

     }

  },

  checkClick: function() {

    if (document.activeElement) {

        var activeElement = document.activeElement;

        var tagName = activeElement.tagName;

        for (var i in this.iframes) {

          if (activeElement === this.iframes[i].element) {

             if (this.iframes[i].hasTracked == false) {

              this.iframes[i].cb.apply(window, []);

              this.iframes[i].hasTracked = true; }

           }

      }

     }

     }

    };

    window.onload = function(){

      var ifs = document.getElementsByClassName("iframe");

      for (var i = 0; i < 12; i++) {

        IframeOnClick.track(ifs[i], function() {

           console.log("click");

          // 这里写一些业务逻辑,例如给变量添加状态

          IframeOnClick.istrack = true;

        });

      }

    }

接着讲,只点击谷歌广告,还达不到监控是否点击a标签跳转啊,要是点击的空白处,也是返回的iframe对象,不是很尴尬;这个时候只能通过其他的方法,去到达a跳转的效果;

配合方法h5新增方法,document.hidden 与 visibilityChangeEvent这个事件配合用,能监听当前页面是否是激活状态,a标签既然会跳转页面,那么当前页面肯定就是非激活状态;这时候配合上面方法;

(1)找到IframeOnClick下面的istrack,它是用来标记状态的

(2)当点击谷歌广告并跳转时,那么给这个IframeOnClick.istrack = true;

(3)在页面非激活状态下,通过判断istrack这个变量,实现业务逻辑,例如ajax 当前的location值啊,获或者获取当前用户IP,这些都是没问题的;

(4)在页面激活状态,你得把istrack这个变量还原为 null,  istrack = null;

排除点击广告没跳转,又点击了你们自己的页面链接出现错误数据统计

// 判断是否在当前页面

var hiddenProperty = 'hidden' in document ? 'hidden' : 'webkitHidden' in document ? 'webkitHidden' : 'mozHidden' in document ? 'mozHidden' : null;

var visibilityChangeEvent = hiddenProperty.replace(/hidden/i, 'visibilitychange');

var onVisibilityChange = function(){

  if (!document[hiddenProperty]) {

    console.log('页面非激活');

      if(IframeOnClick.istrack){

      //执行你要的逻辑

    }

  }else{

    console.log('页面激活')

    IframeOnClick.istrack = null;

   }

}

document.addEventListener(visibilityChangeEvent, onVisibilityChange);

 

感谢大神们的分享,这里做个mark,方便以后自己看,如果有用,点个👍

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM