Como detectar Adblock e criar mensagem personalizada

Com este script você consegue detectar o bloqueador de anúncio e deixar uma mensagem aos leitores. Use com sabedoria!
0
25

Bloqueadores de anúncio são um conforto para o público, especialmente quem usa conexões lentas e pacotes de dados restritivos. Ninguém gosta de entrar num site e levar duas janelas pulando na cara antes de sequer ler o conteúdo. Nem de ser amolado por blocos gigantescos de propaganda que aparecem de repente no lugar do texto. Eu não gosto. Nem você, nem ninguém.

Por outro lado, tal conforto afetou incontáveis projetos online, de todos os tamanhos. Desde pequenos blogs até grandes portais, a perda de rendimentos com a popularização dos AdBlock levou vários ao encerramento de atividades. Outros adotaram táticas alternativas para manter ganhos, como listas de e-mail para vendas comissionadas e — a pior de todas — paywalls.

O Tutoriart foi afetado. Desde a fundação, em 2010, até por volta de 2012, ele só melhorava. Cheguei a considerar torná-lo profissão, mas vieram os bloqueadores de anúncio. Ganhos despencaram, e desde então, estagnaram num valor que nem permite sonhar com tal possibilidade. Imagine sites de médio/grande porte, com profissionais contratados e contas sem fim. Um pesadelo.

A discussão chegou ao ponto de se propor na Europa a legalização do ban de usuários de AdBlock por companhias de mídia. Estima-se que até 2015, mais de 500 milhões de dispositivos no mundo usavam algum bloqueador de anúncios. E destes, quase 150 milhões eram desktops, que ao menos em teoria seriam menos afetados por limitações de banda.

Ou seja: bloquear está se tornando um padrão. Navegadores como o Opera são configurados para bloqueá-los, mesmo sem o usuário pedir.

Vários sites e portais de notícias responderam com paywalls, incluindo alguns dos maiores brasileiros como o UOL, Folha de São Paulo e O Globo. Eles seguem o modelo "poroso" de paywall, ou seja, o leitor consegue ler um número específico de matérias gratuitas por mês. O modelo "sólido" de parede, em que só assinantes têm acesso e fim, se mostrou fracassado, afastando a maioria do público.

O que fazer?

Então, como fechar a conta sem incomodar o leitor?

Se seu site tem conteúdo interessante para um leitor assiná-lo, não há nada errado com o paywall. É uma alternativa dura, mas necessária. Muito mais errado é fechar por falta de receita — ou além de produzir conteúdo, ainda pagar para trabalhar.

O código do AdBlock é constantemente alterado para superar "remendos" que webmasters criam para detectá-lo. É uma batalha constante, e ao ler este artigo, talvez o método mostrado aqui já tenha sido contornado, e outros virão, etc. Ele se baseia em detecção por Javascript.

O nome do script é o singelo FuckAdBlock, de Valentin Allaire. Calma, não vamos mandar seu amado AdBlock se *****. Não ainda.

Como vai funcionar?

  1. Criamos um arquivo com a extensão .js, que será colocada em seu servidor.
  2. O script é chamado no template do seu site em WordPress.
  3. Se tudo estiver certo, a detecção já está ativa, basta usar um trecho de código que conterá a substituição do bloco de anúncio por uma mensagem ao usuário de AdBlock

Vale notar que essa abordagem não é para criação de um paywall ou coisa do tipo, embora também sirva para atrair leitores a um campo de assinatura ou página. A ideia é simplesmente deixar uma mensagem ao bloqueador de anúncio.

Importante reforçar que, se essa mensagem for abusiva, espere um resultado muito negativo por parte do leitor. Não use para bloquear conteúdo ou impedindo a navegação. Não deixe mensagens grosseiras, irônicas ou rancorosas. É tiro no pé.

Primeiro, copie o seguinte código e cole num arquivo chamado "fuckadb.js":

/*
 * FuckAdBlock 3.2.1
 * Copyright (c) 2015 Valentin Allaire <[email protected]>
 * Released under the MIT license
 * https://github.com/sitexw/FuckAdBlock
 */

(function(window) {
	var FuckAdBlock = function(options) {
		this._options = {
			checkOnLoad:		false,
			resetOnEnd:			false,
			loopCheckTime:		50,
			loopMaxNumber:		5,
			baitClass:			'pub_300x250 pub_300x250m pub_728x90 text-ad textAd text_ad text_ads text-ads text-ad-links',
			baitStyle:			'width: 1px !important; height: 1px !important; position: absolute !important; left: -10000px !important; top: -1000px !important;',
			debug:				false
		};
		this._var = {
			version:			'3.2.1',
			bait:				null,
			checking:			false,
			loop:				null,
			loopNumber:			0,
			event:				{ detected: [], notDetected: [] }
		};
		if(options !== undefined) {
			this.setOption(options);
		}
		var self = this;
		var eventCallback = function() {
			setTimeout(function() {
				if(self._options.checkOnLoad === true) {
					if(self._options.debug === true) {
						self._log('onload->eventCallback', 'A check loading is launched');
					}
					if(self._var.bait === null) {
						self._creatBait();
					}
					setTimeout(function() {
						self.check();
					}, 1);
				}
			}, 1);
		};
		if(window.addEventListener !== undefined) {
			window.addEventListener('load', eventCallback, false);
		} else {
			window.attachEvent('onload', eventCallback);
		}
	};
	FuckAdBlock.prototype._options = null;
	FuckAdBlock.prototype._var = null;
	FuckAdBlock.prototype._bait = null;
	
	FuckAdBlock.prototype._log = function(method, message) {
		console.log('[FuckAdBlock]['+method+'] '+message);
	};
	
	FuckAdBlock.prototype.setOption = function(options, value) {
		if(value !== undefined) {
			var key = options;
			options = {};
			options[key] = value;
		}
		
		for(var option in options) {
			this._options[option] = options[option];
			if(this._options.debug === true) {
				this._log('setOption', 'The option "'+option+'" he was assigned to "'+options[option]+'"');
			}
		}
		return this;
	};
	
	FuckAdBlock.prototype._creatBait = function() {
		var bait = document.createElement('div');
			bait.setAttribute('class', this._options.baitClass);
			bait.setAttribute('style', this._options.baitStyle);
		this._var.bait = window.document.body.appendChild(bait);
		this._var.bait.offsetParent;
		this._var.bait.offsetHeight;
		this._var.bait.offsetLeft;
		this._var.bait.offsetTop;
		this._var.bait.offsetWidth;
		this._var.bait.clientHeight;
		this._var.bait.clientWidth;
		
		if(this._options.debug === true) {
			this._log('_creatBait', 'Bait has been created');
		}
	};
	FuckAdBlock.prototype._destroyBait = function() {
		window.document.body.removeChild(this._var.bait);
		this._var.bait = null;
		
		if(this._options.debug === true) {
			this._log('_destroyBait', 'Bait has been removed');
		}
	};
	
	FuckAdBlock.prototype.check = function(loop) {
		if(loop === undefined) {
			loop = true;
		}
		
		if(this._options.debug === true) {
			this._log('check', 'An audit was requested '+(loop===true?'with a':'without')+' loop');
		}
		
		if(this._var.checking === true) {
			if(this._options.debug === true) {
				this._log('check', 'A check was canceled because there is already an ongoing');
			}
			return false;
		}
		this._var.checking = true;
		
		if(this._var.bait === null) {
			this._creatBait();
		}
		
		var self = this;
		this._var.loopNumber = 0;
		if(loop === true) {
			this._var.loop = setInterval(function() {
				self._checkBait(loop);
			}, this._options.loopCheckTime);
		}
		setTimeout(function() {
			self._checkBait(loop);
		}, 1);
		if(this._options.debug === true) {
			this._log('check', 'A check is in progress ...');
		}
		
		return true;
	};
	FuckAdBlock.prototype._checkBait = function(loop) {
		var detected = false;
		
		if(this._var.bait === null) {
			this._creatBait();
		}
		
		if(window.document.body.getAttribute('abp') !== null
		|| this._var.bait.offsetParent === null
		|| this._var.bait.offsetHeight == 0
		|| this._var.bait.offsetLeft == 0
		|| this._var.bait.offsetTop == 0
		|| this._var.bait.offsetWidth == 0
		|| this._var.bait.clientHeight == 0
		|| this._var.bait.clientWidth == 0) {
			detected = true;
		}
		if(window.getComputedStyle !== undefined) {
			var baitTemp = window.getComputedStyle(this._var.bait, null);
			if(baitTemp && (baitTemp.getPropertyValue('display') == 'none' || baitTemp.getPropertyValue('visibility') == 'hidden')) {
				detected = true;
			}
		}
		
		if(this._options.debug === true) {
			this._log('_checkBait', 'A check ('+(this._var.loopNumber+1)+'/'+this._options.loopMaxNumber+' ~'+(1+this._var.loopNumber*this._options.loopCheckTime)+'ms) was conducted and detection is '+(detected===true?'positive':'negative'));
		}
		
		if(loop === true) {
			this._var.loopNumber++;
			if(this._var.loopNumber >= this._options.loopMaxNumber) {
				this._stopLoop();
			}
		}
		
		if(detected === true) {
			this._stopLoop();
			this._destroyBait();
			this.emitEvent(true);
			if(loop === true) {
				this._var.checking = false;
			}
		} else if(this._var.loop === null || loop === false) {
			this._destroyBait();
			this.emitEvent(false);
			if(loop === true) {
				this._var.checking = false;
			}
		}
	};
	FuckAdBlock.prototype._stopLoop = function(detected) {
		clearInterval(this._var.loop);
		this._var.loop = null;
		this._var.loopNumber = 0;
		
		if(this._options.debug === true) {
			this._log('_stopLoop', 'A loop has been stopped');
		}
	};
	
	FuckAdBlock.prototype.emitEvent = function(detected) {
		if(this._options.debug === true) {
			this._log('emitEvent', 'An event with a '+(detected===true?'positive':'negative')+' detection was called');
		}
		
		var fns = this._var.event[(detected===true?'detected':'notDetected')];
		for(var i in fns) {
			if(this._options.debug === true) {
				this._log('emitEvent', 'Call function '+(parseInt(i)+1)+'/'+fns.length);
			}
			if(fns.hasOwnProperty(i)) {
				fns[i]();
			}
		}
		if(this._options.resetOnEnd === true) {
			this.clearEvent();
		}
		return this;
	};
	FuckAdBlock.prototype.clearEvent = function() {
		this._var.event.detected = [];
		this._var.event.notDetected = [];
		
		if(this._options.debug === true) {
			this._log('clearEvent', 'The event list has been cleared');
		}
	};
	
	FuckAdBlock.prototype.on = function(detected, fn) {
		this._var.event[(detected===true?'detected':'notDetected')].push(fn);
		if(this._options.debug === true) {
			this._log('on', 'A type of event "'+(detected===true?'detected':'notDetected')+'" was added');
		}
		
		return this;
	};
	FuckAdBlock.prototype.onDetected = function(fn) {
		return this.on(true, fn);
	};
	FuckAdBlock.prototype.onNotDetected = function(fn) {
		return this.on(false, fn);
	};
	
	window.FuckAdBlock = FuckAdBlock;
	
	if(window.fuckAdBlock === undefined) {
		window.fuckAdBlock = new FuckAdBlock({
			checkOnLoad: true,
			resetOnEnd: true
		});
	}
})(window);

Salve este arquivo em seu servidor. Pode ser numa pasta do template, por exemplo.

Em seguida, chame o script dentro do template. Uma opção para incluí-lo automaticamente em todo o site é usar a função enqueue do WordPress. No arquivo functions.php do seu template, inclua o seguinte:

function venha_bloqueador() {
	wp_enqueue_script('fuckadb', get_stylesheet_directory_uri().'/includes/fuckadb.js', array('jquery'), true);
}
add_action( 'wp_enqueue_scripts', 'venha_bloqueador' );

Salve e atualize no servidor. O caminho indicado vai procurar o script numa pasta chamada "includes", que ficará na pasta-raíz de um tema-filho ou tema principal. Se preciso, ajuste o caminho.

Falta só criar o conteúdo da mensagem. Acrescente a algum lugar do tema — pode ser o footer ou mesmo dentro de algum arquivo como o single.php:

<script>
if(typeof fuckAdBlock === 'undefined') {
	adBlockDetected();
} else {
	fuckAdBlock.onDetected(adBlockDetected);
	fuckAdBlock.onNotDetected(adBlockNotDetected);
	// and|or
	fuckAdBlock.on(true, adBlockDetected);
	fuckAdBlock.on(false, adBlockNotDetected);
	// and|or
	fuckAdBlock.on(true, adBlockDetected).onNotDetected(adBlockNotDetected);
}

// Change the options
fuckAdBlock.setOption('checkOnLoad', false);
// and|or
fuckAdBlock.setOption({
	debug: true,
	checkOnLoad: false,
	resetOnEnd: false
});
	// Function called if AdBlock is not detected
	function adBlockNotDetected() {
		
	}
	// Function called if AdBlock is detected
	function adBlockDetected() {
		document.getElementById('minhadiv').innerHTML = 'Por favor, considere nos desbloquear em seu AdBlock. Saiba mais.';
		document.getElementById('sidegog').innerHTML = '';
	}
	</script>

O que esse último trecho faz?

Logo de cara ele checa se o script foi impedido (atualizações do AdBlock podem incluir o script na lista de restrições); se for o caso, a presença do AdBlock é considerada verdade.

Em seguida, vai detectar um elemento com a ID "minhadiv", que pode ser uma div. Seu conteúdo, que pode ser um código de AdSense, será substituído pela mensagem "Por favor, considere nos desbloquear em seu AdBlock. Saiba mais".

Em "Saiba mais", haverá um link para uma página em que você pode explicar suas razões para solicitar o whitelisting no bloqueador.

Resolve?

Depende do leitor e do seu conteúdo. A verdade é que se o visitante quiser bloquear, nada do que você faça ou peça vai resolver: ele vai simplesmente achar um método de bloquear até aquela solicitação. Ou até vai se ofender com o pedido e não voltar mais. Pedir desbloqueio é indicado para sites que realmente não abusam de propaganda, não usam pop-ups, etc.

A receita é essa. Faça bom uso dela.

- Publicidade -

Receba atualizações do Tutoriart

É grátis, e você pode escolher entre receber só sugestões sobre arte, design gráfico, Photoshop, etc, ou só sobre WordPress, blogging, design web, snippets, etc. Ou tudo, se preferir!

Quero assinar...
Ao assinar, você concorda com os Termos de Privacidade.

DEIXE UMA RESPOSTA

Por favor, digite seu comentário!
Por favor, digite seu nome aqui