Google Publisher Tag registering to Events - google-publisher-tag

I looked at the Google Publisher Tag reference and decided that I could add some events to my ad slots. It works great if I have defined only one slot.
If I add more slots, the events keep repeating on my console number of times I have slots.
So, if I do something like this:
<script type='text/javascript'>
googletag.cmd.push(function() {
var slot1 = googletag.defineSlot('/123456/leadeboard', [[728, 90]], 'div-gpt-ad-123456789-0').addService(googletag.pubads());
var slot2 = googletag.defineSlot('/123456/leadeboard', [[728, 90]], 'div-gpt-ad-123456789-0').addService(googletag.pubads());
var slot3 = googletag.defineSlot('/123456/leadeboard', [[728, 90]], 'div-gpt-ad-123456789-0').addService(googletag.pubads());
googletag.pubads().enableSingleRequest();
googletag.pubads().addEventListener('slotRenderEnded', function(event) {
console.log('Slot has been rendered:');
});
googletag.enableServices();
});
</script>
My console.log would be 3x "Slot has been rendered:". If I remove two of the .addService from the defineSlot part, it only console.logs it once, but then the ad is not rendered.
Is there a way how to remove extra logging without breaking everything else? It can get extremely messy after a while.
Thanks!

Nastasja,
The reason the output repeats three times is the event handler that you registered listens for the 'slotRenderEnded' event, which happens every time a slot renders. Since your example has three slots, the event will fire three times. You can see which slot triggers the callback by inspecting the event object that is passed in.
googletag.pubads().addEventListener('slotRenderEnded', function(event) {
console.log('Slot has been rendered:');
console.log(event); //inspect event
console.log(event.slot); //inspect slot
});
Even though the the event first three times, you can add slot based logic by comparing the slots in the event like this:
var slot1 = googletag.defineSlot('/123456/leadeboard', [[728, 90]], 'div-gpt-ad-123456789-0').addService(googletag.pubads());
googletag.pubads().addEventListener('slotRenderEnded', function(event) {
if(slot1 === event.slot){
console.log('slot1 has been rendered');
}
});
You can read more in the GPT documentation

If your setup loads the listeners each time and they are only used once then you can do it this way:
googletag.pubads().addEventListener('GPT-message', function (event) {
someCode();
googletag.pubads().removeEventListener('GPT-message', arguments.callee);
});

Related

Get the current handled events with jQuery

Is there a way to get all events that are currently handled? That means not the events that are bound to an element. I mean a way to get all events that are currently fired.
So for better interpretation, something like this (but without declaring each event):
var Records = {};
(function loop() {
$(document).bind('click mousemove change', function(e) {
Records[+new Date()] = {type: e.type};
});
setTimeout(loop, 10);
})();
I know about this: $._data($('*').andSelf().get(0), 'events'); but that gives me only the currently handled/attached events.

How to use events and event handlers inside a jquery plugin?

I'm triyng to build a simple animation jQuery-plugin. The main idea is to take an element and manipulate it in some way repeatedly in a fixed intervall which would be the fps of the animation.
I wanted to accomplish this through events. Instead of using loops like for() or while() I want to repeat certain actions through triggering events. The idea behind this: I eventualy want to be able to call multiple actions on certain events, like starting a second animation when the first is done, or even starting it when one animation-sequence is on a certain frame.
Now I tried the following (very simplified version of the plugin):
(function($) {
$.fn.animation = function() {
obj = this;
pause = 1000 / 12; //-> 12fps
function setup(o) {
o.doSomething().trigger('allSetUp');
}
function doStep(o, dt) {
o.doSomething().delay(dt).trigger('stepDone');
}
function sequenceFinished(o) {
o.trigger('startOver');
}
function checkProgress(o) {
o.on({
'allSetup': function(event) {
console.log(event); //check event
doStep(o, pause);
},
'stepDone': function(event) {
console.log(event); //check event
doStep(o, pause);
},
'startOver': function(event) {
console.log(event); //check event
resetAll(o);
}
});
}
function resetAll(o) {
/*<-
reset stuff here
->*/
//then start over again
setup(o);
}
return this.each(function() {
setup(obj);
checkProgress(obj);
});
};
})(jQuery);
Then i call the animation like this:
$(document).ready(function() {
$('#object').animation();
});
And then – nothing happens. No events get fired. My question: why? Is it not possible to use events like this inside of a jQuery plugin? Do I have to trigger them 'manualy' in $(document).ready() (what I would not prefer, because it would be a completely different thing – controling the animation from outside the plugin. Instead I would like to use the events inside the plugin to have a certain level of 'self-control' inside the plugin).
I feel like I'm missing some fundamental thing about custom events (note: I'm still quite new to this) and how to use them...
Thx for any help.
SOLUTION:
The event handling and triggering actually works, I just had to call the checkProgress function first:
Instead of
return this.each(function() {
setup(obj);
checkProgress(obj);
});
I had to do this:
return this.each(function() {
checkProgress(obj);
setup(obj);
});
So the event listening function has to be called before any event gets triggered, what of course makes perfect sense...
You need set event on your DOM model for instance:
$('#foo').bind('custom', function(event, param1, param2) {
alert('My trigger')
});
$('#foo').on('click', function(){ $(this).trigger('custom');});​
You DOM element should know when he should fire your trigger.
Please note that in your plugin you don't call any internal function - ONLY DECLARATION

jQuery — trigger a live event only once per element on the page?

Here's the scenario
$("p").live('customEvent', function (event, chkSomething){
//this particular custom event works with live
if(chkSomething){
doStuff();
// BUT only per element
// So almost like a .one(), but on an elemental basis, and .live()?
}
})
Here's some background
The custom event is from a plugin called inview
The actual issue is here http://syndex.me
In a nutshell, new tumblr posts are being infnitely scrolled via
javascript hack (the only one out there for tumblr fyi.)
The inview plugin listens for new posts to come into the viewport, if the top of an image is shown, it makes it visible.
It's kinda working, but if you check your console at http://.syndex.me check how often the event is being fired
Maybe i'm also being to fussy and this is ok? Please let me know your professional opinion. but ideally i'd like it to stop doing something i dont need anymore.
Some things I've tried that did not work:
stopPropagation
.die();
Some solutions via S.O. didnt work either eg In jQuery, is there any way to only bind a click once? or Using .one() with .live() jQuery
I'm pretty surprised as to why such an option isnt out there yet. Surely the .one() event is also needed for future elements too? #justsayin
Thanks.
Add a class to the element when the event happens, and only have the event happen on elements that don't have that class.
$("p:not(.nolive)").live(event,function(){
$(this).addClass("nolive");
dostuff();
});
Edit: Example from comments:
$("p").live(event,function(){
var $this = $(this);
if ($this.data("live")) {
return;
}
$this.data("live",true);
doStuff();
});
This one works (see fiddle):
jQuery(function($) {
$("p").live('customEvent', function(event, chkSomething) {
//this particular custom event works with live
if (chkSomething) {
doStuff();
// BUT only per element
// So almost like a .one(), but on an elemental basis, and .live()?
$(this).bind('customEvent', false);
}
});
function doStuff() {
window.alert('ran dostuff');
};
$('#content').append('<p>Here is a test</p>');
$('p').trigger('customEvent', {one: true});
$('p').trigger('customEvent', {one: true});
$('p').trigger('customEvent', {one: true});
});
This should also work for your needs, although it's not as pretty :)
$("p").live('customEvent', function (event, chkSomething){
//this particular custom event works with live
if(chkSomething && $(this).data('customEventRanAlready') != 1){
doStuff();
// BUT only per element
// So almost like a .one(), but on an elemental basis, and .live()?
$(this).data('customEventRanAlready', 1);
}
})
Like Kevin mentioned, you can accomplish this by manipulating the CSS selectors, but you actually don't have to use :not(). Here's an alternative method:
// Use an attribute selector like so. This will only select elements
// that have 'theImage' as their ONLY class. Adding another class to them
// will effectively disable the repeating calls from live()
$('div[class=theImage]').live('inview',function(event, visible, visiblePartX, visiblePartY) {
if (visiblePartY=="top") {
$(this).animate({ opacity: 1 });
$(this).addClass('nolive');
console.log("look just how many times this is firing")
}
});
I used the actual code from your site. Hope that was okay.

Titanium Mobile: reference UI elements with an ID?

How do you keep track of your UI elements in Titanium? Say you have a window with a TableView that has some Switches (on/off) in it and you'd like to reference the changed switch onchange with a generic event listener. There's the property event.source, but you still don't really know what field of a form was just toggled, you just have a reference to the element. Is there a way to give the element an ID, as you would with a radiobutton in JavaScript?
Up to now, registered each form UI element in a dictionary, and saved all the values at once, looping through the dictionary and getting each object value. But now I'd like to do this onchange, and I can't find any other way to do it than create a specific callback function for each element (which I'd really rather not).
just assign and id to the element... all of these other solution CAN work, but they seem to be over kill for what you are asking for.
// create switch with id
var switcher0 = Ti.Ui.createSwitch({id:"switch1"});
then inside your event listener
myform.addEventListener('click', function(e){
var obj = e.source;
if ( obj.id == "switch1" ) {
// do some magic!!
}
});
A simple solution is to use a framework that helps you keep track of all your elements, which speeds up development quite a bit, as the project and app grows. I've built a framework of my own called Adamantium.js, which lets you use a syntax like jQuery to deal with your elements, based on ID and type selectors. In a coming release, it will also support for something like classes, that can be arbitrarily added or removed from an element, tracking of master/slave relationships and basic filter methods, to help you narrow your query. Most methods are chainable, so building apps with rich interaction is quick and simple.
A quick demo:
// Type selector, selects all switches
$(':Switch')
// Bind a callback to the change event on all switches
// This callback is also inherited by all new switch elements
$(':Switch').bind('change', function (e) {
alert(e.type + ' fired on ' + e.source.id + ', value = ' + e.value);
});
// Select by ID and trigger an event
$('#MyCustomSwitch').trigger('change', {
foo: 'bar'
});
Then there's a lot of other cool methods in the framework, that are all designed to speed up development and modeled after the familiar ways of jQuery, more about that in the original blog post.
I completely understand not wanting to write a listener to each one because that is very time consuming. I had the same problem that you did and solved it like so.
var switches = [];
function createSwitch(i) {
switches[i] = Ti.UI.createSwitch();
switches[i].addEventListener('change', function(e) {
Ti.API.info('switch '+i+' = '+e.value);
});
return switches[i];
}
for(i=0;i<rows.length;i++) {
row = Ti.UI.createTableViewRow();
row.add(createSwitch(i));
}
However keep in mind that this solution may not fit your needs as it did mine. For me it was good because each time I created a switch it added a listener to it dynamically then I could simply get the e.source.parent of the switch to interact with whatever I needed.
module Id just for the hold it's ID. When we have use id the call any another space just use . and use easily.
Try This
var but1 = Ti.Ui.createButton({title : 'Button', id:"1"});
window.addEventListener('click', function(e){
var obj = e.source;
if ( obj.id == "1" ) {
// do some magic!!
}
});
window.add(but1);
I, think this is supported for you.
how do you create your tableview and your switcher? usually i would define a eventListener function while creating the switcher.
// first switch
var switcher0 = Ti.Ui.createSwitch();
switch0.addEventListener('change',function(e){});
myTableViewRow.add(switch0);
myTableView.add(myTableViewRow);
// second switch
var switch1 = ..
so no generic event listener is needed.

jQuery Live implementation in Prototype

Element.implement({
addLiveEvent: function(event, selector, fn){
this.addEvent(event, function(e){
var t = $(e.target);
if (!t.match(selector)) return false;
fn.apply(t, [e]);
}.bindWithEvent(this, selector, fn));
}
});
$(document.body).addLiveEvent('click', 'a', function(e){ alert('This is a live event'); });
The above code was done in a similar question to implement .live behaviour in Mootools. I've read the question: Prototype equivalent for jQuery live function.
How do I implement this in Prototype? Probably something that can be implemented like this:
document.liveobserve('click', 'a', function(e){ alert('This is a live event');
Edited to make the question clear.
The simplest (and perhaps not the fastest or best) way would appear to be something like:
Element.live = function(evType, evSelector, evBlock) {
var mySelector = evSelector;
var myBlock = evBlock;
this.observe(evType, function(ev) {
if (ev.target.match(mySelector)) {
evBlock(ev);
}
});
};
The parameters evSelector and evBlock are assigned to local variables so the they are available to the event handler (It's a closure). The passed block evBlock gets passed the event object just like a normal Prototype event handler.
It should be noted this is going to handle every event of type 'evType' so if it's a mouseMove/mouseOver this is going to make your page slow. Also FireBug will probably just go to sleep on you due to the number of events that it has to single step through.
EDIT: Changed as per comments

Resources