From the Extract a Method article, steps 1 and 2 have been done where you move some of the code into a function.
There is a good solution for the prevX and prevY at the end of the code. It’s a resize function, so it should only resize. It shouldn’t have anything to do with the event object, for that is mixing in the role of an event handler too.
Let’s separate out the event handler and pass in to the resize function only the information that it needs to know.
First, separating out the event handler:
// window.addEventListener("mousemove", resize);
window.addEventListener("mousemove", resizeHandler);
...
function resizeHandler(e) {
resize(e);
}
function resize(e) {
...
function mouseup() {
// window.removeEventListener("mousemove", resize);
window.removeEventListener("mousemove", resizeHandler);
Then in the handler, we get information that we need from the event object, and pass it to the resize function.
function resizeHandler(e) {
const clientX = e.clientX;
const clientY = e.clientY;
// resize(e);
resize(e, clientX, clientY, prevX, prevY);
}
// function resize(e) {
function resize(e, clientX, clientY, prevX, prevY) {
const rect = el.getBoundingClientRect();
if (currentResizer.classList.contains("se")) {
// el.style.width = rect.width - (prevX - e.clientX) + "px";
el.style.width = rect.width - (prevX - clientX) + "px";
// el.style.height = rect.height - (prevY - e.clientY) + "px";
el.style.height = rect.height - (prevY - clientY) + "px";
We can now remove e from the resize function, and in fact we’ll replace it with el instead, and also add currentResizer.
function resizeHandler(e) {
const clientX = e.clientX;
const clientY = e.clientY;
// resize(e, clientX, clientY, prevX, prevY);
resize(el, clientX, clientY, prevX, prevY, currentResizer);
}
// function resize(e, clientX, clientY, prevX, prevY) {
function resize(el, clientX, clientY, prevX, prevY, currentResizer) {
Where does that el variable in the handler come from? That’s not a concern for now but we can come to that later.
The resize function also updates prevX and prevY at the end of the function. That’s a bad thing to do because it results in the function doing resizing and updating scoped variables. When the explaination of a function includes an “and”, that usually means that separation is required.
In this case the prevX and prevY statements can be easily moved in to the resizeHandler function.
function resizeHandler(e) {
const clientX = e.clientX;
const clientY = e.clientY;
resize(el, clientX, clientY, currentResizer);
prevX = x.clientX;
prevY = x.clientY;
}
function resize(el, clientX, clientY, currentResizer) {
...
// prevX = e.clientX;
// prevY = e.clientY;
}
Before the resize function was serving double-purpose as event handler and elment resizer. Now those duties have been separated and teased out, and the resize function can now be easily moved to somewhere else. I’ll move it up above the resizers query selector.
function resize(el, clientX, clientY, currentResizer) {
...
}
const resizers = document.querySelectorAll(".resizer");
let currentResizer;
That’s the resizer function taken care of. By making small steps on each occasion, it’s easy to ensure that you don’t break anything, so that the code remains working exactly as it was before.
The updated code is found at https://jsfiddle.net/b85a1Lps/
It has also prompted doing similar things with the rest of the code, where we separate out the event handler function from the function the does the work, deal with closure variables, and make other improvements to the code.