Page activation
Describes how to use polling and callback to activate a page.
Conditional activation mode is a flexible and powerful way to activate a page and its associated experiments. There are two ways to use it: with polling, you enter a condition and Optimizely Web Experimentation activates the page once that condition is true. With a callback, you enter a function and trigger a callback once your code is ready for the page to activate. These methods are described in more detail below, and we've also highlighted several examples using each method.
Based on the code you enter, Optimizely Web Experimentation will automatically determine if it should be polled for or executed as a function. See the examples for detailed usage definitions.
Polling
If the code entered does not evaluate to a function type, it will be checked every 50 milliseconds, and the page will be activated when it evaluates to true. Optimizely Web Experimentation checks this code in a try/catch block, so a condition that results in an error will be assumed to be false and polling will continue.
/*
* Usage Option #1 - Polling
* Optimizely will poll for the code condition to be true if the JavaScript
* entered does not evaluate to a function type.
*
* Note: Optimizely will evaluate this code in a try/catch block, meaning
* if your expression errors, it will be evaluated as false. Timeout is two seconds.
*/
// check if butter bar is in the DOM
document.getElementById("butter-bar-flash-sale") !== null;
/*
* Usage Option #2 - Callback Function
* Optimizely will call the function entered immediately if the JavaScript entered
* does evaluate to a function type.
*
* @param {Function} activate - Activate this Page
* @param {Object=} options {
* isActive : {Boolean} - Indicates if this page is active
* pageId : {String} - ID of the activated Page
* }
*
* Note: Optimizely will call this function immediately when the snippet loads, so make
* sure any functions referenced are defined at that time.
*/
function(activate, options) {
// Do logic and call `activate()` when appropriate
}
Polling – Meta tag data
To activate an experiment based on the value of a meta tag, select the contents of the meta tag with jQuery and check them for your value.
<pre><code><meta name="keywords" content="movies,games,videos,photos"/>
</code></pre>
/*
* Condition: Activate when the description meta tag contains 'sports', 'games', or 'puzzles'
* Type: Polling
*/
(/sports|games|puzzles/).test($('meta[name=keywords]').attr('content'))
Polling – JavaScript variable
To activate an experiment based on the value of a JavaScript variable, enter the condition to check.
/*
* Condition: Activate when the Omniture eVar 33 contains 'product'
* Type: Polling
*/
window.s.eVar33.indexOf('product') != -1
Polling – DOM element
To activate an experiment based on the existence of a DOM element, select that element and check the length of the result.
/*
* Condition: Activate when the green button DOM element appears
* Type: Polling
*/
function pollingFn() {
return document.querySelectorAll("button.green").length > 0;
}
Callback function
If the code entered is a function, Optimizely Web Experimentation assumes it is of the form shown here and call it immediately, passing an activate
function and an options
object. Rather than returning a value, your code should call activate()
when it's ready, leveraging options.isActive
and options.pageId
if needed. Because this function is called immediately when the Optimizely snippet loads, any functions or variables referenced here should be available/defined at the time they're used.
Note
No matter which method is used, remember that this is only an activation condition. Visitors must still meet URL and audience targeting to actually be bucketed into any experiments.
/*
* Usage Option #1 - Polling
* Optimizely will poll for the code condition to be true if the JavaScript
* entered does not evaluate to a function type.
*
* Note: Optimizely will evaluate this code in a try/catch block, meaning
* if your expression errors, it will be evaluated as false. Timeout is two seconds.
*/
// check if butter bar is in the DOM
document.getElementById("butter-bar-flash-sale") !== null;
/*
* Usage Option #2 - Callback Function
* Optimizely will call the function entered immediately if the JavaScript entered
* does evaluate to a function type.
*
* @param {Function} activate - Activate this Page
* @param {Object=} options {
* isActive : {Boolean} - Indicates if this page is active
* pageId : {String} - ID of the activated Page
* }
*
* Note: Optimizely will call this function immediately when the snippet loads, so make
* sure any functions referenced are defined at that time.
*/
function(activate, options) {
// Do logic and call `activate()` when appropriate
}
Callback function – Button click
To activate an experiment when a button is clicked, bind a click
or mousedown
event to that element using jQuery and activate the experiment when that event fires.
/*
* Condition: Activate when a button is clicked
* Type: Callback function
*/
function(activate, options) {
// following line assumes you are including jQuery in your Optimizely snippet
var $ = window.optimizely.get('jquery');
$('html').on('mousedown', '#btn', function() {
activate();
});
}
Callback function – AJAX response
To activate an experiment after an AJAX call returns, leverage jQuery's ajaxComplete
function to listen to completed AJAX requests. If the response contains or corresponds to the element that should be changed, activate the experiment.
Note
Optimizely Web Experimentation's default (trimmed) version of jQuery doesn't contain the
ajaxComplete
function. To use this function, you can include the full version of jQuery in your Optimizely snippet (Project Settings -> Project Code Settings) or reference your own version of jQuery that loads above the Optimizely snippet viawindow.$
.
You can disable $.ajaxComplete
on your site if the AJAX setup is called with global
option set to false
, preventing this event from firing. See jQuery's documentation for more information.
/*
* Condition: Activate when an AJAX call contains the element that should be changed
* Type: Callback function
*/
function(activate, options) {
// following line assumes you are including (full version of) jQuery in your Optimizely snippet
var $ = window.optimizely.get('jquery');
$(document).ajaxComplete(function(event, xhr, settings) {
if (xhr.responseText.indexOf('rightRailModule') != -1) {
activate();
}
});
}
Callback function – DOM mutation activation
To activate an experiment based on a DOM element either changing or appearing on the page, make the following call in your experiment's conditional activation code box:
js
function(activate, options) {
window.activateOnDOMMutation('#element:not(.changed)', activate, true);
}
The first part of the call, #element:not(.changed)
, is a DOM element selector you'd like to monitor. Any time this element appears on the page or is changed, the experiment will be activated either once or multiple times depending on the last parameter. You can use any DOM selector that can be used with jQuery. If you change the selected element or its children in Variation code, you'll create an infinite loop. You can prevent this by excluding selectors with an added class, as shown in the code example. You would add the ".changed" class in experiment code.
The second part of the call, activate
, activates the experiment with the given ID.
The last parameter, true
, tells the DOM mutation call that you want to reactivate the experiment every time the selector changes or is added to the page. Adding false
here will activate the experiment only once. This is useful when you're appending content to the page and you don't want to append every time the DOM selector changes.
/*
* Condition: Activate when the dom selector changes on the page
* Type: Callback Function
*
* Place the following code in your Project Javascript and call the function below in your experiment's
* conditional activation code box:
*
* window.activateOnDOMMutation('#element', window['optimizely'].push(["activate", EXPERIMENT_ID]), true);
* @param '#element': DOM Selector of element you'd like to watch
* @param 'window['optimizely'].push(["activate", EXPERIMENT_ID])': Replace EXPERIMENT_ID with the current
* experiment's ID
* @param 'true': True re-activates the experiment on the DOM selector changing or being added to the DOM.
* False activates the experiment only the first time the selector is added or updated.
*/
(function(win) {
'use strict';
var listeners = [],
doc = win.document,
MutationObserver = win.MutationObserver || win.WebKitMutationObserver,
observer;
function waitForElement(selector, repeat, fn) {
// Store the selector and callback to be monitored
listeners.push({
selector: selector,
fn: fn,
repeat: repeat,
});
if (!observer) {
// Watch for changes in the document
observer = new MutationObserver(check);
observer.observe($(document), {
childList: true,
subtree: true
});
}
// Check if the element is currently in the DOM
check();
}
function check() {
// Check the DOM for elements matching a stored selector
for (var i = 0, len = listeners.length, listener, elements; i < len; i++) {
listener = listeners[i];
// Query for elements matching the specified selector
elements = $(listener.selector);
for (var j = 0, jLen = elements.length, element; j < jLen; j++) {
element = elements[j];
if (!element.ready || listener.repeat) {
// Invoke the callback with the element
listener.fn.call(element, element);
}
}
}
}
function activateOnDOMMutation(selector, activate, repeat) {
repeat = repeat === undefined ? false : repeat;
if (window.MutationObserver || window.WebKitMutationObserver) {
waitForElement(selector, repeat, function(element) {
activate();
});
} else {
// this solution does not handle older browsers
}
}
// Expose functions
win.waitForElement = waitForElement;
win.activateOnDOMMutation = activateOnDOMMutation;
})(this);
Callback activation – Conditionally activated pages
Use jQuery and the native utility functions of Optimizely to activate a page conditionally after a DOM element is found on the page. This method is advantageous to the polling activation type because it's not limited by the two-second timeout after DOM ready.
function callbackFn(activate, options) {
var utils = window.optimizely.get('utils');
var $ = window.optimizely.get('jquery');
utils.waitForElement('button').then(function(buttonElement) {
if ($('button').length > 0) {
activate();
}
});
}
Callback activation – Custom activation
There might be instances where you want to activate a page following the execution of an asynchronous function. You can use conditional activation to call the external function and pass activate
as a callback.
function callbackFn(activate, options) {
if (window.location.href.indexOf(/* Some URL */) !== -1) {
options.isActive && activate({isActive: false});
window.customProcessFunction.init(activate);
}
}
Updated almost 2 years ago