Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

poor performance of activation/deactivation methods #19

Closed
tylersticka opened this issue Aug 8, 2013 · 5 comments
Closed

poor performance of activation/deactivation methods #19

tylersticka opened this issue Aug 8, 2013 · 5 comments

Comments

@tylersticka
Copy link
Member

Since fixing #18, instances of the menu being visible momentarily when the body class has been added have increased. Need to investigate ways of improving performance.

@ghost ghost assigned tylersticka Aug 8, 2013
@mattg
Copy link
Contributor

mattg commented Aug 8, 2013

I think I know why. Not sure what the best fix is yet, though.

On Aug 8, 2013, at 3:58 PM, Tyler Sticka <[email protected]mailto:[email protected]> wrote:

Since fixing #18#18, instances of the menu being visible momentarily when the body class has been added have increased. Need to investigate ways of improving performance.


Reply to this email directly or view it on GitHubhttps://github.com//issues/19.

@tylersticka
Copy link
Member Author

I solved the issue with a bit of a stopgap solution in a client project today, just wanted to open an issue to remind myself to put it into the plugin proper when I get a chance.

@mattg
Copy link
Contributor

mattg commented Aug 9, 2013

Is it caused by the short time between the plugin being initialized and on() being fired?

On Aug 8, 2013, at 4:27 PM, Tyler Sticka <[email protected]mailto:[email protected]> wrote:

I solved the issue with a bit of a stopgap solution in a client project today, just wanted to open an issue to remind myself to put it into the plugin proper when I get a chance.


Reply to this email directly or view it on GitHubhttps://github.com//issues/19#issuecomment-22365889.

@tylersticka
Copy link
Member Author

Hmm, this may be less obvious than I first thought it would be. I'm attaching the kludgy version that I had to use to meet a deadline in a production environment... this doesn't suffer from the problem and #18 is still fixed. I can't figure out what exactly about this isn't resulting in the flash of a partially-styled menu.

// Generated by CoffeeScript 1.6.2
(function() {
  var $;

  $ = typeof jQuery !== "undefined" && jQuery !== null ? jQuery : Zepto;

  $.offCanvasMenu = function(options) {
    var actions, baseCSS, body, container, cssSupport, head, inner, innerWrapper, menu, menuLeft, outer, outerWrapper, settings, transEndEventName, transformPosition, transformPrefix, trigger;

    settings = {
      direction: "left",
      coverage: "70%",
      menu: "#menu",
      trigger: "#menu-trigger",
      duration: 250,
      container: 'body',
      classes: {
        inner: 'inner-wrapper',
        outer: 'outer-wrapper',
        container: 'off-canvas-menu',
        open: 'menu-open'
      },
      transEndEventNames: {
        'WebkitTransition': 'webkitTransitionEnd',
        'MozTransition': 'transitionend',
        'OTransition': 'oTransitionEnd otransitionend',
        'msTransition': 'MSTransitionEnd',
        'transition': 'transitionend'
      }
    };
    settings = $.extend(settings, options);
    cssSupport = (typeof Zepto === "undefined" || Zepto === null) && (typeof Modernizr !== "undefined" && Modernizr !== null) && Modernizr.csstransforms && Modernizr.csstransitions;
    if (cssSupport) {
      transformPrefix = Modernizr.prefixed('transform').replace(/([A-Z])/g, function(str, m1) {
        return '-' + m1.toLowerCase();
      }).replace(/^ms-/, '-ms-');
      transEndEventName = settings.transEndEventNames[Modernizr.prefixed('transition')];
    }
    head = $('head');
    body = $(settings.container);
    trigger = $(settings.trigger);
    menu = $(settings.menu);
    transformPosition = settings.direction === "left" ? settings.coverage : "-" + settings.coverage;
    menuLeft = settings.direction === "left" ? "-" + settings.coverage : "100%";
    container = settings.container + "." + settings.classes.container;
    inner = container + " ." + settings.classes.inner;
    outer = container + " ." + settings.classes.outer;
    baseCSS = "<style>  " + outer + " {      left: 0;      overflow-x: hidden;      position: absolute;      top: 0;      width: 100%;    }    " + inner + " {      position: relative;    }    " + container + " " + settings.menu + " {      height  : 0;      left    : " + menuLeft + ";      margin  : 0;      overflow: hidden;      position: absolute;      top     : 0;      width   : " + settings.coverage + ";    }  </style>";
    head.append(baseCSS);
    // body.children(':not(script)').wrapAll('<div class="' + settings.classes.outer + '"/>');
    // outerWrapper = $("." + settings.classes.outer);
    // outerWrapper.wrapInner('<div class="' + settings.classes.inner + '"/>');
    // innerWrapper = $("." + settings.classes.inner);
    actions = {
      on: function() {
        if (window.location.hash === settings.menu) {
          window.location.hash = '';
        }
        trigger.find("a").add(trigger).each(function() {
          $(this).data("href", $(this).attr("href"));
          return $(this).attr("href", "");
        });
        body.children(':not(script)').wrapAll('<div class="' + settings.classes.outer + '"/>');
        outerWrapper = $("." + settings.classes.outer);
        outerWrapper.wrapInner('<div class="' + settings.classes.inner + '"/>');
        innerWrapper = $("." + settings.classes.inner);
        body.addClass(settings.classes.container);
        return trigger.on("touchstart mousedown", function(e) {
          e.preventDefault();
          if (cssSupport || (typeof Zepto !== "undefined" && Zepto !== null)) {
            actions.pauseClicks();
          }
          return actions.toggle();
        }).on("click", function(e) {
          return e.preventDefault();
        });
      },
      off: function() {
        if (typeof outerWrapper !== 'undefined' && outerWrapper !== null) {
          trigger.find("a").add(trigger).each(function() {
            $(this).attr("href", $(this).data("href"));
            return $(this).data("href", "");
          });
          actions.hide();
          body.removeClass(settings.classes.container);
          trigger.off("touchstart mousedown click");
          if (cssSupport) {
            innerWrapper.off(transEndEventName);
          }
          actions.clearHeights();
          innerWrapper.unwrap();
          innerWrapper.children().unwrap();
        }
      },
      toggle: function() {
        if (!$(container).length) {
          return false;
        }
        if (body.hasClass(settings.classes.open) === true) {
          return actions.hide();
        } else {
          return actions.show();
        }
      },
      show: function() {
        if (!$(container).length) {
          return false;
        }
        actions.setHeights();
        actions.animate(transformPosition);
        $(window).on("resize", actions.setHeights);
        return body.addClass(settings.classes.open);
      },
      hide: function() {
        if (!$(container).length) {
          return false;
        }
        actions.animate(0);
        $(window).off("resize");
        return body.removeClass(settings.classes.open);
      },
      animate: function(position) {
        var animationCallback;

        if (!position) {
          animationCallback = actions.clearHeights;
        }
        if (typeof Zepto !== "undefined" && Zepto !== null) {
          return innerWrapper.animate({
            "translateX": position
          }, settings.duration, "ease", animationCallback);
        } else if (cssSupport) {
          innerWrapper.css({
            transition: transformPrefix + " " + settings.duration + "ms ease",
            transform: "translateX(" + position + ")"
          });
          if (!position) {
            return innerWrapper.on(transEndEventName, function() {
              actions.clearHeights();
              return innerWrapper.off(transEndEventName);
            });
          }
        } else {
          return innerWrapper.animate({
            left: position
          }, settings.duration, animationCallback);
        }
      },
      setHeights: function() {
        var height;

        actions.clearHeights();
        height = Math.max($(window).height(), $(document).height(), body.prop('scrollHeight'));
        outerWrapper.css("height", height);
        if (height > innerWrapper.height()) {
          innerWrapper.css("height", height);
        }
        if (height > menu.height()) {
          return menu.css("height", height);
        }
      },
      clearHeights: function() {
        return outerWrapper.add(innerWrapper).add(menu).css("height", "");
      },
      pauseClicks: function() {
        body.on("click", function(e) {
          e.preventDefault();
          return e.stopPropagation();
        });
        return setTimeout((function() {
          return body.off("click");
        }), settings.duration * 2);
      }
    };
    return {
      on: actions.on,
      off: actions.off,
      toggle: actions.toggle,
      show: actions.show,
      hide: actions.hide
    };
  };

}).call(this);

@mattpage
Copy link
Contributor

this is fixed in this commit: 2b6b23e

this wasn't really a perf issue. The fix to this #17 removed the initial height of the menu. This meant that when the menu was added to the page it flashed on the screen for a brief second.

I have reverted the fix for #17 and I am reopening the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants