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
- Author: Phan Thanh Cong
- Email: contact@ptcong.com
- Official website: http://popunderjs.com
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.
- Make pop/tab under/up, works on every desktop, mobile browsers.
- Bypass Adblock Plus
- Support multiple urls, random urls, hooks.
- Use modern syntax, very easy to setup/install.
- Filter mobile, desktop traffics.
- Support asynchonours loading.
- Can bind to or ignore to specific HTML tag names or DOM elements.
- Hidding traffic source.
- Well API, documents.
- and more..
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>
Note: You have to run it in
http://
orhttps://
protocol, don’t run it by double click to your html file. It may not works withfile://
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 addwindow.popns = 'YourOwnName'
on top ofscript.js
or before loadingscript.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:
name
, typestring
- Name of the pop window, each pop already has a unique name by default, you can change it if you want.
device
typestring
, default"any"
, accepted"desktop", "mobile" or "any"
- To filter traffic for the pop, sometimes you want to open pop only for
"mobile"
or"desktop"
.
- To filter traffic for the pop, sometimes you want to open pop only for
expires
typeinteger
DateTime
, default session- By defaults, pop works with session that mean user have to close their browser to get new pop. You can change this to number of seconds or
DateTime
value. (read more) - For example, if you want pop for every 30 minutes, use
expires: 1800
- By defaults, pop works with session that mean user have to close their browser to get new pop. You can change this to number of seconds or
under
typeboolean
, defaulttrue
- If you want to open pop up, change this to
false
- If you want to open pop up, change this to
tab
typeboolean
, defaultfalse
- Change this to
true
if you want to use tab instead of new window.
- Change this to
shouldFire
typefunction(pop, event, target)
- You can add your logic to determine this pop should be fire or not.
- Your logic will be used after main logic, so if pop is fired, even you use
true
, it will not fire. - You can use this to tell the script only open pop if user click to specifc element. (read more)
beforeOpen
typefunction(pop)
, default: NOOP- This method will be called before the pop fired.
afterOpen
typefunction(pop, popWin)
, default: NOOP- This method will be called after the pop fired.
popWin
references to window object of the pop (if you use pop up/under)
noReferrer
typeboolean
, defaultfalse
- Change this to
true
if you want to hide referer for the pop url.
- Change this to
noOpenner
typeboolean
, defaulttrue
- Change this to
true
if you want to hide referer for the pop url.
- Change this to
- You also have option
width
,height
,top
,left
to custom pop window size, postion
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 API
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');