Buggy JS animation problem

https://codepen.io/smiller0727/pen/Poqvqdg

In the pen provided above, I have a div, div#main, with a descendant div, div#net.

div#net can move with left and right arrow keys so as long as there is focus to document.body.

This is made possible by adding a “keydown” event listener to the document to invoke function motion (which is a property of netInst which was initialized to a constructed object by function net) upon occurrence of said event.

2 problems:

1.) When I keep a left or right arrow key down, div#net moves left or right as it should however, after holding down for a second or two, div#net's rate of motion appears to double. I’m using setIntervals to style div#net by modifying its left css property by 5px per 1ms. Why does this happen, and how would I go about preventing its rate of motion from doubling?

2.) In order to stop div#net in place, I added two “keyup” event listeners to the document to invoke separate functions to clear each of the aforementioned intervals correspondingly. The problem is however, is that I had to add them respectively to functions moveLeft (which nests interval _setLeft) and moveRight (which nests interval _setRight), and this causes countless “keyup” event listeners to be added to the document which is not preferable. Here are both moveLeft and moveRight functions:

function moveLeft() { 
  let _setLeft = setInterval(function() { 
    // code that styles the `left` css
    // property of `div#net` 
  }, 1); 
  document.addEventListener("keyup", function() { 
    clearInterval(_setLeft); 
  });
}
function moveRight() { 
  let _setRight = setInterval(function() { 
    // code that styles the `left` css 
    // property of `div#net` 
  }, 1); 
  document.addEventListener("keyup", function() { 
    clearInterval(_setRight); 
  }); 
}

I’ve tried making _setLeft and _setRight global and un-nesting document.addEventListeners from both functions so that each “keyup” event need only be added once to the document however, this causes the motion of div#net to move very apparently buggy. Why does this happen, and if possible, how would I go about clearing both intervals by adding both said event listeners to the document once while preventing the buggy motion of div#net.

I’ve pasted the entire code below. You can also follow the codepen link above. Thanks for reading and for any input anyone would like to provide in advance.

<!-- HTML --> 
<body>
		<div id="main"></div>
</body>
/* CSS */

html, body { 
    width: calc(100% - 50px);
    height: calc(100% - 50px);
}
body { 
    display: flex;
    justify-content: center;
    align-items: center;
}
	
#main { 
    width: 90%; 
    height: 90%; 
    border: 1px solid rgb(0, 0, 0); 
    position: relative; 
} 
// JS 

let _css = function(objs, props) { 

	for(var i = 0; i < objs.length; i++) { 

		for(var prop in props) { 

			objs[i].style[prop] = props[prop]; 

		}

	}

}; 

let main = document.querySelector("#main"); 

function net(mcw, mch) { 

	this.display = "inline-block"; 
	this.width = 19; 
	this.height = 5.333;
	this.background = (function() { 

		let rSpect = function() { return Math.floor(Math.random() * 255); }; 

		return `rgba(${rSpect()}, ${rSpect()}, ${rSpect()}, ${Math.random()})`; 

	})();
	this.css_position = "absolute"; 
	this.grid_position = { 
		lPos: (mcw / 2) - (((mcw) * (this.width / 100)) / (2)), 
		tPos: ((mch) - ((mch) * (this.height / 100))) - ((mch) * (2 / 75)) 
	}; 

	this.motionPace = 5; 

	this.motion = function(e) { 

		function moveLeft() { 

			let _setLeft = setInterval(function() { 

				_css([Net], { 
					left: (netInst.grid_position.lPos -= netInst.motionPace) + "px" 
				});

				if(netInst.grid_position.lPos < 0) { 

					netInst.grid_position.lPos = 0; 
					_css([Net], { left: netInst.grid_position.lPos + "px" });

				} 

			}, 1); 

			document.addEventListener("keyup", function() { clearInterval(_setLeft); }); 

		}

		function moveRight() { 

			let _setRight = setInterval(function() { 

				_css([Net], { 
					left: (netInst.grid_position.lPos += netInst.motionPace) + "px" 
				}); 

				if(netInst.grid_position.lPos > (mcw) - ((mcw) * (netInst.width / 100))) { 

					netInst.grid_position.lPos = ((mcw) - ((mcw) * (netInst.width / 100)));
					_css([Net], { left: netInst.grid_position.lPos + "px" }); 

				} 

			}, 1); 

			document.addEventListener("keyup", function() { clearInterval(_setRight); }); 

		} 
					
		let _key = e.key; 
		switch(_key) { 

			case "ArrowLeft": 
				moveLeft(); 
				break; 

			case "ArrowRight": 
				moveRight(); 

		}

	}; 

	return this;

} 

function loader() { 

	this.netLoad = function(netObj) { 

		let n = document.createElement("DIV"); 
		n.setAttribute("id", "net"); 
		_css([n], { 
			display: netObj.display, 
			width: netObj.width + "%", 
			height: netObj.height + "%", 
			background: netObj.background, 
			position: netObj.css_position, 
			left: netObj.grid_position.lPos + "px", 
			top: netObj.grid_position.tPos + "px"
		}); 

		main.appendChild(n); 

		document.addEventListener("keydown", netObj.motion); 

	} 

	return this; 

}

const MAIN_WIDTH = main.clientWidth; 
const MAIN_HEIGHT = main.clientHeight; 

let netInst = new net(MAIN_WIDTH, MAIN_HEIGHT); 
let Loader = new loader(); 

Loader.netLoad(netInst); 

let Net = document.querySelector("#net");