Better Popunder JS

#1 Popunder Script on the market

Version 3.x.x includes fewer APIs but is more powerful and give better result. The entire script has been rewritten.

Last updated at 2025/01/08

Table Of Contents

Introduction

BetterJsPop is #1 pop under script on the market, written in Javascript by Thanh Cong since 2012. At first it was shared for free but not updated frequently and become paid premium script since lately 2015 with lot of improvements.

About Bypass Adblock

Our script can open pop even with Adblock enabled, but unfortunately, if your pop url is in Adblock’s blacklist, they will close pop window/tab right after it opened. First time we can use redirector trick to bypass this, but Adblock has updated their mechanism same as uBlock Origin as they monitor all urls in tabs, windows then close it when they found a url in blacklist.

If your pop url isn’t in their blacklist ? Congratulation!! You can use our script to open your pop as well even if Adblock is enabled.

Installation

To install this script, you have to upload these files to your server.

They are: script.js, license.XX.js while XX is a random number.

If you’re using local environment, you can use some local domains as 127.0.0.1, *.local to test the script.

Note: license.XX.js is your license file, i will send you this file after you registered your domains with us via email. Don’t use license file that you got from updates or .zip file, it’s just a demo license and does not work in production environment.

For example, your domain is: domain.com, after uploaded all needed files, we got some links:

http://domain.com/script/script.js http://domain.com/script/license.XX.js

So we use basic setup to see how it works.

<script src="http://domain.com/script/script.js"></script>
<script src="http://domain.com/script/license.XX.js"></script>
<script>
BetterJsPop.add('http://example.com', {under: true, tab: false});
</script>
You can use our merger tool https://popunderjs.com/merger.php to merge both script and license file, so uploading it to your server will be easier. The tool also provide some tweaks to help you run this script better.

Note: You have to run it in http:// or https:// protocol, don’t run it by double click to your html file. It may not works with file:// protocol.

Configuration

By default, the script using BetterJsPop as variable name. You can chagne this to any name you want to avoid conflict with other adnetwork (due we have lot of adnetwork as customers). To change this variable, please add window.popns = 'YourOwnName' on top of script.js or before loading script.js For example:

<script>window.popns = 'YourOwnName';</script>
<script src="http://domain.com/script/script.js"></script>
<script src="http://domain.com/script/license.XX.js"></script>
<script>YourOwnName.add('http://example.com');</script>

This is manual method, you can use our Merger Tool to do this.

We have some config options with default values:

Option Type Default
prefix string BetterJsPop
perPage integer -1
bindTo Array null
ignoreTo Array null
interval integer 0
debug boolean false
fallback Object { under: true, tab: true }
mobileSensitive integer 20
noOpenner boolean true
noReferrer boolean false
allowScrollbar boolean true
allowPopUnderTrick boolean true
blankAnchor string TAB_UNDER

To use the options, we put inside .config().

For example:

BetterJsPop.config({
    debug: true,
    perPage: 5
});
Option: perPage

In early version, it’s perpage, but you can use both name in version 3

To limit the number of pop-ups per page load, set the value accordingly. The default is -1 (no limit). You can add multiple urll to the stack using .add(), and the script will sequentially open the URLs each time the user clicks.

Option: bindTo

You can set array of query selectors or DOM elements to tell scripts only open pop when user click to elements you want.

Option: ignoreTo

You can set array of query selectors or DOM elements to tell scripts not open pop when user click to elements you want.

Option: interval

In early version, it’s delay in milliseconds, but since @3.x, we changed to delay in seconds

Number of seconds to wait between two pops to avoid spamming/ pop blocked message.

Option: debug

Enable this option to see log message, or you can use BetterJsPop.Logger.print() to print all queued messages.

Option: blankAnchor

Webkit allow open only one pop/tab by 1 click, we can’t open more at once. If user click to a link with target="_blank", we only can open pop or that link.

IGNORE: Script will not do anything when user click to _blank anchor.

TAB_UNDER: Open a tab under with focus tab is the link and under tab is pop url.

PREVENT: Open pop and prevent default behavior.

Option: fallback

In early version, it’s popFallbackOptions, you can use both name in version 3.x

In some cases, popunder is not avalable, the script will use this option to open pop.

Default is tab under { under: true, tab: true }

You may change it to popup as { under: false, tab: false }

or tabup { under: false, tab: true }

Option: mobileSensitive - @since 2.2.26

mobileSensitive is option to control our fast click technique, sometimes if user scroll a short distance, the script will consider it’s a click and open pop fast.

Default value is 20 will get more pop impressions, if you don’t like this way, you can reduce to 30 or 10.

Don’t set it higher 30, the option should be 30, 20 or 10.

Option: noOpener

Global setting to avoid popped window trying to redirect main window by using window.opener.location. You can adjust this setting for each pop.

Option: noReferrer

Global setting to hide referrer. You can adjust this setting for each pop.

Option: allowScrollbar

In early version, it’s coverScrollbar, but you can use both in version 3.x

Allow the script fire pop when user click to scrollbar. Default value is true

Option: allowPopUnderTrick - @since 3.0.0

Create a small window then move it around. When user click focus to the main window, the small window will become pop under.

Limit Domains For Unlimited Package - @since 1.3.2

Unlimited package mean any website can embed and use your script. Sometimes you want to prevent this and just want to active for some domains.

It’s so easy, just open your license file, then add the code on the top.

window[window.popns || 'BetterJsPop'].href = ['domain1.com', 'domain2.com'];
...

Add new pop

To add new pop to queue list, we ust .add() method.

BetterJsPop.add('http://example.com', {});

Pop Options

For each pop, we have these options:

Example: use pop options

To use pop options, please take a look at this basic example:

BetterJsPop
.add('http://example.com/url1', {
    under: true,
    tab: false
})
.add('http://example.com/url2', {
    device: 'desktop',
    expires: 900, // open every 15 minutes. Note: user have to click to page content to get pop
    beforeOpen: function(pop) {
        console.log('pop url', pop.url);
    },
    afterOpen: function(pop, popWin) {
        consoe.log('after pop open', pop, popWin);
    }
})
Example: shouldFire option
BetterJsPop.add('http://example.com', {
    shouldFire: function(pop, event, target) {
        return target === jQuery('#your-element')[0];
    }
});
Pop option: expires

By defaults, this script use cookie as session for pop, so if pop is fired, user have to close browser to get new pop.

You also can set a DateTime or integer number of seconds for expires.

If you want to pop for every click, you can use expires: 0.

API

config() method

Used to configure the script, for more options, check Configuration section.

/**
 * @param options object
 * @return self
 */
BetterJsPop.config(options);

getConfig() method

Used to get all options that script is using.

/**
 * return object
 */
BetterJsPop.getConfig();

add() method

Used to push a pop to queue then will fire pop when user click to page content.

/**
 * @param url       string|function
 * @param options   object or not defined.
 * @return self
 */
BetterJsPop.add(url, options);

You can pass a function as url to this method to get random url or run your logic before get url for pop.

Example for random urls.

// each time before open this pop, script will execute the function to get new url.
BetterJsPop.add(function() {
    var urls = [
        'http://example.com/?url1',
        'http://example.com/?url2'
    ];
    return urls[Math.floor(Math.random() * urls.length)];
});

You also can repeat .add() multiple times to add more pop

BetterJsPop.add('http://example1.com');
BetterJsPop.add('http://example2.com');
BetterJsPop.add('http://example3.com');

or you can use like this:

// Remember, don't have `;` after each `add`
BetterJsPop
    .add('http://example.com')
    .add('http://example2.com')
    .add('http://example3.com')

getStack() method

Used to get all added pops.

/**
 * @return array
 */
BetterJsPop.getStack();

emptyStack() method

Used to remove all added pops from stack. This will not remove cookie flags. If you want to remove cookies, use reset() method instead of.

/**
 * @return void
 */
BetterJsPop.emptyStack();

bindTo() method

Used to register the pop to some speicifc tag names or DOM nodes.

/**
 * @param string|array|multiple arguments
 * @return self
 */
BetterJsPop.bindTo(arguments);

Example:

// bind script to all img tags
BetterJsPop.bindTo('img');

// you want to bind to all <a> tag ?
BetterJsPop.bindTo('a');

// bind to more than one tag ?
BetterJsPop.bindTo(['button', 'img']);

// or can use like this
BetterJsPop.bindTo('button', 'img');

// @since 2.5.16 - Support selector
BetterJsPop.bindTo(['#id-of-element', '.class-of-elements']);

// To clear bind/ignored list, use
BetterJsPop.bindTo(false);

If you want to bind script to all class name ?

jQuery(document).ready(function($) {
  $('.your-class-name').each(function () {
    BetterJsPop.bindTo(this);
  });
});

ignoreTo() method

Same as bindTo() but just used to tell the script don’t open pop when user click to ignored elements/ DOM nodes.

/**
 * @param string|array|multiple arguments
 * return self
 */
BetterJsPop.ignoreTo(arguments);

getBindTo() method

/**
 * @return array DOM elements
 */
BetterJsPop.getBindTo();

getIgnoreTo() method

/**
 * @return array DOM elements
 */
BetterJsPop.getIgnoreTo();

reset() method

/**
 * Delete all cookies, flags so pop will fire again without a page load.
 */
BetterJsPop.reset();

Logger API

Logger.log() method

/**
 * Add a log message to list. If debug mode is enabled, it will log to console immediately.
 * Support multiple arguments as console.log()
 */
BetterJsPop.Logger.log(arguments)

Logger.print() method

/**
 * Print all log messages to console.
 */
BetterJsPop.Logger.print();

Cookie.set() method

/**
 * Set cookie.
 *
 * @param name string
 * @param value mixed
 * @param expires DateTime|integer number of seconds
 * @param attributes object
 */
BetterJsPop.Cookie.set(name, value, expires, attributes);

Cookie.get() method

/**
 * Get cookie by name.
 *
 * @param  string
 * @return string|null
 */
BetterJsPop.Cookie.get();

Cookie.remove() method

/**
 * Remove a cookie by name.
 *
 * @param string name
 */
BetterJsPop.Cookie.remove(name);

Storage API

Storage.set() method

/**
 * Set storage item.
 *
 * @param string    name
 * @param mixed     value
 */
BetterJsPop.Storage.set(name, value);

Storage.get() method

/**
 * Get storage item by name.
 *
 * @param  string       name
 * @return string|null
 */
BetterJsPop.Storage.get(name);

Storage.remove() method

/**
 * Remove an item by name.
 *
 * @param name string
 */
BetterJsPop.Storage.remove(name);

Storage.clear() method

/**
 * Clear all storage items.
 *
 * @param name string
 */
BetterJsPop.Storage.clear();

Browser API

Browser.isLinux property

/**
 * @type boolean
 */
BetterJsPop.Browser.isLinux;

Browser.isWin property

/**
 * @type boolean
 */
BetterJsPop.Browser.isWin;

Browser.isMac property

/**
 * @type boolean
 */
BetterJsPop.Browser.isMac;

Browser.isIOS property

/**
 * @type boolean
 */
BetterJsPop.Browser.isIOS;

Browser.isAndroid property

/**
 * @type boolean
 */
BetterJsPop.Browser.isAndroid;

Browser.isMobile property

/**
 * @type boolean
 */
BetterJsPop.Browser.isMobile;

Browser.isWebkit property

/**
 * @type boolean
 */
BetterJsPop.Browser.isWebkit;

Browser.isMozilla property

/**
 * @type boolean
 */
BetterJsPop.Browser.isMozilla;

Browser.isChrome property

/**
 * @type boolean
 */
BetterJsPop.Browser.isChrome;

Browser.isFirefox property

/**
 * @type boolean
 */
BetterJsPop.Browser.isFirefox;

Browser.isSafari property

/**
 * @type boolean
 */
BetterJsPop.Browser.isSafari;

Browser.isIE property

/**
 * @type boolean
 */
BetterJsPop.Browser.isIE;

Browser.isEdge property

/**
 * @type boolean
 */
BetterJsPop.Browser.isEdge;

Browser.isOpera property

/**
 * @type boolean
 */
BetterJsPop.Browser.isOpera;

Browser.version property

/**
 * Return version number of browser
 * @type integer
 */
BetterJsPop.Browser.version;

Browser.longVersion property

/**
 * Return long version number of browser
 * @type string
 */
BetterJsPop.Browser.longVersion;

Browser.versionCompare method

/**
 * Compare current browser version to a version.
 * @return boolean
 */
BetterJsPop.Browser.versionCompare(operator, version);

Example:
BetterJsPop.Browser.versionCompare('>=', '10.5');
BetterJsPop.Browser.versionCompare('<', '60');