Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript ads in Angular templates

I'm trying to render a Javascript ad in my Angular template but it will not show up. I've found some solutions when they append the Javascript to the head tag but I want the ad to be placed in my Html (inside body).

Here is a Plunker: https://plnkr.co/edit/WHhQ95gS5HKSphmmirio

Here is a simple plain Html example that works.

    <html>
    <head>
    </head>
    <body>
    <div class="ad">
       <script src="http://media.affiliatelounge.com/data/nordicbet/ad_js/display_88.js?ad=ad_793270_88.html&amp;size=300x250&amp;clicktag=http://record.affiliatelounge.com/_sVuSoFFh4LK58VwA2IUESrKVVrME-Gsw/1&amp;media=108786&amp;campaign=1"></script>
    </div>
    </body>
    </html>

But if I add the div inside an Angular template it will not render and the console says nothing.

I have some ads up and running here (http://www.odds.nu/erbjudanden), but they are either .gif or iframes. I want to be able to show Javascript ads instead. They are added to the Html but are not rendered (placed in the bottom of the page).

Can $sce or $compile help somehow?

My index.html

    <div data-ng-view="" class="mainView"></div>

My app.js

    $routeProvider.when("/erbjudanden", {
          controller: "offerController",
          templateUrl: "/app/templates/offers.html"
    });

My offers.html

    <div class="ad">
       <script src="http://media.affiliatelounge.com/data/nordicbet/ad_js/display_88.js?ad=ad_793270_88.html&amp;size=300x250&amp;clicktag=http://record.affiliatelounge.com/_sVuSoFFh4LK58VwA2IUESrKVVrME-Gsw/1&amp;media=108786&amp;campaign=1"></script>
    </div>

Any solution?

like image 901
Kungen Avatar asked Feb 01 '16 21:02

Kungen


1 Answers

If you had inspected result of that url request(make sure adBlock is off)

https://wlbetclic.adsrv.eacdn.com/S.ashx?btag=a_17172b_14837c_&affid=12824&siteid=17172&adid=14837&c=

You will see the actual result

document.write('<script type="text/javascript" src="//wlbetclic.eacdn.com/TrafficOpt/s.5.4.min.js?t=1"></script>');
document.write('<script type="text/javascript" src="//wlbetclic.eacdn.com/wlbetclic/img/js/Affiliate_12824.js?t=20160224"></script>');
//other lines omitted for brevity

So this file is executing document.write which obviously will not work in angular, just because they are totally different (even though you could trigger digest cycle somehow, you still don't have access to modify that script file, as it's generated by 3rd party server and has own variables)

What i would do is - make a page like ad.html, just like index.html or 404.html, then request this file from angular (not as template, but like a view file) as an iframe src with custom attributes

And i would use custom DOM element, and populate contents with jQuery, or with angular, look at jQuery sample below

Also i would need krux/postscribe plugin, because you cannot use document.write in async html files

<!-- create multiple holders -->
<ad-holder url="https://wlbetclic.adsrv.eacdn.com/S.ashx?btag=a_17172b_14837c_&affid=12824&siteid=17172&adid=14837&c="></ad-holder>

<div class="black-widow">
    <!-- with size attributes -->
    <ad-holder url="http://google.com" width="100" height="40"></ad-holder>
</div>

<!-- jQuery population with iframe -->
<script>
    //get all custom elements
    $('ad-holder').each(function(){

        //create iframe placeholder
        var $iframe = $(document.createElement('iframe'));

        //get url of custom element
        var url = $(this).attr('url');

        //request ad.html file with params, currently it's url param
        $iframe.attr('src', 'ad.html?url=' + url);

        //some stylings acceptable here
        $iframe.width('100px');

        //or get styles from custom-element
        var heightValue = $(this).attr('height');
        $iframe.height(heightValue || '50px');

        //rebuild custom element with iframe
        $(this).append($iframe);
    });
</script>

<!-- angular populate with iframe directive -->
<scrip>
    angular.module('app', []).directive('adHolder', function(){
        return {
            restrict: 'E',
            scope: { url: '@' },
            //you could also execute in compile-phase
            link: function(scope, element, attribute){
                var $iframe = angular.element(document.createElement('iframe'));
                $iframe.attr('src', 'ad.html?url=' + scope.url);
                element.html($iframe);
            }
        }
    });
</script>

And ad.html would look like

<body>
  <div id="ad"></div>
  <script>
    function getQueryVariable(variable) {
      var query = window.location.search.substring(1);
      //for the sake of simplicity we expect only 1 param (url)
      return query.replace('url=', '');
    }
    var adUrl = getQueryVariable('url');
    if (adUrl) 
      postscribe('#ad', '<script src="' + adUrl + '"><\/script>');
    else {
      var $h1 = $(document.createElement('h1'));
      $h1.text('No ad available');
      $(document.body).append($h1);
    }
  </script>
</body>

The best part of this solution is that you can reuse same custom-element with different url attribute for any other ads

Checkout jQuery real working demo

Although this demo heavily uses jQuery, it's easy to tweak for angular version, which i would suggest you to implement as homework =)

like image 156
Medet Tleukabiluly Avatar answered Oct 04 '22 00:10

Medet Tleukabiluly