2011-05-17 91 views
13

使用prettyPhoto插件打开模式样式的内容容器,并尝试与Google Analytics的事件跟踪集成以跟踪视频何时打开。jQuery将事件侦听器绑定到另一个之前

麻烦的是,当我

$('a.videoClickListener').click(function(event){ 
    console.log('here'); 
    _gaq.push(['_trackEvent', 'Product Page', 'Video Open', '<?php echo $product->getNameWithManufacturer(); ?>']); 
}); 

的事件从来没有发射,因为prettyPhoto停止持续的事件(相当正确,否则该网页将如果一个超链接被单击更改)。

prettyPhoto似乎没有提供'open'回调函数,但如果它确实无法使用它,因为prettyPhoto监听器是在布局中的某处设置的(我们每次使用rel="prettyPhoto"时都要使用它prettyPhoto,并通过URL传递参数,这是漂亮的照片推荐的做事方式)。我还想将产品详情传递给Google Analytics,排除所有prettyPhoto开幕活动中的全球视频开放侦听器。

如何在prettyPhoto侦听器之前绑定我的听众之前?如果事实证明我必须使用.unbind(),然后绑定我的侦听器,然后重新绑定prettyPhoto,我如何解除在插件中指定的处理程序?

回答

18

理想情况下,您可以在之前添加您的事件绑定,以便它首先执行。

不幸的是,jQuery似乎没有包含任何这样的设施。

不过,我编写了一个preBind method,这似乎这样的伎俩:

$.fn.preBind = function(type, data, fn) { 
    this.bind(type, data, fn); 

    var currentBindings = this.data('events')[type]; 
    var currentBindingsLastIndex = currentBindings.length - 1; 

    var newBindings = []; 

    newBindings.push(currentBindings[currentBindingsLastIndex]); 

    $.each(currentBindings, function (index) { 
    if (index < currentBindingsLastIndex) 
     newBindings.push(this); 
    }); 

    this.data('events')[type] = newBindings; 

    return this; 
}; 

用法:

$('#button').bind('click', function() { 
    console.log('world'); 
}); 

// 2nd apostrophe for the selector was missing 
$('#button').preBind('click', function() { 
    console.log('hello'); 
}); 

$('#button').click(); 

// Output: 
// 
// > "hello" 
// > "world" 
+0

尝试以下解决方案以获取较新和较旧的jQuery版本中的事件:stackoverflow.com/a/26892146/655224 – algorhythm 2014-11-12 16:49:19

+0

未捕获TypeError:无法读取未定义(...)的属性'更改' – fdrv 2016-11-08 02:49:43

-1

如果您使用unbind(),则即使插件所做的绑定也将被解除绑定。

+0

感谢您的答复。我将如何去选择一个事件来解除绑定?他们以某种方式命名?在prettyPhoto中,侦听器被绑定为匿名函数。 – sennett 2011-05-17 10:30:47

+1

多漂亮的照片是如何停止事件?如果你和插件都在同一个项目上监听某种类型的事件,那么这个插件就无法阻止你绑定。听取插件监听的相同类型的事件,并在同一个元素上完全监听。 – Amareswar 2011-05-17 11:48:34

+0

再次感谢。它似乎现在正在工作......我必须在某个地方犯了另一个错误(当从PHP传递给javascript时可能不会编码产品名称)。 – sennett 2011-05-17 13:18:26

13

我使用的是乔纳森的prebind方法,稍作修改,它也很好的诀窍。

​​
+0

+1:该代码是一种等功能优化jonathanconway的。 – Adrien 2013-11-16 16:12:03

+5

在新版本的jQuery'$ this.data('events')[type]'不起作用。您必须使用'$ ._ data(this,'events')[type]' – 2014-01-08 16:40:27

+0

@RichardRout尝试以下解决方案以获取较新和较旧的jQuery版本中的事件:http://stackoverflow.com/a/26892146/655224 – algorhythm 2014-11-12 16:48:40

2

后来换一行在上面的代码,使其工作:

var currentBindings = $this.data('events',type); // var currentBindings = $this.data('events')[type]; 

这可能是因为我使用jQuery 2.0.3

+1

在1.8.3中,我必须使用以下内容: ''。$ ._ data(this,“events”)[type];'''。注意'this'是实际的html元素,而不是一个jQuery对象。 – Gowiem 2013-10-17 21:13:37

6

为我工作与旧版和新版jQuery版本:

/** 
* @link http://stackoverflow.com/a/26892146/655224 
*/ 
jQuery.fn.getEvents = function() { 
    if (typeof(jQuery._data) == 'function') { 
     return jQuery._data(this.get(0), 'events') || {}; 
    } else if (typeof(this.data) == 'function') { // jQuery version < 1.7.? 
     return this.data('events') || {}; 
    } 
    return {}; 
}; 

jQuery.fn.preBind = function(type, data, fn) { 
    this.each(function() { 
     var $this = jQuery(this); 

     $this.bind(type, data, fn); 

     var currentBindings = $this.getEvents()[type]; 
     if (jQuery.isArray(currentBindings)) { 
      currentBindings.unshift(currentBindings.pop()); 
     } 
    }); 
    return this; 
}; 

但要注意,这个功能只能返回/的prebind的事件,这是用jQuery自己设置。

特别感谢@jonathanconway和@Patrick ...

+0

另请参阅此主题:http://stackoverflow.com/a/26892146/655224 – algorhythm 2014-11-14 23:29:21

5

下面是使用更现代。对()方法的解决方案的一个变种。

// Same as .on() but moves the binding to the front of the queue. 
$.fn.priorityOn = function (type, selector, data, fn) { 
    this.each(function() { 
     var $this = $(this); 

     var types = type.split(" "); 

     for (var t in types) { 
      $this.on(types[t], selector, data, fn); 

      var currentBindings = $._data(this, 'events')[types[t]]; 
      if ($.isArray(currentBindings)) { 
       currentBindings.unshift(currentBindings.pop()); 
      } 
     } 


    }); 
    return this; 
}; 

用法是一样

$(document).priorityOn("click blur change", ".some .selector input", function (e) { 
    // Your code. 
});