├── counter.php ├── banners.html ├── banners.php └── banners.js /counter.php: -------------------------------------------------------------------------------- 1 | true, 9 | "data" => true 10 | ); 11 | 12 | echo $funcName . "(" . json_encode($response) . ")"; -------------------------------------------------------------------------------- /banners.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | test 7 | 8 | 9 | 10 | 11 | 12 |

test 1

13 | 14 |

Supports all browsers from Internet Explorer 6

15 | 16 |
17 | 18 | 19 |

Reload banner (click several times if the banner does not change)

20 | 21 | 22 | -------------------------------------------------------------------------------- /banners.php: -------------------------------------------------------------------------------- 1 | array( 11 | array("id"=>"001", "type"=>"image", "src"=>"http://mmm.neti.ee/reklaam/users/480f0f35cd842/775x120.gif", "width"=>775, "height"=>120), 12 | array("id"=>"002", "type"=>"image", "src"=>"http://mmm.neti.ee/reklaam/users/480f0f35cd842/728x90.gif", "width"=>728, "height"=>90), 13 | array("id"=>"002", "type"=>"image", "src"=>"http://mmm.neti.ee/reklaam/users/480f0f35cd842/600x60.gif", "width"=>600, "height"=>60), 14 | array("id"=>"002", "type"=>"image", "src"=>"http://mmm.neti.ee/reklaam/users/480f0f35cd842/200x600.gif", "width"=>200, "height"=>600), 15 | array("id"=>"002", "type"=>"image", "src"=>"http://mmm.neti.ee/reklaam/users/480f0f35cd842/600x300_asemel.gif", "width"=>600, "height"=>300) 16 | 17 | ) 18 | ); 19 | 20 | $areas = array(); 21 | foreach($_GET as $key => $val){ 22 | $keyParts = explode("~", $key); 23 | if(count($keyParts) == 2 && $keyParts[0] == "area"){ 24 | $areas[] = $keyParts[1]; 25 | } 26 | } 27 | 28 | $data = array(); 29 | foreach($areas as $area){ 30 | $count = intval($_GET["area~".$area]); 31 | if($banners[$area]){ 32 | $arr = $banners[$area]; 33 | shuffle($arr); 34 | $data[$area] = array_slice($arr, 0, $count); 35 | } 36 | } 37 | 38 | $response = array( 39 | "success" => true, 40 | "data" => $data 41 | ); 42 | 43 | echo $funcName . "(" . json_encode($response) . ")"; 44 | -------------------------------------------------------------------------------- /banners.js: -------------------------------------------------------------------------------- 1 | 2 | var AD_HOST = "."; 3 | 4 | // Uses only ES3 to support IE6+ 5 | easyBanners = { 6 | 7 | // indicates if dom ready was already fired 8 | _alreadyStarted: false, 9 | 10 | // counter for generating unique jsonp callback functions 11 | _funcCounter: 0, 12 | 13 | // function store for jsonp callback functions 14 | _funcs: {}, 15 | 16 | // handlers for banner types, eg. {"image": ImageHandler} 17 | _handlers: {}, 18 | 19 | // stores current DOM nodes on the page that should host banners 20 | _map: {areas:{}, keys:[]}, 21 | 22 | // contain ids of displayed banners 23 | _idCounter: [], 24 | 25 | // setups handlers for dom loaded event 26 | init: function(ready){ 27 | var that = this; 28 | 29 | if(ready){ 30 | return this.ready(); 31 | } 32 | 33 | this.observe(document, "DOMContentLoaded", function(){ 34 | that.ready(); 35 | }); 36 | 37 | this.observe(document, "readystatechange", function(){ 38 | that.ready(); 39 | }); 40 | 41 | this.observe(window, "load", function(){ 42 | that.ready(); 43 | }); 44 | }, 45 | 46 | // run when dom has been loaded 47 | ready: function(){ 48 | 49 | // if this is not the very first run, skip it 50 | if(this._alreadyStarted){ 51 | return false; 52 | } 53 | this._alreadyStarted = true; 54 | 55 | var areas, area, i, len; 56 | 57 | // find all DOM nodes with data-banner attribute 58 | areas = this.selectorFunc("banner"); 59 | 60 | // find differnet "area" types 61 | for(i = 0, len = areas.length; i < len; i++){ 62 | if(!(area = this.getDataAttribute(areas[i], "area"))){ 63 | continue; 64 | } 65 | 66 | if(!this._map.areas[area]){ 67 | this._map.areas[area] = [{node: areas[i]}]; 68 | }else{ 69 | this._map.areas[area].push({node: areas[i]}); 70 | } 71 | } 72 | 73 | if("keys" in Object){ 74 | this._map.keys = Object.keys(this._map.areas); 75 | }else{ 76 | for(i in this._map.areas){ 77 | if(this._map.areas.hasOwnProperty(i)){ 78 | this._map.keys.push(i); 79 | } 80 | } 81 | } 82 | 83 | this.loadBanners(); 84 | }, 85 | 86 | // load banners from the server, required banners are defined by used "areas" 87 | loadBanners: function(){ 88 | var queryParams = [], page, that = this; 89 | 90 | // reset id counter 91 | this._idCounter = []; 92 | 93 | queryParams.push("url="+encodeURIComponent(window.location.href)); 94 | 95 | // add all "areas" and the count of how many banners for such an area is needed 96 | for(var i=0, len = this._map.keys.length; i < len; i++){ 97 | queryParams.push(encodeURIComponent("area~" + this._map.keys[i]) + "=" + this._map.areas[this._map.keys[i]].length); 98 | } 99 | 100 | // make a JSONP request to the server to load banner data 101 | this.jsonp(AD_HOST + "/banners.php?" + queryParams.join("&"), function(err, data){ 102 | if(err){ 103 | // error usually fires when response status is not 200, or response has a syntax error 104 | if(typeof console == "object" && typeof console.log == "function"){ 105 | console.log(err.message); 106 | } 107 | return; 108 | } 109 | 110 | that.handleLoadedBanners(data); 111 | }); 112 | }, 113 | 114 | // match DOM nodes with banner data loaded from the server 115 | handleLoadedBanners: function(banners){ 116 | var key; 117 | for(var i=0, len = this._map.keys.length; i < len; i++){ 118 | key = this._map.keys[i]; 119 | if(banners[key] && this._map.areas[key]){ 120 | for(var j=0, jlen = this._map.areas[key].length; j < jlen; j++){ 121 | if(!banners[key].length){ 122 | break; 123 | } 124 | this._map.areas[key][j].banner = banners[key].shift(); 125 | this.setupBanner(this._map.areas[key][j]); 126 | } 127 | } 128 | } 129 | 130 | // if there is something to count, send the info to the server 131 | if(this._idCounter.length){ 132 | var url = AD_HOST + "/counter.php?url="+encodeURIComponent(window.location.href)+"count=" + this._idCounter.join(","); 133 | this.jsonp(url, function(err, success){ 134 | 135 | }); 136 | } 137 | }, 138 | 139 | // checks if an handler exists for selected banner and runs it 140 | setupBanner: function(element){ 141 | var handler; 142 | if(element && element.banner && element.banner.id && this._handlers[element.banner.type]){ 143 | handler = new this._handlers[element.banner.type](element); 144 | if(handler.paint()){ 145 | this._idCounter.push(element.banner.id); 146 | } 147 | } 148 | }, 149 | 150 | // DOM RELATED METHODS 151 | 152 | observe: function(element, evt, listener){ 153 | if("addEventListener" in document){ 154 | return ((this.observe = function(element, evt, listener){ 155 | return element.addEventListener(evt, listener, false); 156 | }))(element, evt, listener); 157 | }else if("attachEvent" in window){ 158 | return ((this.observe = function(element, evt, listener){ 159 | return element.attachEvent("on" + evt, listener); 160 | }))(element, evt, listener); 161 | } 162 | 163 | return false; 164 | }, 165 | 166 | selectorFunc: function(name){ 167 | if(document.querySelectorAll){ 168 | this.selectorFunc = function(name){ 169 | if(!name){ 170 | return []; 171 | }else{ 172 | name = "data-" + name; 173 | } 174 | return Array.prototype.slice.call(document.querySelectorAll("[" + name + "]")); 175 | }; 176 | }else{ 177 | this.selectorFunc = function(name){ 178 | var dataElements = [], 179 | elements = document.getElementsByTagName("*"); 180 | 181 | if(!name){ 182 | return []; 183 | }else{ 184 | name = "data-" + name; 185 | } 186 | 187 | for(var i=0; i