Блогът на Гонзо

Как да подобрим in-text рекламите на EasyAds

Миналата седмица един клиент ни препрати код от EasyAds, чрез който да се активират реклами върху ключови думи в текста на сайта. Като оставим настрана самата идея половината думи в текста да станат рекламни връзки и на всичкото отгоре със досадни блокчета, които изскачат като минете с мишката върху тях, въпросният код ме накара няколко пъти да изразя възмущението си в Twitter.

Ще започна с това, че JavaScript-ът разчиташе на document.write(). Това е една ужасно лоша практика, за съжаление в арсенала на всички рекламни мрежи. Освен, че методът е нодопустим в XHTML страници, използването му за добавяне на елемент script води до забавяне (или дори блокиране) на зареждането на страницата докато се изтегли скриптът и съответно влошаване на потребителското изживяване.

Оригиналният скрипт изглежда така:

<script type="text/javascript"><!--//<![CDATA[
var dd=et=dc=ur=rf=sc=scr="";
var cb=0;
scr=screen;
dd=new Date();
dc=document;
et=dd.getTimezoneOffset()+dd.getTime();
sc=scr.width+"x"+scr.height;
cb=Math.round(Math.random()*21474836);
rf=escape(dc.referrer);
ur="ht"+"tp://media.easyads.bg/intext.php?rid=XXX&scr="+sc+"&et="+et+"&cb="+cb+"&rf="+rf+"&md5checksum=ZZZ";
dc.writeln("<sc"+"ript src=\""+ur+"\" type=\"text/jav"+"ascr"+"ipt\"></scr"+"ipt>");
//]]>--></script>

Как да се освободим от document.write() методът? Естествено чрез DOM:

<script type="text/javascript"><!--//<![CDATA[
var dd=et=dc=ur=rf=sc=scr="";
var cb=0;
scr=screen;
dd=new Date();
dc=document;
et=dd.getTimezoneOffset()+dd.getTime();
sc=scr.width+"x"+scr.height;
cb=Math.round(Math.random()*21474836);
rf=escape(dc.referrer);
ur="ht"+"tp://media.easyads.bg/intext.php?rid=XXX&scr="+sc+"&et="+et+"&cb="+cb+"&rf="+rf+"&md5checksum=ZZZ";
var sc = dc.createElement('script');
sc.src = ur;
var head = dc.getElementsByTagName('head')[0];
head.appendChild(sc);
//]]>--></script>

Тъй като в сайта използваме така или иначе jQuery, горния пример придобива малко по-прост вид:

<script type="text/javascript"><!--//<![CDATA[
var dd=et=dc=ur=rf=sc=scr="";
var cb=0;
scr=screen;
dd=new Date();
dc=document;
et=dd.getTimezoneOffset()+dd.getTime();
sc=scr.width+"x"+scr.height;
cb=Math.round(Math.random()*21474836);
rf=escape(dc.referrer);
ur="ht"+"tp://media.easyads.bg/intext.php?rid=XXX&scr="+sc+"&et="+et+"&cb="+cb+"&rf="+rf+"&md5checksum=ZZZ";
$(window).load(function(){
$.getScript(ur);
});
//]]>--></script>

Както виждате, никак не е трудно въпросният скрипт с динамично генериран адрес да се добави към страницата така, че да не се блокира зареждането на страницата. Повече по въпроса можете да прочетете в тази статия на Стоян в YUIBlog.

Следващият проблем в рекламите на EasyAds беше с изискванията им за кода на страницата, за да работи техния скрипт. Според тях текстът, в който искаме да има реклами, трябва да бъде заграден от <div class="EasyadsIntext">. Чудесно, при нас текстът е заграден от div, който вече има клас, добавих и техния клас и… йок! За да работи чудото, елементът трябва да е изписан така, както е показано в техния пример – не може да има други класове. Естествено, че полудях! Толкова ли е трудно да намериш всички елементи в DOM, които имат даден клас? Естествено че не, не ставай смешен! Методът се нарича getElementsByClassName и се поддържа от всички съвременни браузъри. За съжаление най-популярният браузър не е сред тях, но това не пречи за него да напишем малка функцийка, която да върши необходимата работа.

И така, в кода на EasyAds намирам следната функция:

function getElementsByStyleClass (className){ 
var all = document.all ? document.all : document.getElementsByTagName('*'); 
var elements = new Array(); 
for (var e = 0; e < all.length; e++) 
	if (all[e].className == className) elements[elements.length] = all[e]; 
return elements; 
}

Доста първичен подход към задачата. Аз като мързелив човек се поразрових и естествено попаднах на статия на Робърт Нийман, в която той дава работещо решение. Неговата функция е доста по-пълна откъм функционалност, но по-важното е, че използва DOM методът, когато е наличен в браузъра и по този начин работи много по-бързо за повечето потребители. Задължително прочетете и коментарите под тази публикация на PPK, макар и стари, има доста полезна информация.

Третият проблем, който имах с EasyAds се дължеше на факта, че пробвах скрипта на тестовия ни сървър. Работата е там, че той е с адрес напълно различен от този на работещия сайт и явно EasyAds проверяват от къде правите заявката. Нищо лошо, обаче начинът да ви информира, че нещо не е наред, беше следния:

document.write('Error');

Веднага си спомних кое е първото нещо, което един уеб-разработчит трябва да може според Ники Бачийски. И ако не сте разбрали защо, това е един чудесен пример. След като на страницата нищо не се случи, първо проверих с Firebug дали има заявка към сървъра на EasyAds. Да, имаше заявка и всичко с нея беше наред, статус 200. Тогава проверих и съдържанието на отговора. Нямаше ли да е по-добре, ако при некоректна заявка сървърът връщаше подходящ статус? Например 400 или 403? Тогава браузърът ще знае, че заявката е неуспешна и няма да изпълни нищо, което от своя страна няма да доведе до промяна в съдържаниет на страницата. Ако не знаете какво означава кодовете за статус на HTTP протокола, описани са в RFC 2616.

Етикети: , ,

6 коментара по “Как да подобрим in-text рекламите на EasyAds

  1. Гонзо

    Е той кода беше на 1 ред, ама не се чете така, та го подредих малко. Докато им издиря функцията getElementsByStyleClass ква мъка беше…

  2. Евгени Йорданов

    Те естествено са го сложили на един ред, за да е трудно за четене разбира се. Стандартна техника. Статията е наистина добра… Може и аз да се възползвам скоро.

  3. Георги

    Аз да попитам рискуваме ли бан от мрежата, ако променяме кода.
    Или няма проблеми, зашото се чудя

  4. Гонзо

    @Георги, не виждам причина да те отрежат, тъй като промените по никакъв начин не променят начина на работа на системата. Промяната е единствено в начина на зареждане на скрипта. А и до сега сайтовете, в които работи променения код си показват рекламите без проблем.

Вашият коментар

Вашият имейл адрес няма да бъде публикуван. Задължителните полета са отбелязани с *