I'm working on a jQuery plugin. The problem is that when I use it I can see a high CPU usage in task manager.
I think the problem is here:
$elementTSMask.on("mousemove", function(event){
if(isMouseDown && isLeftButton){
var toScroll;
if(endPosition != 0){
toScroll = scrolled + (event.pageY - startPosition);
}else{
toScroll = event.pageY - startPosition;
}
$elementToScroll.css("top", toScroll + "px");
}
});
The toScroll
variable is calculated every time the user moves the mouse, so the CSS property is continuous changing. What can I do?
(function($) {
$.fn.dragToScroll = function(options) {
if (!this.length) { return this; }
var opts = $.extend(true, {}, $.fn.dragToScroll.defaults, options);
var $elementToScroll;
var $elementTSMask;
var scrolled = 0;
var maxScroll = 0;
var startPosition = 0;
var endPosition = 0;
var isMouseDown = false;
var isLeftButton = false;
this.each(function() {
var $this = $(this);
$elementToScroll = $this.find('.element-to-scroll');
$elementTSMask = $this.find('.element-ts-mask');
maxScroll = parseInt($elementToScroll.height(),10) - parseInt($elementTSMask.height(),10);
console.log(maxScroll);
$elementTSMask.on("mousedown", function(event){
isMouseDown = true;
startPosition = event.pageY;
if(event.which == 1){
isLeftButton = true;
}else{
isLeftButton = false;
}
});
$elementTSMask.on("mousemove", function(event){
if(isMouseDown && isLeftButton){
var toScroll;
if(endPosition != 0){
toScroll = scrolled + (event.pageY - startPosition);
}else{
toScroll = event.pageY - startPosition;
}
$elementToScroll.css("top", toScroll + "px");
}
});
$elementTSMask.on("mouseup mouseleave", function(event){
console.log(scrolled);
endPosition = event.pageY;
scrolled += endPosition - startPosition;
isMouseDown = false;
isLeftButton = false;
if(scrolled > 0 && Math.abs(scrolled) < maxScroll){
$elementToScroll.animate({"top": "0px"}, function(){
scrolled = 0;
});
}else if(Math.abs(scrolled) >= maxScroll){
$elementToScroll.animate({"top": "-" + maxScroll + "px"}, function(){
scrolled = -maxScroll;
});
}
});
var mousedownTimeout, startP = 0, endP = 1;
$this.on({
mousemove: function(event){
endP = event.pageY;
clearTimeout(mousedownTimeout);
}, mousedown: function(event){
if(event.which == 1){
startP = event.pageY;
mousedownTimeout = setTimeout(function() {
if(endP == startP){
$elementTSMask.fadeIn();
}
}, 400);
}
}, mouseleave: function(event){
clearTimeout(mousedownTimeout);
$elementTSMask.fadeOut();
}
});
});
return this;
};
$.fn.dragToScroll.defaults = {
defaultOne: true,
defaultTwo: false,
defaultThree: 'yay!'
};
})(jQuery);
*{
margin:0;
padding:0;
}
html,body {
height: 100%;
}
#container{
width:400px;
height:100%;
position:relative;
display: block;
left:0;
background-color:black;
overflow: hidden;
}
.element-to-scroll{
width:100%;
height:800px;
position:relative;
display: block;
background: green;
}
.element-ts-mask{
position: absolute;
top:0;
left:0;
width:100%;
height:100%;
display: none;
background:rgba(255,0,0,0.3);
cursor:all-scroll;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="dragToScroll.js"></script>
<script type="text/javascript">
jQuery(document).ready(function($) {
$('.gesture-scroll').dragToScroll();
});
</script>
</head>
<body>
<div id="container" class="gesture-scroll">
<div class="element-to-scroll" style="z-index:1;">
<div style="background:yellow;position:absolute;bottom:0;left:0;">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iusto ullam minima, veniam, maiores molestiae assumenda pariatur corrupti voluptatum id ea commodi aperiam dignissimos fuga, exercitationem illo eius praesentium suscipit. Velit.
</div>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quis, asperiores doloribus cum laudantium voluptatum, ullam dicta tempora nulla culpa, placeat et nobis voluptatem harum ipsa est. Deserunt dolor, consequuntur ut!
</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quis, asperiores doloribus cum laudantium voluptatum, ullam dicta tempora nulla culpa, placeat et nobis voluptatem harum ipsa est. Deserunt dolor, consequuntur ut!
</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quis, asperiores doloribus cum laudantium voluptatum, ullam dicta tempora nulla culpa, placeat et nobis voluptatem harum ipsa est. Deserunt dolor, consequuntur ut!
</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quis, asperiores doloribus cum laudantium voluptatum, ullam dicta tempora nulla culpa, placeat et nobis voluptatem harum ipsa est. Deserunt dolor, consequuntur ut!
</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quis, asperiores doloribus cum laudantium voluptatum, ullam dicta tempora nulla culpa, placeat et nobis voluptatem harum ipsa est. Deserunt dolor, consequuntur ut!
</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quis, asperiores doloribus cum laudantium voluptatum, ullam dicta tempora nulla culpa, placeat et nobis voluptatem harum ipsa est. Deserunt dolor, consequuntur ut!
</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quis, asperiores doloribus cum laudantium voluptatum, ullam dicta tempora nulla culpa, placeat et nobis voluptatem harum ipsa est. Deserunt dolor, consequuntur ut!
</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quis, asperiores doloribus cum laudantium voluptatum, ullam dicta tempora nulla culpa, placeat et nobis voluptatem harum ipsa est. Deserunt dolor, consequuntur ut!
</p>
</div>
<div class="element-ts-mask" style="z-index:2;"></div>
</div>
</body>
</html>
Note: What you need to do is to press the mouse button for about 1 second and then you will see some red over the green area. After that you need to release the mouse button and then you should see that the cursor changed. Now you can drag the content by holding the mouse button over the green area.
1 Answer 1
A short review,
Attaching handlers to mousemove will spike the CPU load, even if you do nothing in those handlers
NAME YOUR FUNCTIONS!@!!
function(event){
should be
function dragScollerMouseMove(event){
Otherwise people who want to profile your code (P.S. if you have CPU and other performance problems, you should use the Chrome Developer Tools to profile) will see a bunch of anonymous functions and feel miffed.
Uncaught ReferenceError: myTimeout is not defined
in your snippet.. \$\endgroup\$