Rich-text Reply

jQuery Trigger Click Event

drofnas 02-05-15
Accepted Solution

jQuery Trigger Click Event

[ Edited ]

I'm sure there is something simple that I'm missing, but when I try and do a simple experiment that calls the Click event for a button, it doesn't seem to work:

 

$("#vampires-carousel-category-link").trigger("click");

 

I'm trying this out on our registration website: join.secondlife.com

 

It's just going to be a simple expirement as to what category of avatars we are showing by default. When I do that same code in the Chrome Console, it works just fine, but can't seem to get it to work via Optimizely. My expirement ID is "2449620011", not sure if that will help anyone. I've even added the following just to ensure the code was being triggered in the first place (since I can't get console.log to work either):

 

$("#carousel-categories").css({"background-color":"#fcc"});

 

I'm currently testing this on my local development machine, so I can't show you this running in some sort of live capacity.

 

Thanks for any help you can provide.

Level 2

JDahlinANF 02-06-15
 

Re: jQuery Trigger Click Event

Most likely, the event you are hoping to invoke has not been bound to the DOM element yet.

 

Presumably, your site's JS file contains something like

$('#vampires-carousel-category-link').click(function(){
  //do some stuff
});

 Further, it is typical to place these types of things inside of "document.ready() llike this:

$(document).ready(function() {
  $('#vampires-carousel-category-link').click(function(){
    //do some stuff
  });
});

 If the Optimizely code executes before that code runs, the click will not run "do some stuff".

What you need to do is wait for the "do some stuff" code to be assigned to the click event before you trigger the click.

 

I'll post another comment with some commentary on how you might do this.

JDahlinANF 02-06-15
 

Re: jQuery Trigger Click Event

Because you need to wait for "stuff to happen" before you trigger the click event, you need to find way for your page to let you know that the binding is ready for you.

 

For example, is there a variable reference that is created during that binding that you coudl "listen for"?  Perhaps there is a variable that is created after that binding takes place that you could listen for?

 

Suppose your site does something like this:

var $theElements = $('.carousel-links');
$.each($theElements,function(e){
  e.click(function(){
    //do some stuff
  });
});

You could try waiting for $theElements to exist.

A safer bet would be to use a variable that is created after that code executes.

Here are a couple articles that talk about setting this up:

The original support article: https://help.optimizely.com/hc/en-us/articles/200040635

My take on it: https://community.optimizely.com/t5/Using-Optimizely/How-to-change-a-javascript-variable/td-p/5946

JDahlinANF 02-06-15
 

Re: jQuery Trigger Click Event

Since you are running this locally, can you alter the structure of the code so that the click event doesn't "do some stuff" but instead calls a function that does some stuff?

 

$(document).ready(function() {
  $('.carousel-links').click(DoSomeStuff());

  function DoSomeStuff(){
    //do some stuff
  }
});

 

This way you can listen for whether the function exists.  Once the function exists, you can then trigger the click (or, just call the function yourself if that is more appropriate).

 

Hope this helps spur some ideas.

blueacorn 02-06-15
 

Re: jQuery Trigger Click Event

[ Edited ]
 

Re: jQuery Trigger Click Event

[ Edited ]

My guess is that you might be running into an issue wherein the content doesn't exist yet (the DOM elements) on the page when your JavaScript gets executed at run-time. In other words, the elements are "null" and so nothing happens. In this instance, you're going to need to use delegated events. jQuery has an awesome and versatile .on() method which handles delegated events, but unfortunately the Optimizely snippet uses jQuery 1.6 which doesn't have this method because .on() was introduced in jQuery 1.7... you can read more about it here: http://api.jquery.com/on/

Thankfully, you can use .delegate() which accomplishes the same thing albeit with different syntax/structure. You can read about it here: http://api.jquery.com/delegate/

 

Ultimately, what you can do is attach your click event listener to an element that already exists on the page. If there isn't an obvious element, then just use the <body> element. Then you can target elements that might exist in the future using this method and handle things accordingly. So, for example, let's say you have an HTML <table> element wherein a user could keep appending/adding rows maybe with some button. These rows would be <tr> elements. Well, you couldn't attach an event listener to a <tr> element that doesn't exist yet. BUT, you could attach the listener to the <table> element because that already exists, and then you can target any current and future <tr> elements using the .delegate() method. In this case, you would use the following structure:

 

$('table').delegate('tr', 'click', function() {
  // handle everything here
});

 

This would target all current and future <tr> elements. Hopefully that will work for you assuming that this is the issue you're experiencing. You'll find that you'll need to use delegated events quite a bit when using Optimizely. 

 

Another option is to also run a setInterval() method that checks for the presence of an element, and if it exists, then you do something. I use the following structure most of the time when I need to do this:

 

var interval = setInterval(function() {
  var $selector = $('.your_selector_here');
  if ( $selector.length > 0 ) {
    if ( $selector.is(':visible') ) {
      // your functions/logic here 
      clearInterval(interval); // clear the interval after you run your logic!
    }
  }
}, 250);


So in this code snippet, I'm essentially polling the DOM every 250ms for an element to see if it both exists AND is visible. Once it is, some logic/code runs and then the polling is stopped. 

 

Hopefully this helps!

 

Edit: apologies... posted this under my company's main account when I meant to post under this one.

-- Sean
UI Developer @ Blue Acorn

optimizely developer certification
drofnas 02-07-15
 

Re: jQuery Trigger Click Event

I tried following the article that nap0leon posted, related to dealing with delayed content. But even using their code (almost exactly, since Optimizely Editor complained about redefining timeout and keepAlive). This is what I've ended up with, but still doesn't work:

 

/* Don't touch this code */
function waitForDelayedContent(selector, experiment, t, k) {
    var intervalTime = 50;
    var timeout = t || 5000;
    var keepAlive = k || false;
    var maxAttempts = timeout / intervalTime;
    var attempts = 0;
    var elementsCount = 0;
    var interval = setInterval(function() {
        if ($(selector).length > elementsCount) {
            if (!keepAlive) {
                clearInterval(interval);
            }
            experiment();
            elementsCount = $(selector).length;
        } else  if (attempts > maxAttempts) {
            clearInterval(interval);
        }
        attempts ++;
    }, intervalTime);
}
/* --------------------------------------------- */

waitForDelayedContent('#vampires-carousel-category-link.bound', function(){
  $("#carousel-categories").css({"background-color":"#ddd"}); //visual test to ensure this runs
  $("#vampires-carousel-category-link").trigger('click');
});

 

I can see the '#carousel-categories' background color change on the page, but the trigger() still never happens. To ensure that something has been bound, and not relying on methods that Optimizely version of jQuery might not support, I simply added a class of "bound" to the element after I've added the click event. Then used that in my selector above.

 

$('#carousel-category-links .carousel-category-link').click(function() {
   //do stuff
}
}).addClass('bound');

 

I even tried replacing the click event above with an old school alert('blah'), just to try and see something work. But nope, that doesn't work either. It's like that "trigger()" doesn't even work, and I'm not sure why.

Level 2
Junan 02-11-15
 

Re: jQuery Trigger Click Event

@drofnas Similar to what you had tried and what @seanemmel_ba suggested, can you try this? The trigger() function should work within Optimizely so it sounds like it might be a timing issue (like the others have mentioned).

 

var myInterval = setInterval(function() {
if ($("#vampires-carousel-category-link").length > 0) {
$("#vampires-carousel-category-link").trigger('click');
clearInterval(myInterval);
}
}, 50);

 

Junan Pang
Optimizely
drofnas 02-11-15
 

Re: jQuery Trigger Click Event

That's what I'm doing right now, just with a bit more complex code :-)

 

But, I think I just figured out what it was. At least for the issue with "trigger()", I just changed that line of code to the following and that seems to have fixed it, now I just have some other items I need to wait for on the page now. Since that click event is occuring before other objects that need to be manipulated exist. But this is progress, finally.

 

jQuery("#vampires-carousel-category-link").trigger('click');

 

Level 2
Junan 02-11-15
 

Re: jQuery Trigger Click Event

@drofnas 

 

Ah, that's a good catch. You must be using Optimizely's trimmed version of jQuery. This leads into another suggestion which is, if you already have jQuery defined at the top of your page, you can go ahead and tell Optimizely to use your page's version of jQuery, thus reducing the size of the Optimizely snippet and also allowing you to use the functions not included in Optimizely's trimmed version. Just make sure that jQuery is included on the page before the Optimizely snippet.

 

Thanks!

Junan Pang
Optimizely