438

I would like to be able to detect if the user is using adblocking software when they visit my website. If they are using it, I want to display a message asking them to turn it off in order to support the project, like this website does.

If you enter to that site and your browser has some kind of adblock software enabled, then the site instead of showing the actual ads shows a little banner telling the users that the ad revenue is used for hosting the project and they should consider turning Adblock off.

I want to do that on my website, I'm using adsense ads on it, How can I do that?

Paolo Forgia
  • 6,572
  • 8
  • 46
  • 58
Jmlevick
  • 6,504
  • 9
  • 29
  • 35
  • 2
    possible duplicate of [Detecting AdBlocking software?](http://stackoverflow.com/questions/1185067/detecting-adblocking-software) – 416E64726577 Dec 17 '14 at 21:03
  • 6
    For users looking for a latest solution, please know that there is a comprehensive pluggable solution available at https://github.com/sitexw/BlockAdBlock – yeaske Sep 29 '15 at 15:02
  • 8
    Some people simply don't like to be analysed and advertised at on the web. Some sites I've visited, telling us that the revenue supports their project, are so bogged down in ads it becomes ridiculous. – Paul Mar 29 '16 at 07:49
  • 12
    Now that sites are doing this more and more (and abusing it, and lying to us about their ads being unintrusive, and forcing us to whitelist their whole site just to enter...) -- Are there any extensions or tricks we can use to prevent them from detecting we use AdBlock+? -- I don't mind seeing a few targeted banner ads here or there, but click jacking, and constant full screen video pop-ups are not my thing guys. – BrainSlugs83 Aug 02 '16 at 19:51
  • 1
    Please see my solution, it's the simple and clean. Pure JS, no extra requests, no external libraries or plugins or any other BS. – Cumulo Nimbus Aug 30 '16 at 19:50
  • 3
    As a recommendation: If you can tell people are using an adblocker, telling them to 'stop' isn't really going to help you much, and blocking content generally just annoys people. I always recommend, if you can tell they're using adblock, simply have some locally-hosted test ads. These generally get more clickthrough and higher payout anyway, or have a cheap lifetime membership that comes with ad-free and advertise that in the ad space. And never block content as them sharing it is free WOM for your site. – lilHar Jan 08 '18 at 20:57
  • 1
    Another one who wants to dictate what I am running on my own computer. How about, if your site is so good, you actually get companies to sponsor your page instead of using adservers, they pay to be displayed on the page whether anyone clicks through or not because it's the information they have given that is the real advertising, and their name is embedded non-intrusively as a "page sponsor" in which case I can't really see how an ad-blocker can block it, as it is purely page content. It's my computer and I'll run what I want to on it. – CashCow Jul 22 '21 at 15:27

47 Answers47

493

My solution is not specific to a certain ad network and is very lightweight. I've been running it in production for a few years. AdBlock blocks all URLs containing the word "ads" or "prebid". So this is what I did:

I added a small js file to my webroot with the name prebid-ads.js

This is the only line of code in that file. Update 2022-04-26 Call this variable something else, see below!

var canRunAds = true;

Then somewhere in your page:

<html>
  <head>
    <script src="/js/prebid-ads.js"></script>
  </head>
  <body>
    <script>
      if( window.canRunAds === undefined ){
        // adblocker detected, show fallback
        showFallbackImage();
      }
    </script>
  </body>
</html>

Update 2022-04-26 uBlock Origin loads their own ads-prebid.js that reverts the trick described in this answer (proud!), their file contains the following:

(function() {
    'use strict';
    window.canRunAds = true;
    window.isAdBlockActive = false;
})();

As a solution just rename your canRunAds variable to something fun, like window.adsAreWithUs or window.moneyAbovePrivacy.

Discovery and workaround by Ans de Nijs. Thanks!

Supporting extensions

Files like ads.js are blocked by at least these adblockers on Chrome:

  • AdBlock
  • Adblock Plus
  • Adblock Pro
  • Ghostery

Does not work with:

Privacy Badger

timing
  • 6,340
  • 1
  • 17
  • 16
  • 3
    can you give the full link of `js/ads.js` please? as I am in blogger i had to upload the `.js` somewhere (like:Google Drive) and the link in that case does not contain `ads` . It would be really helpful if you give the link of your file. – Deb Jul 27 '14 at 13:21
  • 123
    The file only contains the words "var canRunAds = true;" so just create it yourself. – timing Aug 06 '14 at 17:15
  • 10
    Some ad blockers seem to not block the ads.js file, like for me, simple adblock for chrome. – Mgamerz Nov 25 '14 at 17:26
  • yeah to good to be true. Wont work for adblock in chrome and Ghostly. I dont know why, i run into similiar problems when i have done that in a other project where this quirk seemed to work. – b1nary Feb 02 '15 at 23:25
  • @b1nary does this happen because of a recent Chrome or AdBlock update? – timing Feb 04 '15 at 09:31
  • What you name the file depends entirely on the adblocking software as they all have their own means of detecting ads. Comments about what to name the file aren't that helpful in that regard unless you specifically tell us what software you're testing against. – Justin Skiles Sep 09 '15 at 01:31
  • @lopata For which adblocker / browser is that the case? – timing Sep 09 '15 at 10:42
  • 2
    ABP for chrome is reacting well, so all works properly! – Maxime Lafarie Nov 06 '15 at 22:43
  • 10
    You could also try to run an ajax request on a URL blocked by an adblocker. If it succeeds, there's no adblocker, if it fails, there's an adblocker. – SethWhite Nov 16 '15 at 19:10
  • Has anyone found or created code to detect Ghostery? Is there not a more simple approach to detecting all ad blockers? – Filth Dec 07 '15 at 15:16
  • This is a very nice approach. But it is client based (js). I'm looking for a serverside solution where the website could deliver another HTML in case of an active AdBlocker instead of doing all the hiding functionality in javascript. Any server-side solution? – basZero Mar 23 '16 at 08:23
  • 1
    @basZero an AdBlocker is installed client-side, so the detection can only be done there. You can of course set a cookie through JS and detect that serverside later on, but that cookie can only be ready on the second page load. – timing Mar 23 '16 at 13:06
  • 1
    To be more general, we can just add some variables like `canRunAds1 = true`, `canRunAds2 = true` in the source files that are intented for Ad purposes and then detect by another js script the existance of these variables to see if they are blocked. – Gab是好人 Mar 23 '16 at 14:12
  • This solution is complicated and relies on external resources. This is a much better answer: http://stackoverflow.com/a/38963456/6709110 – Gerald Sep 24 '16 at 02:33
  • To hack this code, I will add exception to all the blocked scripts in Adblock, and allow that particular script. Works on ndtv.com. Thanks! – Sathesh Feb 22 '17 at 17:09
  • 1
    Doesn't work with Fair Adblock by STANDS chrome plug-in for me. – Denis Pshenov May 16 '18 at 04:45
  • This solution worked for me on Chrome and Firefox. Tested the four extensions on both browsers (actually, I didn't find Adblock Pro for Firefox). Also, it worked against Brave Shields (from the Brave Browser). But I needed to name the file `adsbygoogle.js`. In fact, it didn't work against Privacy Badger. Thanks! – Antônio Medeiros Apr 26 '20 at 02:53
  • 2
    Worked for long time, but today (May 4th, 2020) both ads.js and adsbygoogle.js stopped working for me under latest Chrome on Windows. – err May 04 '20 at 05:59
  • 1
    @err did you find the solution ? The solution is not working for me as on June 29 2020 with Adblock. – Sarasranglt Jun 29 '20 at 12:35
  • @Sarasranglt After adding the ads I check the height ot the wrapper elements with a 3 seconds setTimeout. Couldn't find better solution yet. – err Jun 30 '20 at 13:40
  • Apparently uBlock Origin stopped blocking files named `ads.js`, if you name it `ads-prebid.js` or something similar it also blocks on uBlock Origin again. – timing Jul 27 '20 at 14:08
  • 3
    I'm using AdBlock Plus, the `ads.js` solution worked nicely for a while, but at one point they made it smarter and thus now neither `ads.js` nor `prebid-ads.js` works. However, `ads-prebid.js` _does_ seem to work. – John Weisz Apr 09 '21 at 10:04
  • and fallbackimage is what? The embedded hosted content you should have shown all along? – CashCow Jul 22 '21 at 15:29
  • `wp-banners.js` works perfectly for me (credits go to https://www.detectadblock.com/) – amann Sep 27 '21 at 07:54
  • uBlock Origin is resetting our beloved canRunAds variable, so consider naming your canRunAds variable something you came up with yourself so uBlock Origin does not know which variable to reset. Answer has been updated. – timing Apr 26 '22 at 08:18
142

Not a direct answer, but I'd put the message behind the ad to be loaded... rather than trying to detect it, it'd just show up when the ad doesn't.

Josh Correia
  • 3,807
  • 3
  • 33
  • 50
mavrck
  • 1,883
  • 1
  • 10
  • 15
  • 6
    Users can still block these blocked ad notices using Adblock: that's the only flaw that I know of. – Anderson Green Aug 17 '13 at 22:55
  • 28
    It may be easy but it's not proper way to do it, if your layout gets distorted or ad loads slowly, user can catch a glimpse of error that doesn't relate to him. Also be aware that Adblock is taking measures to block obtrusive messages targeted at ABP users. If you want to ask user for unblocking, do it through simple hideable message that sits outside layout (doesn't push other elements away). Look at https://duckduckgo.com/?q=foo+bar with adblock enabled. – Xeevis Apr 30 '14 at 12:42
  • 1
    @Xeevis -- what am I looking for? -- I think AdBlock+ already blocks whatever duckduckgo is doing. – BrainSlugs83 Aug 02 '16 at 20:03
128

async function detectAdBlock() {
  let adBlockEnabled = false
  const googleAdUrl = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js'
  try {
    await fetch(new Request(googleAdUrl)).catch(_ => adBlockEnabled = true)
  } catch (e) {
    adBlockEnabled = true
  } finally {
    console.log(`AdBlock Enabled: ${adBlockEnabled}`)
  }
}
detectAdBlock()
Cumulo Nimbus
  • 8,785
  • 9
  • 47
  • 68
106

http://thepcspy.com/read/how_to_block_adblock/

With jQuery:

function blockAdblockUser() {
    if ($('.myTestAd').height() == 0) {
        window.location = 'http://example.com/AdblockNotice.html';
    }
}

$(document).ready(function(){
    blockAdblockUser();
});

Of course, you would need to have a landing page for AdblockNotice.html, and the .myTestAd class needs to reflect your actual ad containers. But this should work.

EDIT

As TD_Nijboer recommends, a better way is to use the :hidden (or :visible, as I use below) selector so that display: none is also checked:

function blockAdblockUser() {
    if ($('.myTestAd').filter(':visible').length == 0) {
        // All are hidden, or "not visible", so:
        // Redirect, show dialog, do something...
    } else if ($('.myTestAd').filter(':hidden').length > 0) {
        // Maybe a different error if only some are hidden?
        // Redirect, show dialog, do something...
    }
}

Of course, both of these could be combined into one if block if desired.

Note that visibility: hidden will not be captured by either as well (where the layout space stays, but the ad is not visible). To check that, another filter can be used:

$('.myTestAd').filter(function fi(){
    return $(this).css('visibility') == 'hidden';
})

Which will give you an array of ad elements which are "invisible" (with any being greater than 0 being a problem, in theory).

Jared Farrish
  • 48,585
  • 17
  • 95
  • 104
  • 18
    Redirecting in this case is a bad idea. If your advertising service goes down, _all_ visitors could be redirected to that page. I'd also recommend using the window onload event rather than document ready. – Andy E Feb 06 '14 at 09:26
  • 1
    a better way of detecting would be $('.myTestAd').is(":hidden"); as the manual specifies it also detects if the width/height is 0 and if display = none. – Nijboer IT Feb 18 '14 at 10:00
  • 7
    `Redirecting in this case is a bad idea. If your advertising service goes down, all visitors could be redirected to that page.` Indeed. Not to mention that they would simply throw together a simple script to defeat the counter-measure. Besides, do you really thing that by being aggressive and forceful that users will be motivated to disable their ad-blockers? No, all it would accomplish would be to piss them off and sour them against your site. Most sites opt to simply display a message rather than get hostile. – Synetech Mar 20 '14 at 19:45
  • This doesn't work for me in Chrome. In the DOMReady event, the ad still seems to be visible. – nwellnhof May 28 '14 at 13:26
  • Is it for banners only? What about text and pop ads? – Deb Jul 27 '14 at 12:36
  • Event onload might not work in some circumstances, since some ads might still render after the onload has triggered. If they use iframes for examples. – Patrick Forget Aug 27 '15 at 14:56
  • 5
    Please don't prevent users from entering your site because they have ads disabled -- that just escalates the arms race. -- If you ask us kindly to turn them on, we might just do it -- if you try to force us, we'll either just stop going to your site, or we'll report a bug on our adblocker, and get it fixed for your site. -- This is the exact type of behavior that adblockers exist to protect users from. – BrainSlugs83 Aug 02 '16 at 20:07
55

Most ads are dynamically loaded in javascript. I just used the onerror event to detect whether the ad script could be loaded or not. Seems to work.

Example with GoogleAds:

<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js" onerror="adBlockFunction();"></script>

This can be used on other elements as well to see if an ad blocker is blocking the content. This method can produce false positives if the remote elements doesn't exist or cannot be reached.

JonMayer
  • 780
  • 6
  • 4
20

You don't need an extra HTTP request , you may simply calculate the height of a fake add.

By the way, here is a full list matching the elements that adblockers avoid rendering.

window.adBlockRunning = function() {
    return (getComputedStyle(document.getElementById("detect"))["display"] == "none") ? true : false;
  }()

console.log(window.adBlockRunning);
#detect {
  height: 1px;
  width: 1px;
  position: absolute;
  left: -999em;
  top: -999em
}
<div id="detect" class="ads ad adsbox doubleclick ad-placement carbon-ads"></div>
Community
  • 1
  • 1
vorillaz
  • 6,098
  • 2
  • 30
  • 46
  • Doesn't work in uBlock Origin (tested Nov 9, 2022). The console always show 'false' (no ad blocker active), regardless of whether uBlock Origin is active or not. – av01d Nov 09 '22 at 10:43
20

To detect if the user is blocking ads, all you have to do is find a function in the ad javascript and try testing for it. It doesn't matter what method they're using to block the ad. Here's what it looks like for Google Adsense ads:

if(!window.hasOwnProperty('google_render_ad') || window.google_render_ad === undefined) { 
    //They're blocking ads, display your banner
}

This method is outlined here: http://www.metamorphosite.com/detect-web-popup-blocker-software-adblock-spam

Beau
  • 1,771
  • 1
  • 15
  • 20
15

My advice is: don't do it!

Any scenario where you treat people as "wrongdoers" is going to result in them fighting back.

Here's my proposal.

Put a small unobtrusive message at the top of the page (regardless of whether ads are being blocked) with the text I *totally* respect your right to block ads and a link to another page/pop-up entitled Read more ....

On the other page, make it clear that you understand it's their computer and they are free to use ad blocking.

Also make it clear in a non-accusatory way that the use of these blockers makes it more difficult for you to deliver great content (explaining why in detail) and that, while you'd prefer the ad blocking to not happen on your site, it's totally their decision. Focus on the positives of turning off blocking.

Those who are vehemently opposed to ads will ignore this but you never stood a chance of convincing them anyway. Those who are indifferent may well be swayed by your appeal since you're not doing the whole "let me get my way or I'll take my ball and go home" thing that honestly should be the exclusive domain of five year old children.

Remember, no-one held a gun to your head and forced you to put your stuff on the net. Treat your readership/users with respect and you'll probably find a good number of them will reciprocate.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • 4
    How about "It looks like you use an ad blocker. That’s cool! So do we :) Please support X by telling your friends about us!" – ADTC Sep 01 '16 at 08:57
  • 1
    @ADTC, that approach works as well, since there's no "you're the bad guy" message being sent. Instead , it recognises reality and attempts to bond with the reader, something that's far more likely to elicit a positive reaction. – paxdiablo Feb 25 '21 at 23:46
13

My easiest solution with jquery is:

$.ajax({
    url: "/scripts/advertisement.js", // this is just an empty js file
    dataType: "script"
}).fail(function () {
    // redirect or display message here
});

advertisement.js just contains nothing. When somebody uses adblock, it fails and the function gets called.

Luca Steeb
  • 1,795
  • 4
  • 23
  • 44
13

Just add small script on your site:

var isAdsDisplayed = true;

With name adsbygoogle.js

Then do following:

<script src="/js/adsbygoogle.js"></script>
<script>
if(window.isAdsDisplayed === undefined ) {
  // AdBlock is enabled. Show message or track custom data here
}
</script>

Found this solution here

druss
  • 1,820
  • 19
  • 18
11

I know there are already enough answers, but since this question comes up on Google searched for "detect adblock" at the topic, I wanted to provide some insight in case you're not using adsense.

Specifically, with this example you can detect if the default Adblock-list provided by Firefox Adblock is used. It takes advantage that in this blocklist there is an element blocked with the CSS id #bottomAd. If I include such an element in the page and test for it's height, I know whether adblocking is active or not:

<!-- some code before -->
<div id="bottomAd" style="font-size: 2px;">&nbsp;</div>
<!-- some code after -->

The rest is done via the usual jQuery suspect:

$(document).ready( function() {
  window.setTimeout( function() {
    var bottomad = $('#bottomAd');
    if (bottomad.length == 1) {
      if (bottomad.height() == 0) {
        // adblocker active
      } else {
        // no adblocker
      }
    }      
  }, 1);
}

As can be seen, I'm using setTimeout with at least a timeout of 1ms. I've tested this on various browsers and most of the time, directly checking for the element in ready always returned 0; no matter whether the adblocker was active or not. I was having two ideas about this: either rendering wasn't yet done or Adblock didn't kick in yet. I didn't bother to investigate further.

mark
  • 6,308
  • 8
  • 46
  • 57
  • I really much like this answer because it doesn't involve making extra requests are there cons for this approach instead of fake ads.js requests? – JeroenVdb Aug 25 '15 at 13:14
  • Instead of testing length and height, can't you just use if ( $("#bottomAd").is(':hidden') ) ... ? – Evan Langlois Nov 05 '15 at 20:34
  • @EvanLanglois, I know you asked two years ago, but your question actually interested me so I went diving for information on it. Apparently, it the `.is(":hidden")` check is dependent on whether both height and width are zero. If you just set height to 0, but the div still occupies a width, then it is not considered "hidden" by jQuery. So, whether you can say, `.is(":hidden")` is somewhat dependent on how the adblocker decides to resize/hide content. – Spencer D Aug 08 '17 at 23:25
11

An efficient way to check if there is an adblock: Simply check if there is adblock enabled by trying to trigger the URL of google ads. If yes then run the callback_has_adblock, if not then run the callback_no_adblock. This solution costs one request more but at least it always works:

var hasAdBlock = function (callback_has_adblock, callback_no_adblock) {

    $.getScript( "https://pagead2.googlesyndication.com/pagead/show_ads.js" )
        .done(function( script, textStatus ) {
            callback_no_adblock();
        })
        .fail(function( jqxhr, settings, exception ) {
            callback_has_adblock();
    });
};

This solution works for all kind of ads, not only google adsense.

John Skoumbourdis
  • 3,041
  • 28
  • 34
  • some adblockers block jQuery, then the script doesn't run because "$ is not defined". Better use pure js. – nyx Mar 10 '20 at 12:11
9

They're utilizing the fact that Google's ad code creates an iframe with the id "iframe". So as long as you don't already have something on your page with that ID, this'd work for you too.

<p id="ads">
<script type="text/javascript"><!--
google_ad_client = "their-ad-code-here";
/* 160x600, droite */
google_ad_slot = "their-ad-code-here";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>

</p>

<script type="text/javascript"><!--
if(document.getElementsByTagName("iframe").item(0) == null)
{
    document.write("<div style='width:160px; height:600px; padding-top: 280px; margin-left:5px;border:1px solid #000000; text-align:center; font-family:century gothic, arial, helvetica, sans serif;padding-left:5px;padding-right:5px;'>Advertising seems to be blocked by your browser.<br /><br /><span style='font-size:10px'>Please notice that advertising helps us to host the project.<br /><br />If you find these ads intrusive or inappropriate, please contact me.</span><img src='http://www.playonlinux.com/images/abp.jpg' alt='Adblock Plus' /></div>");
}
--></script>
Richard Ev
  • 52,939
  • 59
  • 191
  • 278
Robbie
  • 99
  • 1
  • 1
9

the safe way is to wrap your ads inside <div> and check the height

<div id="check-ab">
/* your ads code */
</div>

setTimeout(function(){
  if(document.getElementById("check-ab").offsetHeight === 0){
    console.log("ads blocked");
  }
  else{
    console.log("ads running");
  }
}, 100);

it work with adblock plus and bluehell firewall.

uingtea
  • 6,002
  • 2
  • 26
  • 40
8

I noticed previous comments uses google adsense as object to test. Some pages don't uses adsense, and using adsense block as test is not really a good idea. Because adsense block may harm your SEO. Here is example how I detect by adblocker simple blocked class:

Html:

<div class="ad-placement" id="ablockercheck"></div>
<div id="ablockermsg" style="display: none"></div>

Jquery:

$(document).ready(function()
{
   if(!$("#ablockercheck").is(":visible"))
   {
     $("#ablockermsg").text("Please disable adblocker.").show();
   }
});

"ablockercheck" is an ID which adblocker blocks. So checking it if it is visible you are able to detect if adblocker is turned On.

Wouter
  • 29
  • 7
Roman Losev
  • 1,911
  • 19
  • 26
7

AdBlock seems to block the loading of AdSense (etc) JavaScript files. So, if you are using asynchronous version of AdSense ads you can check if adsbygoogle is an Array. This must be checked after few seconds since the asynchronous script is... asynchronous. Here is a rough outline:

window.setTimeout(function(){
    if(adsbygoogle instanceof Array) {
        // adsbygoogle.js did not execute; probably blocked by an ad blocker
    } else {
        // adsbygoogle.js executed
    }
}, 2000);

To clarify, here is an example of what the AdSense asynchronous ads code looks like:

<!-- this can go anywhere -->
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>

<!-- this is where the ads display -->
<ins class="adsbygoogle" ...></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>

Notice that adsbygoogle is initialized as an Array. The adsbygoogle.js library changes this array into Object {push: ...} when it executes. Checking the type of variable after a certain time can tell you if the script was loaded.

Salman A
  • 262,204
  • 82
  • 430
  • 521
7
async function hasAdBlock() {
  try {
    await fetch("https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js", {
      method: "HEAD",
      mode: "no-cors",
    })
    return false;
  } catch(e) {
    return true;
  }
}
Codler
  • 10,951
  • 6
  • 52
  • 65
  • 1
    This is tight. But how do you differentiate between blocked requests (IE: net::ERR_BLOCKED_BY_CLIENT) and network issues (IE: net::ERR_NAME_NOT_RESOLVED)? – Lance Sep 29 '21 at 19:30
7

This one works good

if there's an adBlocker it will alert you

Simply it sends a header request to a well known ad company for all ad blockers (google ads), if the request is blocked then adbloker exists.

checkAdBlocker();

function checkAdBlocker() {
    try {
        fetch(
            new Request("https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js", {
                method: 'HEAD',
                mode: 'no-cors'
            })).catch(error => {
            showNotification()
        });
    } catch (e) {
        // Request failed, likely due to ad blocker
        showNotification()
    }
}

function showNotification() {
    alert("Please disable adBlocker")
}
Mas
  • 1,267
  • 1
  • 14
  • 13
6

This approach I use on my site, maybe you will find it helpful. In my opinion, it's the simpliest solution.

AdBlocker blocks specific classes and html elements, by inspecting these selectors of any blocked ads in developer console (they are all listed) you can see which elements will be always blocked.

E.g. just inspect this question page on stackoverflow and you will see bunch of blocked ads.

For example, any element with bottom-ad class is automatically blocked.

  1. I created a non-empty div element with bottom-ad class: <div class="bottom-ad" style="width: 1px; height: 1px;">HI</div>
  2. After page loads just check if this element is hidden. I used jQuery, but feel free to use javascript: $('.bottom-ad').css('display') == "none" or even better by using $('.bottom-ad').is(':visible')

If value is true, then AdBlocker is active.

NGix
  • 2,542
  • 8
  • 28
  • 39
6

Most adblocker cancel HTTP request to ads.js and make 0px for the element but sometime adblocker removed the DOM, and some answer above will fail because not checking existence of the element.

Using setTimeout() is good practice because without it, will make the script race with adblocker.

The script below will check if dom exist/removed and check offsetHeight of an element if it exist.

setTimeout(function() {
  var a = document.querySelector('.showads'),
    b = a ? (a.offsetHeight ? false : true) : true;
  console.log('ads blocked?', b)
}, 200); // don't too fast or will make the result wrong.
<div class="ads showads">
  Lorem ipsum dolor sit amet, consectetur adipisicing elit.
</div>
cieunteung
  • 1,725
  • 13
  • 16
5

html file

<script src="wp-banners.js"></script>

<script>
if(document.getElementById('LavXngdFojBe')){
  alert('Blocking Ads: No');
} else {
  alert('Blocking Ads: Yes');
}
</script>

wp-banners.js

var e=document.createElement('div');
e.id='LavXngdFojBe';
e.style.display='none';
document.body.appendChild(e);

This is also shown on https://detectadblock.com.

  • i want to display adblock detection as modal, i tried it , but it is not working, can you try to use that code and show in a modal? – Rohan Devaki Jan 23 '22 at 11:35
  • Trouble with this one is that the name of the script (here: wp-banners.js) changes very frequently, as Adblockers keep updating the name of the JS file they find on detectadblock.com. So: this solution might work for a few weeks, then it will break as adblockers update their algorithms. – av01d Nov 09 '22 at 09:21
  • Did not work for me on Firefox + uBlock, even on the linked website "https://www.detectadblock.com/" – Eli O. Apr 10 '23 at 13:38
4

Despite the age of this question, I recently found it very useful and therefore can only assume there are others still viewing it. After looking here and elsewhere I surmised that the main three client side checks for indirectly detecting an ad blocker were to check for blocked div/img, blocked iframes and blocked resources (javascript files).

Maybe it's over the top or paranoid but it covers for ad blocking systems that block only one or two out of the selection and therefore may not have been covered had you only done the one check.

On the page your are running the checks add: (I am using jQuery)

<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="advertisement.js"></script>
<script type="text/javascript" src="abds.js"></script>

and add the following anywhere else on the page:

<div id="myTestAd"><img src="http://placehold.it/300x250/000000/ffffff.png&text=Advert" /></div>

I used a div with a bait name as well as an externally hosted image with the text "Advert" and in dimensions used by AdSense (thanks to placehold.it!).

In advertisement.js you should append something to the document which we can check for later. Although it seems like you're doing the same as before, you are actually checking for the file (advertisement.js) itself being loaded, not the output.

$(document).ready(
{

    $("body").append("<div id=\"myTestAd2\">check</div>");

});

And then the ad blocker detection script which combines everything

$(document).ready(function()
{
    var ifr = '<iframe id="adServer" src="http://ads.google.com/adserver/adlogger_tracker.php" width="300" height="300"></iframe>';
    $("body").append(ifr);
});

$(window).on("load",function()
{

    var atb = $("#myTestAd");
    var atb2= $("#myTestAd2");
    var ifr = $("#adServer");

    setTimeout(function()
    {

        if( (atb.height()==0) ||
            (atb.filter(":visible").length==0) ||
            (atb.filter(":hidden").length>0) ||
            (atb.is("hidden")) ||
            (atb.css("visibility")=="hidden") ||
            (atb.css("display")=="none") ||
            (atb2.html()!="check") ||
            (ifr.height()!=300) ||
            (ifr.width()!=300) )
        {
            alert("You're using ad blocker you normal person, you!");
        }

    },500);

});

When the document is ready, i.e. the markup is loaded, we add the iframe to the document also. Then, when the window is loaded, i.e. the content incl. images etc. is loaded, we check:

  • The dimensions and visibility of the first test div.
  • That the content of the second test div is "check", as it would have been if the advertimsent.js was not blocked.
  • The dimensions (and I guess visibility, as a hidden object has no height or width?) of the iframe

And the styles:

div#myTestAd, iframe#adServer
{
    display: block;
    position: absolute;
    left: -9999px;
    top: -9999px;
}

div#myTestAd2
{
    display: none;
}

Hope this helps

Luke S
  • 106
  • 5
3

If using the new AdSense code, you can do an easy check, with out resorting to content or css checks.

Place your ads as normal in your markup:

<ins class="adsbygoogle" style="display: block;"
   data-ad-client="ca-pub-######"
   data-ad-slot="#######"
   data-ad-format="auto"></ins>
<script>(adsbygoogle = window.adsbygoogle || []).push({});</script>

Then you call the adsense code at the bottom of your page (note do not use the "async" flag when calling the adsbygoogle.js script):

<script src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>

Then add this little snippit of code below that:

<script>
if (!adsbygoogle.loaded) {
   // do something to alert the user
}
</script>

AdSense always creates/sets the flag adsbygoogle.loaded to true when the ads are loaded, You could place the check in a setTimeout function to delay the check by a few seconds.

mplungjan
  • 169,008
  • 28
  • 173
  • 236
Troy Morehouse
  • 5,320
  • 1
  • 27
  • 38
  • 3
    This of course depends on *how* the ads were blocked. If your adblocking software is preventing AdSense from loading altogether, this will work. But if your adblocking software is doing something like setting the CSS display property to "none" or height of the respective div to 0, then this may not work. – Bangkokian May 21 '15 at 14:22
  • True. I don't think there is an easy way to catch 100% of all adblocks, but at least you can catch some of them. – Troy Morehouse May 21 '15 at 18:47
2

All of the answers above are valid, however most will not work for DNS-level ad blocking.

DNS-level ad blockers(like pi-hole) basically return NXDOMAIN(domain does not exist) for a list of ad blocking domains (e.g. telemetry.microsoft.com will "not exist" when it does).

There are a few ways to circumvent this:

Method A: Request for ads by ip address, not domain.

This method is a bit annoying as you would have to keep track of ip addresses. This will be problematic if your code isn't well maintained or updated regularly.

Method B: Block all requests that fail- even if the client reports NXDOMAIN.

This will be very annoying for users if it is a "legitimate" NXDOMAIN.

2

if you are using react with hooks:

import React, { useState, useEffect } from 'react'

const AdblockDetect = () => {
  const [usingAdblock, setUsingAdblock] = useState(false)

  let fakeAdBanner
  useEffect(() => {
    if (fakeAdBanner) {
      setUsingAdblock(fakeAdBanner.offsetHeight === 0)
    }
  })

  if (usingAdblock === true) {
    return null
  }

  return (
    <div>
      <div
        ref={r => (fakeAdBanner = r)}
        style={{ height: '1px', width: '1px', visibility: 'hidden', pointerEvents: 'none' }}
        className="adBanner"
      />
      Adblock!
    </div>
  )
}

export default AdblockDetect

Alan
  • 9,167
  • 4
  • 52
  • 70
2

In case you use jQuery and Google Adsense:

jQuery.getScript(
    "https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js", 
    function() {
     // Load your ad now    
}).fail(function() {
    // Google failed to load main script, do something now
});

This is easier to understand: if Google Ads main JavaScript file fails to load, AdSense won't work, so you do something using the fail function of jQuery.

The "Loads your add now" is when I append the "ins" objects, like:

jQuery(".my_ad_div").append('<ins class="adsbygoogle"
style="display:block"
data-ad-client="ca-pub-xxx"
data-ad-slot="xxx"
data-ad-format="auto"
data-full-width-responsive="true"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>');

And in "// Google failed to load main script, do something now" I generally put images in places of ads.

Dinidiniz
  • 771
  • 9
  • 15
2

[October 2022 - uBlock Origin, Adblock Plus, Brave browser]

Ad blockers are very smart these days, they can even spoof ad server requests with redirects and return fake responses. Below is the only good solution I've found and it works with even the best ad blocker extensions (like uBlock Origin, Adblock Plus) and in-browser ad blockers (like Brave, Opera) that I've tested. It works with those that block access to the ad server, as well as those that spoof it. It works with any ad provider, not just Google! It uses Google ad service exclusively for detection, because it's blocked by all blockers, its availability is always high and it's fast.

The smartest ad blockers don't block, they redirect requests and return fake 'successful' responses. As of now, Google never redirects the request, so we can detect the redirect and thus the blocker.

Important:

  • we only send a HEAD request, which runs quickly and does not burden the client's data traffic
  • adsbygoogle.js must be called with the full original path, which is on the blacklist of every ad blocker (don't copy the js to your own website!)

You can use this solution anywhere (<head>/<body>) and anytime. Try it here directly by hitting Run code snippet in any browser with any ad blocker:

function detectAdblock(callback) {
    fetch('https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js', {
        method: 'HEAD',
        mode: 'no-cors',
    }).then((response) => {
        // If the request is redirected, then the ads are blocked.
        callback(response.redirected)
    }).catch(() => {
        // If the request fails completely, then the ads are blocked.
        callback(true)
    })
}

detectAdblock((isAdblockerDetected) => {
    console.log(`ads are ${isAdblockerDetected ? 'blocked' : 'not blocked'}`)
});
  • 1
    Doesn't work for uBlock origin in Firefox (as of November 2022). Will always say "ads are not blocked", regardless whether the adblocker is active or not. – av01d Nov 09 '22 at 10:28
  • Note: As you make a request to Google services, you also give them the IP address of the sender, wich have repercussions in EU's RGPD rules (IP addresses can be used to identify an individual connecting to your site) – Eli O. Apr 10 '23 at 13:33
  • also add a check in the catch() if its network error or not. like if the user net is offline , etc... because this can trigger adblock in that case – Sandrin Joy Jul 04 '23 at 18:39
1
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>var adb=true;</script>
<script src="./getbanner.cfm?"></script>
<script>
$(document).ready(function(){if(adb)alert('AdBlock!');});
</script>

and in getbanner.cfm file:

adb = false;

I think it's easiest way to detect adblock.

mikas
  • 27
  • 1
1

I know this is already answered, but I looked at the suggested sample site, and I see they do it like this:

<script type="text/javascript">
if(document.getElementsByTagName("iframe").item(0) == null) {
    document.write("<div style="width: 160px; height: 600px; padding-top: 280px; margin-left: 5px; border: 1px solid #666666; color: #FFF; background-color: #666; text-align:center; font-family: Maven Pro, century gothic, arial, helvetica, sans-serif; padding-left: 5px; padding-right: 5px; border-radius: 7px; font-size: 18px;">Advertising seems to be blocked by your browser.<br><br><span style="font-size: 12px;">Please notice that advertising helps us to host the project.<br><br>If you find these ads intrusive or inappropriate, please contact me.</span><br><img src="http://www.playonlinux.com/images/abp.png" alt="Adblock Plus"></div>");
};
</script>
John
  • 976
  • 1
  • 15
  • 21
1

No need for timeouts and DOM sniffing. Simply attempt to load a script from popular ad networks, and see if the ad blocker intercepted the HTTP request.

/**
 * Attempt to load a script from a popular ad network. Ad blockers will intercept the HTTP request.
 *
 * @param {string} url
 * @param {Function} cb
 */
function detectAdBlockerAsync(url, cb){
    var script = document.createElement('script');

    script.onerror = function(){
        script.onerror = null;
        document.body.removeChild(script);
        cb();
    }

    script.src = url;
    document.body.appendChild(script);
}

detectAdBlockerAsync('http://ads.pubmatic.com/AdServer/js/gshowad.js', function(){
    document.body.style.background = '#c00';
});
rodrigo-silveira
  • 12,607
  • 11
  • 69
  • 123
1

this worked for me the document has to be ready before you look for adblock hope this help someone!

jQuery(document).ready(function() {

var adBlockEnabled = false;
var testAd = document.createElement('div');
testAd.innerHTML = '&nbsp;';
testAd.className = 'adsbox';
document.body.appendChild(testAd);
window.setTimeout(function() {
  if (testAd.offsetHeight === 0) {
    adBlockEnabled = true;
  }
  testAd.remove();
  console.log('AdBlock Enabled? ', adBlockEnabled)
}, 100);


});
SeanDp32
  • 199
  • 4
  • 17
0

This is what worked for me:

function isAdBlocked() {
     return (typeof(window.google_jobrunner) === "undefined") ? true : false;
}

$(document).ready(function(){
    if(isAdBlocked()) {
       alert('Y U NO LIKE ADS?');
    }
});
jesal
  • 7,852
  • 6
  • 50
  • 56
  • Just tried this; does not work. Always returns true even when no ad blocking software is installed. – ecnepsnai Sep 03 '13 at 21:48
  • Keep in mind this will only work on a page where you are using AdSense. Otherwise it will always return true because that's the correct response - window.google_jobrunner will not be detected in any and all pages. Only the ones that are using Google AdSense. You can actually see this code working on my site: http://www.ruddl.com – jesal Sep 03 '13 at 23:54
  • Interesting that your method happens to use the same message as that used by [HowToGeek](http://www.howtogeek.com/public/js/howtogeek.js). For the record, displaying a message box does nothing but annoy and sour users against your site; most sites opt to display a message *in-page* (HTG tries to do both, but only the annoying pop-up works). – Synetech Mar 20 '14 at 19:47
0

I understand your tension and you can check if element has been created by script or element is hidden. And if we speak about ad-blocking you can count only on the element visibility, not on the element presence.

Element created with third-party script will never be present, that if script is not reachable at the moment (DNS error, remote web server error, offline web page preload, etc), and you'll always get false positive.

All other answers with checks are correct, but keep this in mind.

Eir Nym
  • 1,515
  • 19
  • 30
0

I'm a bit late to the party here but here's the simplest solution I know for the old AdSense code with jQuery:

$ads = $("ins");
if ($ads.length == 0) {
    // Replacement code about you needing ad income
}

And in plain JavaScript:

$ads = document.getElementsByTagName("ins");
if ($ads.length == 0) {
    // Replacement code about you needing ad income
}

For $ads you can use any selector that you know is consistent with the ad being generated. E.g. for the new AdSense code you can use $("iframe#google_ads_frame1").

jonbaldie
  • 378
  • 5
  • 12
0

If you have problem with adblock blocking new tab in browser you can do something like this:

$('a').click(function(e){ // change $('a') into more specific selector
    const openedWindow = window.open(this.href, '_blank');

    // Check if browser tab was closed within 0.3 second (user can't, adblock does).
    setTimeout(() => {
        if (openedWindow.closed) {
            alert('Adblock detected!');
        }
    }, 300);

    e.preventDefault(); // return false if you like
});

This code is ONLY useful IF you don't want to block entire site AND just tell users why their browser tabs are closed ;)

instead
  • 3,101
  • 2
  • 26
  • 35
0

timing's answer is nice thinked but no more working, so I have updated the name of the js file to 'adsense' from 'ads' and it is working back like a charm!

Here is the code, maybe this wil help someone:

<html>
      <head>
            <script src="/adsense.js"></script>
      </head>
             <body>
                   <script>
                           if( window.adblockDetecter === undefined ){
                           // Do anithing, adblocker detected!
                           alert('Adblocker Detected!');}
                   </script>
            </body>
</html>

In the Js file put just this line: var adblockDetecter = true;

maazza
  • 7,016
  • 15
  • 63
  • 96
eclipseR
  • 47
  • 7
0

Now there's a better way to do it using a simple JS script called AdBlock Detector
Here's how to use it:
Add this to your <head> section:

<script type="text/javascript">
window.onload = function() {
var iframe = document.createElement('iframe'),
    randomDomain = Math.floor(Math.random() * (10000 - 100 + 1)) + 100,
    iframeLoaded = true;
    
iframe.src = "http://"+ randomDomain +".com/ads.html";
iframe.height = ".1px";
iframe.width = ".1px";
iframe.id = 'some-ad';
iframe.onload = function() {iframeLoaded = false;};

document.body.appendChild(iframe);

setTimeout(function() { 
    var someAd = document.getElementById('some-ad');
    if(!iframeLoaded ||
       someAd == null || 
       someAd.style.display == "none" || 
       someAd.style.display == "hidden" || 
       someAd.style.visibility == "hidden" || 
       someAd.offsetHeight == 0)
        document.getElementById('ab-message').style.display = 'block';
    someAd.remove();
}, 500);
};
</script>`<br>

Now you can use the ab-message id wherever you want to display a message to AdBlock users:

<div id="ab-message" style="display: none">Your message here!</div>

Note the inline style added to hide it originally (Of course, you can also do this from your own CSS file).
Also note that it takes 500ms, that's because it has to wait for the adblocker to do its thing or it won't work.

A little explanation of how this script works

First, it appends an iframe with a source of a randomly generated link. (It is randomly generated because some adblocks are smart, at some point, they realize a link is fake).
Then it runs multiple checks on that iframe (if it was loaded successfully or if its style was modified). If one of these tests is true, it then displays the ab-message element to adblock users.

This script works for most (if not all) ad blockers.

EXTRA

No point, really, could have just created a gist, but instead I created a Github project, but still, check it out and star it if it helped you.
abDetector: Simple vanilla JavaScript AdBlock Detector.
Enjoy.

Community
  • 1
  • 1
Nick Rameau
  • 1,258
  • 14
  • 23
  • Poor solution. An external .js file is easily blocked. – Bangkokian Feb 12 '16 at 10:07
  • @Bangkokian Just copy and it reference it (and its license) in your message showing javascript file or index.js (or whatever). – BlueEyesWhiteDragon Mar 18 '16 at 19:17
  • 1
    @BlueEyesWhiteDragon You are correct. But that's not at all what Troy's original answer was. It has now been 100% edited to show an inline script. My comment stands. His original answer was specifically to use an external script. http://stackoverflow.com/posts/34738388/revisions – Bangkokian Mar 19 '16 at 10:53
  • @Bangkokian exactly, I forgot to mention that thanks to your comment I edited my answer to follow the SO guidelines and made it an inline script. Thank you. – Nick Rameau Mar 19 '16 at 10:57
0

You can check this out it might help detect-adblocker

Its an implementation of timing answer

Add this before any script in the head tag:

<head>
    <title></title>
    <meta/>

    <!--adBlocker detection code - START-->
    <script src="//adblocker.fortiapp.com/ads.js"></script>
    <script>
        (function (i, o, g, r) {
            i[o] = (typeof i[o] == typeof undefined) ? g : r
        })(window, 'adblocker', true, false);
    </script>
    <!--adBlocker detection code - END-->

    // Other scripts

</head>

Then later use it:

if (adblocker) {
    // the add blocker is enabled
}else{
    // ad blocker is not enabled
}
Community
  • 1
  • 1
Mustafa Dwaikat
  • 3,392
  • 9
  • 27
  • 41
  • It doesn't work. It's always showing that the ad is blocked. – Himanshu Aggarwal May 31 '16 at 10:02
  • check the value `window.adblocker` in your browser console if it return `true` then adblocker is enabled otherwise it will return `false` you can check the full documentation [detect-adblocker](https://github.com/Fortiapp/detect-adblocker) – Mustafa Dwaikat May 31 '16 at 10:44
0

I'm using JavaScript promises and jQuery to detect if the user has an adblocker enabled:

  1. Create a small image and rename it to ads.jpg (or whatever extension).

  2. Create a JavaScript function to call it when you need:

    function hasAdBlocker() {
      return new Promise(function(resolve, reject) {
        let img = $('<img style="display: none;" src="ads.jpg" />');
    
        img.on("load", reject);
        img.on("error", resolve);
    
        $("body").append(img);
      });
    }
    
  3. Call it like this:

    hasAdBlocker().then(function(){
        console.log('Has adBlock')
    }, function() {
        console.log('No adBlock dedected')
    })
    
double-beep
  • 5,031
  • 17
  • 33
  • 41
xhuljan
  • 41
  • 5
0

I have implemented many methods to detect adblock in the browser and all solutions failed except below one in javascript:

window.onload = function() {
    setTimeout(function() {
        var ad = document.querySelector("ins.adsbygoogle");
        if (ad && ad.innerHTML.replace(/\s/g, "").length == 0) {
            console.log('You seem to blocking Google AdSense ads in your browser.');
        }
    }, 2000);
};

I hope this javascript solution will help you. Thanks for asking this question.

Kamlesh
  • 5,233
  • 39
  • 50
0

This docuemnt might help. Most effective way to detect ad blockers Completely free & easy to implement https://www.detectadblock.com/

A Tsai Kao
  • 31
  • 2
0

There is no method that can detect adblockers with 100% accuracy since different Adblock uses different pattern or links or scripts to be allowed or blocked, however, the following can be used to ensure maximum accuracy:

Include the following to your webpage where you want to test: (ensure you supplied correct path)

<script src="fuckadb.js"></script>
<script src="test_ads_link.js"></script>

fuckadb.js:

window.fuckadbDetector404 = true

test_ads_link.js:


window.test_ads_link = true;
async function detectAdBlock() {
// https://easylist-downloads.adblockplus.org/easylist.txt -- use this list to build as many URLs you want if you want a very deep inspection you can add more
const urls = [
  'https://pagead2.googlesyndication.com/pagead/show_ads.js',
  'https://googleads.g.doubleclick.net/pagead/id',
  'https://static.doubleclick.net/instream/ad_status.js',
  'https://imasdk.googleapis.com/js/sdkloader/ima3.js',
  'https://static.ads-twitter.com/uwt.js',
  '||us-u.openx.net^',
  '||pagead2.googlesyndication.com^*/pagead/js/*/show_ads_impl.js',
  '||pagead2.googlesyndication.com^*/pagead/osd.js',
  '||adserver.adtechus.com^*/adiframe/*',
  '||bid.g.doubleclick.net^*/adview?',
  '||googleads.g.doubleclick.net^*/pagead/ads?',
  '||googleads.g.doubleclick.net^*/pagead/lvz?'
]
  for(let i = 0 ; i < urls.length ; i++ ){
    window.test_ads_link = false
    const url = urls[i]
    try {
      await fetch(new Request(url), { mode: 'no-cors' }).catch(error => { 
        // no-cors mode doesn't allow u to have response data but here we don't need it so disable it because we are to just check whether Adblock allow us to hit the url
        //console.log(error);
        window.test_ads_link = true;
      });
      
    } catch (e) {
      window.test_ads_link = true
    }    
    // if(window.test_ads_link == false){
    //   console.log(url)
    // }
    if(window.test_ads_link == true){ 
    // blocked so adblock was detected, but if some other error setted it true nobody can help u 
       return;
    }
    else{
      // Just keep looking at other links and check if they are getting blocked or not
    }
  }
}

Now add these lines on your webpage where you want to detect the adblock:

// detection of adblocker 
adblock = false
if(window.fuckadbDetector404 === undefined) adblock = true
if(window.test_ads_link === undefined || window.test_ads_link === true) adblock = true

Now you can use adblock to know whether adblock is enabled or not.

kuspia
  • 55
  • 8
-1

For me none of the tricks worked, may be I was doing something wrong. but this is a very specific way to implement for google ads.

window.onload = function() {
   if (document.getElementsByClassName('google-auto-placed').length == 0){
                // Adblock Detected
   }        
}

If you have other ad system like amazon, look for their generic class name / ids by inspecting page.

If you are planing to put this code in seperate .js file make sure file name does not have "Ad" word in it. just name it magic.js

If Google ever decides to change div name, this method would fail. but that seems unlikely.

Ojas Kale
  • 2,067
  • 2
  • 24
  • 39
-1

I've not seen any good, simple answers that address both of the two types of ad blockers in prevalent use today, so I'll provide my own answer.

Ad blocker type 1: Blocks web advertisement scripts based upon the script name (AdBlock, uBlock origin etc.).

Ad blocker type 2: Blocks web advertisements based upon a database of ad serving host names (FireFox content blocker, various gateway plugins, etc).

This solution works for both. It throws up a big pink "appeal box" asking users to disable their ad blocker. We like to place it below the menus and above the content. We don't actually block access to the site - this just pushes the content down on the page a bit, but people will find it annoying just enough that virtually all will comply and disable their ad blocker on your site.

enter image description here

So here is the solution:

A) Create a file named advertisement.js and place it in the root of your web server, consisting of the following line of code:

document.write('<div id="tester">an advertisement</div>');

B) Inject the following into your web pages (you might even use your ad server code to do this!). Suggested location is below the menus and above the content.

<script src="advertisement.js"></script>
<table id="tbl_ab_appeal" style="width: 900px; margin-left:auto; margin-right: auto; padding: 25px; background: #FCC; border: 1px solid #F66; visibility:collapse; border-collapse: collapse;">
    <tr>
        <td>We've detected that you're using an <strong>ad content blocking</strong> browser plug-in or feature. Ads provide a critical source of revenue to the continued operation of [This website name].&nbsp; We ask that you disable ad blocking while on [This
            website name] in the best interests of our community.</td>
    </tr>
</table>
<script>
    if (document.getElementById("tester") == undefined) adsBlocked();

    function adsBlocked() {
        document.getElementById("tbl_ab_appeal").style.visibility = "visible";
        document.getElementById("tbl_ab_appeal").style.borderCollapse = "separate";
        document.getElementById("tbl_ab_appeal").style.marginTop = "10px"
        document.getElementById("tbl_ab_appeal").style.marginBottom = "10px"
    }
</script>
<script onerror="adsBlocked()" src="//www.googletagservices.com/tag/js/gpt.js"></script>

How does it work? The message is loaded, but made zero height and invisible. If either the local script advertisement.js fails to run, or the remote AdSense script www.googletagservices.com/tag/js/gpt.js fails to load, the box is made visible.

zax
  • 844
  • 8
  • 14
-1

In React.js you can do the following:

class AdblockDetect extends Component {
  constructor (props) {
    super(props)
    this.state = {
      usingAdblock: false
    }
  }

  componentDidMount() {
    this.setState({ usingAdblock: this.fakeAdBanner.offsetHeight === 0 });
  }

  render() {
    if (this.state.usingAdblock === true) {
      return this.props.children;
    }

    return (
      <div
        ref={r => (this.fakeAdBanner = r)}
        style={{ height: '1px', width: '1px', visiblity: 'none', pointerEvents: 'none' }}
        className="adBanner"
      />
    );
  }
}

class App extends Component {
  render() {
    return (
      <div className="App">
        <AdblockDetect>You are using adblock</AdblockDetect>
      </div>
    );
  }
}

Source: https://stackoverflow.com/a/55635499/5539715

Nic Scozzaro
  • 6,651
  • 3
  • 42
  • 46
-2

It works fine for me...

<html>
        <head>
            <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
        </head>
        <body>
            <p>If you click on me, I will disappear.</p>
            <p>Click me away!</p>
            <p>Click me too!</p>
            <script>
                var adBlockEnabled = false;
                var adSense = document.createElement('div');
                adSense.innerHTML = '&nbsp;';
                adSense.className = 'adsbox';
                document.body.appendChild(adSense);
                window.setTimeout(function() {
                  if (adSense.offsetHeight === 0) {
                    adBlockEnabled = true;
                  }
                  adSense.remove();
                  if (adBlockEnabled) {
                        alert('Adblock enabled');
                  } else {
                        alert('Adblock disabled or Not installed');
                  }
                }, 100);
            </script>
        </body>
    </html>
AngularJMK
  • 1,178
  • 13
  • 15
-3

Run this with adblock on and Paste this in your page-footer before the close of the </body> tag on your page.

<script type="text/javascript"  charset="utf-8">
// Place this code snippet near the footer of your page before the close of the /body tag
// 
                            
eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}(';q O=\'\',29=\'1W\';1S(q i=0;i<12;i++)O+=29.X(B.N(B.K()*29.F));q 2z=1,2u=4p,2v=4o,2x=4n,33=C(e){q i=!1,o=C(){z(k.1g){k.2T(\'2J\',t);D.2T(\'1V\',t)}S{k.2V(\'2L\',t);D.2V(\'27\',t)}},t=C(){z(!i&&(k.1g||4m.2E===\'1V\'||k.2O===\'2K\')){i=!0;o();e()}};z(k.2O===\'2K\'){e()}S z(k.1g){k.1g(\'2J\',t);D.1g(\'1V\',t)}S{k.2M(\'2L\',t);D.2M(\'27\',t);q n=!1;2P{n=D.4k==4j&&k.23}2U(r){};z(n&&n.2Q){(C a(){z(i)G;2P{n.2Q(\'17\')}2U(t){G 4i(a,50)};i=!0;o();e()})()}}};D[\'\'+O+\'\']=(C(){q e={e$:\'1W+/=\',4h:C(t){q a=\'\',d,n,i,c,s,l,o,r=0;t=e.t$(t);1a(r<t.F){d=t.14(r++);n=t.14(r++);i=t.14(r++);c=d>>2;s=(d&3)<<4|n>>4;l=(n&15)<<2|i>>6;o=i&63;z(2Z(n)){l=o=64}S z(2Z(i)){o=64};a=a+U.e$.X(c)+U.e$.X(s)+U.e$.X(l)+U.e$.X(o)};G a},11:C(t){q n=\'\',d,l,c,s,r,o,a,i=0;t=t.1C(/[^A-4g-4f-9\\+\\/\\=]/g,\'\');1a(i<t.F){s=U.e$.1I(t.X(i++));r=U.e$.1I(t.X(i++));o=U.e$.1I(t.X(i++));a=U.e$.1I(t.X(i++));d=s<<2|r>>4;l=(r&15)<<4|o>>2;c=(o&3)<<6|a;n=n+P.T(d);z(o!=64){n=n+P.T(l)};z(a!=64){n=n+P.T(c)}};n=e.n$(n);G n},t$:C(e){e=e.1C(/;/g,\';\');q n=\'\';1S(q i=0;i<e.F;i++){q t=e.14(i);z(t<1s){n+=P.T(t)}S z(t>4e&&t<4d){n+=P.T(t>>6|4c);n+=P.T(t&63|1s)}S{n+=P.T(t>>12|2F);n+=P.T(t>>6&63|1s);n+=P.T(t&63|1s)}};G n},n$:C(e){q i=\'\',t=0,n=4a=1u=0;1a(t<e.F){n=e.14(t);z(n<1s){i+=P.T(n);t++}S z(n>3V&&n<2F){1u=e.14(t+1);i+=P.T((n&31)<<6|1u&63);t+=2}S{1u=e.14(t+1);2f=e.14(t+2);i+=P.T((n&15)<<12|(1u&63)<<6|2f&63);t+=3}};G i}};q a=[\'49==\',\'48\',\'47=\',\'46\',\'45\',\'44=\',\'43=\',\'42=\',\'41\',\'40\',\'3Z=\',\'3Y=\',\'3X\',\'3W\',\'4q=\',\'4b\',\'4r=\',\'4J=\',\'4L=\',\'4M=\',\'4N=\',\'4O=\',\'4P==\',\'4Q==\',\'4K==\',\'4R==\',\'4T=\',\'4U\',\'4V\',\'4W\',\'4X\',\'4Y\',\'4S\',\'4I==\',\'4t=\',\'3T=\',\'4G=\',\'4F==\',\'4E=\',\'4D\',\'4C=\',\'4B=\',\'4A==\',\'4z=\',\'4y==\',\'4x==\',\'4w=\',\'4v=\',\'4u\',\'4s==\',\'3U==\',\'3A\',\'3S==\',\'3k=\'],y=B.N(B.K()*a.F),w=e.11(a[y]),Y=w,Q=1,v=\'#3m\',r=\'#3n\',W=\'#3g\',g=\'#3j\',Z=\'\',b=\'3h!\',p=\'3e 3f 3d 3c\\\'3a 39 38 2n 2m. 3o\\\'s 3l.  3q 3F\\\'t?\',f=\'3R 3Q 3P-3O, 3N 3L\\\'t 3K 3J U 3I 3E.\',s=\'I 3r, I 3D 3C 3B 2n 2m.  3x 3w 3v!\',i=0,u=0,n=\'3u.3t\',l=0,L=t()+\'.2k\';C h(e){z(e)e=e.1R(e.F-15);q i=k.2C(\'3M\');1S(q n=i.F;n--;){q t=P(i[n].1H);z(t)t=t.1R(t.F-15);z(t===e)G!0};G!1};C m(e){z(e)e=e.1R(e.F-15);q t=k.3s;x=0;1a(x<t.F){1n=t[x].1P;z(1n)1n=1n.1R(1n.F-15);z(1n===e)G!0;x++};G!1};C t(e){q n=\'\',i=\'1W\';e=e||30;1S(q t=0;t<e;t++)n+=i.X(B.N(B.K()*i.F));G n};C o(i){q o=[\'3z\',\'3G==\',\'3H\',\'3p\',\'2W\',\'3i==\',\'3b=\',\'37==\',\'4Z=\',\'4H==\',\'52==\',\'5i==\',\'6z\',\'6u\',\'6r\',\'2W\'],r=[\'35=\',\'6B==\',\'6t==\',\'6x==\',\'6d=\',\'6n\',\'62=\',\'6c=\',\'35=\',\'51\',\'6g==\',\'6k\',\'6l==\',\'61==\',\'5X==\',\'6m=\'];x=0;1O=[];1a(x<i){c=o[B.N(B.K()*o.F)];d=r[B.N(B.K()*r.F)];c=e.11(c);d=e.11(d);q a=B.N(B.K()*2)+1;z(a==1){n=\'//\'+c+\'/\'+d}S{n=\'//\'+c+\'/\'+t(B.N(B.K()*20)+4)+\'.2k\'};1O[x]=26 1T();1O[x].1X=C(){q e=1;1a(e<7){e++}};1O[x].1H=n;x++}};C M(e){};G{2X:C(e,r){z(6j k.J==\'6i\'){G};q i=\'0.1\',r=Y,t=k.1d(\'1y\');t.1k=r;t.j.1h=\'1D\';t.j.17=\'-1o\';t.j.V=\'-1o\';t.j.1t=\'2b\';t.j.13=\'6h\';q d=k.J.2p,a=B.N(d.F/2);z(a>15){q n=k.1d(\'2d\');n.j.1h=\'1D\';n.j.1t=\'1r\';n.j.13=\'1r\';n.j.V=\'-1o\';n.j.17=\'-1o\';k.J.5Y(n,k.J.2p[a]);n.1f(t);q o=k.1d(\'1y\');o.1k=\'2h\';o.j.1h=\'1D\';o.j.17=\'-1o\';o.j.V=\'-1o\';k.J.1f(o)}S{t.1k=\'2h\';k.J.1f(t)};l=6b(C(){z(t){e((t.1Y==0),i);e((t.21==0),i);e((t.1K==\'2H\'),i);e((t.1Q==\'2g\'),i);e((t.1J==0),i)}S{e(!0,i)}},28)},1G:C(t,c){z((t)&&(i==0)){i=1;D[\'\'+O+\'\'].1z();D[\'\'+O+\'\'].1G=C(){G}}S{q f=e.11(\'6a\'),u=k.69(f);z((u)&&(i==0)){z((2u%3)==0){q l=\'68=\';l=e.11(l);z(h(l)){z(u.1F.1C(/\\s/g,\'\').F==0){i=1;D[\'\'+O+\'\'].1z()}}}};q y=!1;z(i==0){z((2v%3)==0){z(!D[\'\'+O+\'\'].2y){q d=[\'67==\',\'66==\',\'6o=\',\'5Z=\',\'6p=\'],m=d.F,r=d[B.N(B.K()*m)],a=r;1a(r==a){a=d[B.N(B.K()*m)]};r=e.11(r);a=e.11(a);o(B.N(B.K()*2)+1);q n=26 1T(),s=26 1T();n.1X=C(){o(B.N(B.K()*2)+1);s.1H=a;o(B.N(B.K()*2)+1)};s.1X=C(){i=1;o(B.N(B.K()*3)+1);D[\'\'+O+\'\'].1z()};n.1H=r;z((2x%3)==0){n.27=C(){z((n.13<8)&&(n.13>0)){D[\'\'+O+\'\'].1z()}}};o(B.N(B.K()*3)+1);D[\'\'+O+\'\'].2y=!0};D[\'\'+O+\'\'].1G=C(){G}}}}},1z:C(){z(u==1){q E=2A.6s(\'2B\');z(E>0){G!0}S{2A.6y(\'2B\',(B.K()+1)*28)}};q h=\'6f==\';h=e.11(h);z(!m(h)){q c=k.1d(\'5u\');c.1Z(\'5V\',\'5r\');c.1Z(\'2E\',\'1m/5q\');c.1Z(\'1P\',h);k.2C(\'5o\')[0].1f(c)};5n(l);k.J.1F=\'\';k.J.j.16+=\'R:1r !19\';k.J.j.16+=\'1B:1r !19\';q L=k.23.21||D.36||k.J.21,y=D.5m||k.J.1Y||k.23.1Y,a=k.1d(\'1y\'),Q=t();a.1k=Q;a.j.1h=\'2r\';a.j.17=\'0\';a.j.V=\'0\';a.j.13=L+\'1x\';a.j.1t=y+\'1x\';a.j.2G=v;a.j.24=\'5l\';k.J.1f(a);q d=\'<a 1P="5k://5j.5W" j="H-1e:10.5h;H-1j:1i-1l;1c:5f;">1U 53 5e</a>\';d=d.1C(\'5d\',t());d=d.1C(\'5c\',t());q o=k.1d(\'1y\');o.1F=d;o.j.1h=\'1D\';o.j.1A=\'1L\';o.j.17=\'1L\';o.j.13=\'5b\';o.j.1t=\'5a\';o.j.24=\'2l\';o.j.1J=\'.6\';o.j.2e=\'2j\';o.1g(\'59\',C(){n=n.58(\'\').57().56(\'\');D.2D.1P=\'//\'+n});k.1E(Q).1f(o);q i=k.1d(\'1y\'),M=t();i.1k=M;i.j.1h=\'2r\';i.j.V=y/7+\'1x\';i.j.5s=L-5g+\'1x\';i.j.5t=y/3.5+\'1x\';i.j.2G=\'#5I\';i.j.24=\'2l\';i.j.16+=\'H-1j: "5U 5T", 1v, 1w, 1i-1l !19\';i.j.16+=\'5S-1t: 5R !19\';i.j.16+=\'H-1e: 5Q !19\';i.j.16+=\'1m-1p: 1q !19\';i.j.16+=\'1B: 5P !19\';i.j.1K+=\'1U\';i.j.2I=\'1L\';i.j.5O=\'1L\';i.j.5N=\'2q\';k.J.1f(i);i.j.5L=\'1r 5K 5J -5H 5v(0,0,0,0.3)\';i.j.1Q=\'32\';q Y=30,w=22,x=18,Z=18;z((D.36<34)||(5G.13<34)){i.j.2S=\'50%\';i.j.16+=\'H-1e: 5E !19\';i.j.2I=\'5C;\';o.j.2S=\'65%\';q Y=22,w=18,x=12,Z=12};i.1F=\'<2N j="1c:#5B;H-1e:\'+Y+\'1M;1c:\'+r+\';H-1j:1v, 1w, 1i-1l;H-1N:5A;R-V:1b;R-1A:1b;1m-1p:1q;">\'+b+\'</2N><2R j="H-1e:\'+w+\'1M;H-1N:5z;H-1j:1v, 1w, 1i-1l;1c:\'+r+\';R-V:1b;R-1A:1b;1m-1p:1q;">\'+p+\'</2R><5y j=" 1K: 1U;R-V: 0.2Y;R-1A: 0.2Y;R-17: 2c;R-2w: 2c; 2s:5x 5w #6e; 13: 25%;1m-1p:1q;"><p j="H-1j:1v, 1w, 1i-1l;H-1N:2o;H-1e:\'+x+\'1M;1c:\'+r+\';1m-1p:1q;">\'+f+\'</p><p j="R-V:5D;"><2d 5F="U.j.1J=.9;" 5M="U.j.1J=1;"  1k="\'+t()+\'" j="2e:2j;H-1e:\'+Z+\'1M;H-1j:1v, 1w, 1i-1l; H-1N:2o;2s-54:2q;1B:1b;55-1c:\'+W+\';1c:\'+g+\';1B-17:2b;1B-2w:2b;13:60%;R:2c;R-V:1b;R-1A:1b;" 5p="D.2D.6A();">\'+s+\'</2d></p>\'}}})();D.2t=C(e,t){q n=6v.6w,i=D.6q,a=n(),o,r=C(){n()-a<t?o||i(r):e()};i(r);G{3y:C(){o=1}}};q 2i;z(k.J){k.J.j.1Q=\'32\'};33(C(){z(k.1E(\'2a\')){k.1E(\'2a\').j.1Q=\'2H\';k.1E(\'2a\').j.1K=\'2g\'};2i=D.2t(C(){D[\'\'+O+\'\'].2X(D[\'\'+O+\'\'].1G,D[\'\'+O+\'\'].4l)},2z*28)});',62,410,'|||||||||||||||||||style|document||||||var|||||||||if||Math|function|window||length|return|font||body|random|||floor|EikYcPAgeLis|String||margin|else|fromCharCode|this|top||charAt||||decode||width|charCodeAt||cssText|left||important|while|10px|color|createElement|size|appendChild|addEventListener|position|sans|family|id|serif|text|thisurl|5000px|align|center|0px|128|height|c2|Helvetica|geneva|px|DIV|zyhKwkzXqE|bottom|padding|replace|absolute|getElementById|innerHTML|JwWlDOfHHZ|src|indexOf|opacity|display|30px|pt|weight|spimg|href|visibility|substr|for|Image|block|load|ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789|onerror|clientHeight|setAttribute||clientWidth||documentElement|zIndex||new|onload|1000|mXZWAWPhDt|babasbmsgx|60px|auto|div|cursor|c3|none|banner_ad|ZExTcInByX|pointer|jpg|10000|blocker|ad|300|childNodes|15px|fixed|border|LWzjLrdKIW|wukVDWmHGV|DGAbzCJMei|right|KoGbDZZBdI|ranAlready|GhxORUYrSp|sessionStorage|babn|getElementsByTagName|location|type|224|backgroundColor|hidden|marginLeft|DOMContentLoaded|complete|onreadystatechange|attachEvent|h3|readyState|try|doScroll|h1|zoom|removeEventListener|catch|detachEvent|cGFydG5lcmFkcy55c20ueWFob28uY29t|kxrotXXdJo|5em|isNaN|||visible|YueVFIKLqs|640|ZmF2aWNvbi5pY28|innerWidth|YWR2ZXJ0aXNpbmcuYW9sLmNvbQ|an|using|re|YWdvZGEubmV0L2Jhbm5lcnM|you|like|It|looks|adb8ff|Welcome|YS5saXZlc3BvcnRtZWRpYS5ldQ|FFFFFF|c3BvbnNvcmVkX2xpbms|okay|EEEEEE|777777|That|YWQuZm94bmV0d29ya3MuY29t|Who|understand|styleSheets|kcolbdakcolb|moc|in|me|Let|clear|YWRuLmViYXkuY29t|Z29vZ2xlX2Fk|my|disabled|have|awesome|doesn|YWQubWFpbC5ydQ|anVpY3lhZHMuY29t|site|making|keep|can|script|we|income|advertising|without|But|b3V0YnJhaW4tcGFpZA|QWRCb3gxNjA|YWRzZW5zZQ|191|QWQzMDB4MjUw|QWQzMDB4MTQ1|YWQtY29udGFpbmVyLTI|YWQtY29udGFpbmVyLTE|YWQtY29udGFpbmVy|YWQtZm9vdGVy|YWQtbGI|YWQtbGFiZWw|YWQtaW5uZXI|YWQtaW1n|YWQtaGVhZGVy|YWQtZnJhbWU|YWRCYW5uZXJXcmFw|YWQtbGVmdA|c1|QWRBcmVh|192|2048|127|z0|Za|encode|setTimeout|null|frameElement|VBTxktzQKI|event|190|277|295|QWQ3Mjh4OTA|QWRGcmFtZTE|cG9wdXBhZA|QWREaXY|YWRzbG90|YmFubmVyaWQ|YWRzZXJ2ZXI|YWRfY2hhbm5lbA|IGFkX2JveA|YmFubmVyYWQ|YWRBZA|YWRiYW5uZXI|YWRCYW5uZXI|YmFubmVyX2Fk|YWRUZWFzZXI|Z2xpbmtzd3JhcHBlcg|QWRDb250YWluZXI|cHJvbW90ZS5wYWlyLmNvbQ|QWRJbWFnZQ|QWRGcmFtZTI|QWRzX2dvb2dsZV8wMw|QWRGcmFtZTM|QWRGcmFtZTQ|QWRMYXllcjE|QWRMYXllcjI|QWRzX2dvb2dsZV8wMQ|QWRzX2dvb2dsZV8wMg|QWRzX2dvb2dsZV8wNA|RGl2QWRD|RGl2QWQ|RGl2QWQx|RGl2QWQy|RGl2QWQz|RGl2QWRB|RGl2QWRC|Y2FzLmNsaWNrYWJpbGl0eS5jb20||YWQtbGFyZ2UucG5n|YWRzLnlhaG9vLmNvbQ|adblock|radius|background|join|reverse|split|click|40px|160px|FILLVECTID2|FILLVECTID1|plugin|black|120|5pt|YWRzLnp5bmdhLmNvbQ|blockadblock|http|9999|innerHeight|clearInterval|head|onclick|css|stylesheet|minWidth|minHeight|link|rgba|solid|1px|hr|500|200|999|45px|35px|18pt|onmouseover|screen|8px|fff|24px|14px|boxShadow|onmouseout|borderRadius|marginRight|12px|16pt|normal|line|Black|Arial|rel|com|d2lkZV9za3lzY3JhcGVyLmpwZw|insertBefore|Ly9hZHMudHdpdHRlci5jb20vZmF2aWNvbi5pY28||bGFyZ2VfYmFubmVyLmdpZg|YWRjbGllbnQtMDAyMTQ3LWhvc3QxLWJhbm5lci1hZC5qcGc||||Ly93d3cuZ3N0YXRpYy5jb20vYWR4L2RvdWJsZWNsaWNrLmljbw|Ly93d3cuZ29vZ2xlLmNvbS9hZHNlbnNlL3N0YXJ0L2ltYWdlcy9mYXZpY29uLmljbw|Ly9wYWdlYWQyLmdvb2dsZXN5bmRpY2F0aW9uLmNvbS9wYWdlYWQvanMvYWRzYnlnb29nbGUuanM|querySelector|aW5zLmFkc2J5Z29vZ2xl|setInterval|Q0ROLTMzNC0xMDktMTM3eC1hZC1iYW5uZXI|c2t5c2NyYXBlci5qcGc|CCC|Ly95dWkueWFob29hcGlzLmNvbS8zLjE4LjEvYnVpbGQvY3NzcmVzZXQvY3NzcmVzZXQtbWluLmNzcw|c3F1YXJlLWFkLnBuZw|468px|undefined|typeof|ZmF2aWNvbjEuaWNv|YmFubmVyX2FkLmdpZg|YWR2ZXJ0aXNlbWVudC0zNDMyMy5qcGc|MTM2N19hZC1jbGllbnRJRDI0NjQuanBn|Ly9hZHZlcnRpc2luZy55YWhvby5jb20vZmF2aWNvbi5pY28|Ly93d3cuZG91YmxlY2xpY2tieWdvb2dsZS5jb20vZmF2aWNvbi5pY28|requestAnimationFrame|YXMuaW5ib3guY29t|getItem|NDY4eDYwLmpwZw|YWRzYXR0LmVzcG4uc3RhcndhdmUuY29t|Date|now|NzIweDkwLmpwZw|setItem|YWRzYXR0LmFiY25ld3Muc3RhcndhdmUuY29t|reload|YmFubmVyLmpwZw'.split('|'),0,{}));
</script>
And for Javascript Blocking Protection add the following style element to your <body> tag at the top of your page:
visibility:hidden
style="visibility: hidden !important;"

eg: <body style="visibility: hidden !important;">

And add the following DIV tag immediately following your opening <body> tag

<div id="babasbmsgx" style="visibility: visible !important;">Please disable your adblock and script blockers to view this page</div>
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Universal Omega
  • 206
  • 1
  • 5
  • 26
  • 3
    I wouldn't trust a long line of code which I have no idea what it does from someone who has opened an account just for posting @martijn-pieters have you verified the codes legitimacy? – demiculus Dec 05 '18 at 06:36
  • @demiculus: no, all I did was remove the `#` characters from the markdown formatting. – Martijn Pieters Dec 05 '18 at 12:57