Decrease the Elements feature in the DOM applied in the Jquery that generates Ripple

Asked

Viewed 141 times

0

Well I am with the effect of Ripple almost ready but I notice some bugs mainly to delete the effect after applying but it does not affect the execution but rather the Performance of the Browser, increasing the use of RAM and I need to reduce this cost and I am using the jsHint to guide me in the codes and correct them. I tested the code in these Navagedores:

  • Safari (Windows) 5.1.7;
  • Google Chrome (Blink) 49.0.2623.112 m;
  • Chromium (Webkit) 26.0.1410.12;
  • Firefox 47.0a2;
  • Microsoft Edge 20.10240.16384.0;
  • Internet Explorer 11

Follows the Code:

(function($) {

  function App() {
    $(document).ready(function() { // Initialize app when document is ready
      // Init events

      // Init actions
      $('.ripple').materialripple();
    });
  }

  document.addEventListener('touchmove', function(e) {
    e.preventDefault();
  }, false);
  document.addEventListener('DOMContentLoaded', function() {
    setTimeout(App(), 200);
  }, false);

  var mobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent);
  var startClick = (mobile ? "touchstart" : "mousedown"),
    moveClick = (mobile ? "touchmove" : "mousemove"),
    stopClick = (mobile ? "touchend" : "mouseup");

  //Edit: Adicionei esta variavel pois touch não tava entregando os valores clientX e clientY
  var getPointerEvent = function(event) {
    return event.originalEvent.targetTouches ? event.originalEvent.targetTouches[0] : event;
  };


  /* APP
  –––––––––––––––––––––––––––––––––––––––––––––––––– */

  $.fn.materialripple = function(options) {
    var defaults = {
      rippleClass: 'ripple-wrapper'
    };
    $.extend(defaults, options);

    var newRippleElement = null,
      xPos = null,
      yPos = null,
      elementWidth = null,
      elementHeight = null,
      d = null,
      rippleX = null,
      rippleY = null,
      rplDelTimer = null;

    function addRippleElement(element, e) {
      $(element).append('<span class="added ' + defaults.rippleClass + '"></span>');
      newRippleElement = $(element).find('.added');
      newRippleElement.removeClass('added');
      newRippleElement.removeClass('end-ripple');

      // get Mouse/Touch Position
      var pointer = getPointerEvent(e);

      xPos = pointer.clientX;
      yPos = pointer.clientY;

      // for each ripple element, set sizes
      elementWidth = $(element).outerWidth();
      elementHeight = $(element).outerHeight();
      d = Math.max(elementWidth, elementHeight);
      newRippleElement.css({
        'width': d,
        'height': d
      });

      rippleX = xPos - $(element).offset().left - d / 2 + $(window).scrollLeft();
      rippleY = yPos - $(element).offset().top - d / 2 + $(window).scrollTop();

      // Position the Ripple Element
      newRippleElement.css('top', rippleY + 'px').css('left', rippleX + 'px').addClass('animated-ripple');

      // Reset ripple deletion timer
      clearTimeout(rplDelTimer);
    }

    // Delete ripple element one second after last click
    function delRipple() {
      rplDelTimer = setTimeout(function() {
        $('body').on('transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd', '.' + defaults.rippleClass, function() {
          $(this).remove();
        });
      }, 2000);
    }

    // add Ripple-Wrapper to all Elements
    $(this).addClass('has-ripple');

    // Let it ripple on click
    $(this).bind(startClick, function(e) {
      addRippleElement(this, e);
    });

    $(this).bind(stopClick, function() {
      $('.' + defaults.rippleClass).addClass('opacityOff');
      delRipple();
    });
  };

})(jQuery); // pass in (jQuery):
/* BUTTON
-------------------------------------------------- */

* {
  background-repeat: no-repeat;
  margin: 0;
  padding: 0;
  -webkit-transition: 0.25s ease-in-out;
  -moz-transition: 0.25s ease-in-out;
  -ms-transition: 0.25s ease-in-out;
  -o-transition: 0.25s ease-in-out;
  transition: 0.25s ease-in-out;
}
button,
*[role="button"],
input[type="button"],
input[type="submit"],
.btn {
  display: inline-block;
  cursor: pointer;
  min-width: 7em;
  height: 40px;
  text-align: center;
  text-transform: uppercase;
  white-space: nowrap;
  background-image: none;
  border: 1px solid transparent;
  padding: 7px;
  margin: 0;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  vertical-align: middle;
  -webkit-border-radius: 2px;
  -moz-border-radius: 2px;
  -ms-border-radius: 2px;
  -o-border-radius: 2px;
  border-radius: 2px;
  -webkit-user-select: none;
  /* Chrome all / Safari all */
  -moz-user-select: none;
  /* Firefox all */
  -ms-user-select: none;
  /* IE 10+ */
  -o-user-select: none;
  /* Opera 27+ */
  user-select: none;
  /* Likely future */
  -webkit-transform: translateZ(0);
  -moz-transform: translateZ(0);
  -ms-transform: translateZ(0);
  -o-transform: translateZ(0);
  transform: translateZ(0);
}
*[role="button"].raised,
input[type="button"].raised,
input[type="submit"].raised,
button.raised,
.btn.raised {
  color: white;
  -webkit-box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.156863), 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2);
  -moz-box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.156863), 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2);
  -ms-box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.156863), 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2);
  -o-box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.156863), 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.156863), 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2);
}
*[role="button"].raised:active,
input[type="button"].raised:active,
input[type="submit"].raised:active,
button.raised:active,
.btn.raised:active {
  color: white;
  -webkit-box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.156863), 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12), 0 5px 5px -3px rgba(0, 0, 0, 0.4);
  -moz-box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.156863), 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12), 0 5px 5px -3px rgba(0, 0, 0, 0.4);
  -ms-box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.156863), 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12), 0 5px 5px -3px rgba(0, 0, 0, 0.4);
  -o-box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.156863), 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12), 0 5px 5px -3px rgba(0, 0, 0, 0.4);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.156863), 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12), 0 5px 5px -3px rgba(0, 0, 0, 0.4);
}
*[role="button"].raised.light_blue,
input[type="button"].raised.light_blue,
input[type="submit"].raised.light_blue,
button.raised.light_blue,
.btn.raised.light_blue,
*[role="button"].raised:active.light_blue,
input[type="button"].raised:active.light_blue,
input[type="submit"].raised:active.light_blue,
button.raised:active.light_blue,
.btn.raised:active.light_blue {
  background-color: #03a9f4;
}
/* ACTION ANIMATE
–––––––––––––––––––––––––––––––––––––––––––––––––– */

.ripple-wrapper.opacityOff {
  -webkit-opacity: 0;
  -moz-opacity: 0;
  -ms-opacity: 0;
  -o-opacity: 0;
  opacity: 0;
}
/* RIPPLE
–––––––––––––––––––––––––––––––––––––––––––––––––– */

.ripple-wrapper {
  display: block;
  position: absolute;
  background: #FFFFFF;
  border-radius: 50%;
  -ms-touch-action: none;
  /* disable ms pointers */
  -webkit-opacity: 0.4;
  -moz-opacity: 0.4;
  -ms-opacity: 0.4;
  -o-opacity: 0.4;
  opacity: 0.4;
  -webkit-transform: scale(0);
  -moz-transform: scale(0);
  -ms-transform: scale(0);
  -o-transform: scale(0);
  transform: scale(0);
  -webkit-transition: all 1.3s ease-out, top 0s, left 0s, width 0s, height 0s;
  -moz-transition: all 1.3s ease-out, top 0s, left 0s, width 0s, height 0s;
  -ms-transition: all 1.3s ease-out, top 0s, left 0s, width 0s, height 0s;
  -o-transition: all 1.3s ease-out, top 0s, left 0s, width 0s, height 0s;
  transition: all 1.3s ease-out, top 0s, left 0s, width 0s, height 0s;
}
.ripple-wrapper * {
  pointer-events: none;
}
.ripple-wrapper.animated-ripple {
  -webkit-transform: scale(2.0);
  -moz-transform: scale(2.0);
  -ms-transform: scale(2.0);
  -o-transform: scale(2.0);
  transform: scale(2.0);
}
.has-ripple {
  position: relative;
  overflow: hidden;
  outline: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  -o-user-select: none;
  user-select: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<button class="raised light_blue ripple">Button</button>

1 answer

2


you can do the same effect only with CSS, maybe solve your memory problem.

var riples = document.querySelectorAll(".riple");

function onStep1End(event) {
  event.target.removeEventListener("transitionend", onStep1End);
  window.setTimeout(function () {
    event.target.classList.add("step2");
    event.target.addEventListener("transitionend", onStep2End);
  }, 0);

};

function onStep2End(event) {
  event.target.removeEventListener("transitionend", onStep2End);  
  window.setTimeout(function () {
    event.target.parentNode.removeChild(event.target);
  }, 0);
};


[].forEach.call(riples, function (riple, indice) {
  riple.addEventListener("click", function (event) {
    var effect = document.createElement("div");
    effect.classList.add("effect");
    effect.style.top = event.clientY + "px";
    effect.style.bottom = "calc(100% - " + event.clientY + "px)";
    effect.style.left = event.clientX + "px";
    effect.style.right = "calc(100% - " + event.clientX + "px)";
    window.setTimeout(function () {
      effect.classList.add("step1");
      effect.addEventListener("transitionend", onStep1End);
    }, 25);

    riple.appendChild(effect);
  });
})
.riple {
  position: relative;
  float: left;
  overflow: hidden;
}

.riple .effect {
  position: absolute;
  pointer-events: none;
  background-color: rgba(255, 255, 255, 0.7);
  border-radius: 50%;
  transition-property: all;
  transition-timing-function: linear;
}

.riple .step1 {
  top: -50% !important; 
  right: -50% !important; 
  bottom: -50% !important; 
  left: -50% !important;
  transition-duration: 0.7s;
}

.riple .step2 {
  background-color: rgba(255, 255, 255, 0);
  transition-duration: 0.3s;
}

button {
  height: 40px;
  background-color: blue;
  color: white;
  border: 0px none transparent;
  box-shadow: 0px 0px 10px blue;
}
<div class="riple">
  <button>Meu Button</button>
</div>

  • The idea is good but I lose the support of Internet Explorer because the @keyframes only works well in IE 10, my problem is when I run several times and to delete does not work properly, sometimes gives a bug in the first one and the others it deletes and more I run and Jquery does not delete increases the RAM to be processed in the browser.

  • @iLeonardoCarvalho, updated the answer to use transition progressively rather than progressively animation, this eliminates the need for @keyframes.

  • Thanks for the idea I just didn’t get to perform the second .step2, in this case is for multiple clicks?

  • 1

    @iLeonardoCarvalho do you remember that my animation was divided into two parts, one up to 70% and the other into the last 30%? the step2 is to reproduce this second part.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.