skip to Main Content

I am building an A/B test for a Shopify site through Google Optimize. When someone adds a product to the cart, a popup shows with the item added to cart for only 5 seconds. I am trying to make it so that it shows indefinitely.

I wish I could edit the theme.js file directly, because it would be very simple. There is a function called popdown that has a setTimeout of 5 seconds. The class "is-visible" that is being added simply changes the visibility property to none.

Does anyone know how I could change this using JavaScript or CSS running through Google Optimize?

Here is the JavaScript/jQuery from the theme.js file that defines the method I’m trying to change.

Product.prototype = _.assignIn({}, Product.prototype, {
    init: function () {
      theme.mediaInstances[this.id] = new theme.Media(this.container);
      theme.mediaInstances[this.id].init();
    },
    initAdd: function () {
      var $drawer = $(this.selectors.addDrawerWrapper),
        source = $(this.selectors.addDrawerTemplate).html(),
        template = Handlebars.compile(source),
        globalTimer;

      $("[data-add-to-cart]").on("click", function (e) {
        var isFocusEnabled = $("body").hasClass("focus-enabled");
        if (isFocusEnabled) {
          return;
        }
        e.preventDefault();
        var form = $(this).closest("form"),
          form_serialized = form.serializeArray();
        if (form.find('[type="file"]').length) {
          return;
        }
        var form_object = {};
        $.map(form_serialized, function (val, i) {
          form_object[val.name] = val.value;
        });
        ajaxAddItem(form_object);
      });
      var ajaxAddItem = function (data) {
        $.ajax({
          type: "POST",
          url: "/cart/add.js",
          dataType: "json",
          data: data,
          error: addError,
          success: addSuccess,
          complete: updateHeaderTotal,
        });
      };
      var updateHeaderTotal = function () {
        $.getJSON("/cart.js").done(function (cart) {
          var newTotal = slate.Currency.formatMoney(
            cart.total_price,
            theme.moneyFormat
          );
          $(".cartCost")
            .html("(<span class='money'>" + newTotal + "</span>)")
            .removeClass("hidden-count");
        });
      };
      var addError = function (object, status) {
        var errors =
          '<div class="errors">' + object.responseJSON.description + "</div>";
        $drawer.empty();
        $drawer.append(errors);
        $drawer.addClass("has-errors is-visible");
        popdown();
      };
      var addSuccess = function (product) {
        productObject = {
          product_title: product.product_title,
          product_image: product.image,
          variant:
            product.variant_title == "Default Title"
              ? false
              : product.variant_title,
          quantity: product.quantity,
          price: slate.Currency.formatMoney(product.price, theme.moneyFormat),
        };
        $drawer.empty();
        $drawer.append(template(productObject));

        // Popover should be just below header
        var topPosition =
          $(".site-header").outerHeight() + $(".info-bar").outerHeight();
        $drawer.attr("style", "");

        // If it is sticky, just put it at the header height with position: fixed
        if ($(".header__wrapper").hasClass("header--sticky")) {
          var topPosition = $(".site-header ").outerHeight();
          $drawer.css("top", topPosition);
        } else if ($(window).scrollTop() > topPosition) {
          // header is not visible pin to top
          $drawer.css("top", 0);
          $drawer.css("z-index", "2000");
        } else {
          // otherwise positon: absolute below header
          // or at top if scrolled below header
          topPosition = Math.max($(window).scrollTop(), topPosition);
          $drawer.css("position", "absolute");
          $drawer.css("top", topPosition);
        }

        $drawer.addClass("is-visible");
        popdown();
      };
      var popdown = function () {
        clearTimeout(globalTimer);
        globalTimer = setTimeout(function () {
          $drawer.removeClass("is-visible").removeClass("has-errors");
        }, 5000);
      };
      $drawer.on("click", ".close", function () {
        $drawer.removeClass("is-visible").removeClass("has-errors");
      });
    }

I’ve tried changing the CSS to "visible", but it never shows. I tried changing it through added CSS as well as changing the visibility property through JS. In the dev tools on Chrome, the visibility for the object shows "visible" in the computed styles, but it’s not working.

I’ve also tried changing the "initAdd" method within the Product class that has the "popdown" function in it. But I think there’s a different instance of the Product class that’s being utilized that I can’t seem to get access to. I’ve also tried looking through the eventListeners on the add to cart button.

I haven’t had success with anything so far. I’m open to trying anything. It’s such a small thing that I thought would be so simple but it’s been such a pain.

2

Answers


  1. Chosen as BEST ANSWER

    I ended up solving this by using a mutation observer. I couldn't figure out how to change the method in the Product class, so I used a mutation observer to watch for when the "is-visible" class was removed and immediately add it back. It's not ideal but it works just enough to solve my problem.

      const element = document.getElementById("CartDrawerWrapper--product");
      const addToCartButton = document.getElementById("AddToCart-product");
    
      let observerEnabled = true;
    
      addToCartButton.addEventListener("click", () => {
        observerEnabled = true;
      });
    
      const observer = new MutationObserver(function (mutationsList) {
        if (observerEnabled) {
          for (let mutation of mutationsList) {
            if (
              mutation.type === "attributes" &&
              mutation.attributeName === "class"
            ) {
              const classList = mutation.target.classList;
    
              if (!classList.contains("is-visible")) {
                classList.add("is-visible");
    
                const exitButton = document.querySelector(
                  "#CartDrawerWrapper--product > span.close"
                );
                exitButton.addEventListener("click", function () {
                  observerEnabled = false;
                  classList.remove("is-visible");
                });
              }
            }
          }
        }
      });
    
      const observerConfig = { attributes: true, attributeFilter: ["class"] };
    
      observer.observe(element, observerConfig);
    }, 500);
    

  2. To make popup show indefinitely instead of disappearing after 5 seconds, Modify the popdown function in the JavaScript code.Remove the timeout and keep the popup visible until you close it.

        var popdown = function () {
      // Remove timeout function
      clearTimeout(globalTimer);
      // Comment out code that hideS popup
      // $drawer.removeClass("is-visible").removeClass("has-errors");
    };
    

    OR

    Modify popdown function to remove these classes instead of hiding the popup completely. The popup will still be rendered in the DOM but will not be visible due to the CSS rules associated with these classes BY Removing the classes "is-visible" and "has-errors",

    var popdown = function () {
      clearTimeout(globalTimer);
      $drawer.removeClass("is-visible").removeClass("has-errors");
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search