드래그 위치 유지

YEONGHUN KO·2021년 11월 15일
0

JAVASCRIPT - TO DO LIST

목록 보기
14/15
post-thumbnail

1. jquery 코드 옮기기

드래그 기능을 구현했었는데 그 위치가 새로고침되어도 유지가 되는 기능은 구현하지 못했었다.(어쩌면 못한게 아니라 안한건지도..) 그러다고 우연히 드래그위치가 유지되는 기능을 구현한 다른사람의 코드를 보게되었고 적용했다.

우선 html에 있는 jquery 코드가 눈에 거슬렸다. 따라서 todoo.js로 이동시켜주었다.

function dragEnable() {
  var script = document.createElement("script");
  script.innerHTML = `
  $(function () {
    $('#js_pending').sortable({
      axis: 'y',
      revert: true,
      scroll: true,
      placeholder: 'sortable-placeholder',
      start: function (event, ui) {
        ui.placeholder.html(ui.item.html());
      },
    });
    $('#js_finished').sortable({
      axis: 'y',
      revert: true,
      scroll: true,
      placeholder: 'sortable-placeholder',
      start: function (event, ui) {
        ui.placeholder.html(ui.item.html());
      },
    });
  });
  `;
  document.getElementsByTagName("head")[0].appendChild(script);
}
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <link rel="stylesheet" href="index.css" />
  <title>JUST F**KING DO IT</title>
</head>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<body>
  ...
</body>

jqeury 소스는 그대로 남겨두고 script 코드만 옮겼다. 이제 드래그 위치를 유지하는 기능을 구현해보겠다.

2. 드래그 위치 기억

다른 사람의 코드를 보았는데, 사실 다 이해한건 아니다. 아니 20%정도밖에 이해못했다. 그러나 그 원리는 이해했다. 바로 드래그가 끝난 다음 localstorage에 저장되는 array를 수정하여 다시 저장한다는 것이다.

그래서, 생각해보았다. 로직은 이렇다.

1 지금 paint된 ul의 list를 array로 뽑아낸다음 각각의 리스트와 그에 해당하는 인덱스를 받아온다.

2 ul array를 순회하면서 list와 인덱스와 LS에 저장된 array에 있는 list와 인덱스를 비교한다.

3 비교해서 인덱스가 서로 다르면 지금 paint된 인덱스위치로 옮긴다.

4 예를들어서 A 라는 list가 3번째에 paint되어있는데 LS상에는 1번째라면 3번쨰에 있는 애를 지우고 첫번째에 옮기고 1번째에 있는 애를 지우고 3번째로 옮긴다.

그런데 이렇게 로직을 짜면 일일이 새로 굴러들어온 돌, 그리고 기존에 박혀있는 돌의 위치를 조정해줘야한다. 너무 복잡해질것같았다. 따라서 로직을 다시 짰다.

1 새로운 array를 만든다.

2 ul array를 순회하면서 list와 인덱스와 LS에 저장된 array에 있는 list와 인덱스를 비교한다.

3 순회하면서 해당 list와 array에 저장된 list가 같으면 그 list를 불러와서 새로운 array에 해당 list를 paint상의 인덱스위치에 저장한다.

4 새로운 array를 기존 array에 덮어씌운다음 LS에 저장한다.

이렇게 짜면 버그가 날 가능성도 줄어들고 코드도 깔끔해질것 같았다. 그리고 이 모든과정은 TO-DO-LIST가 종료되기 전에 딱 한 번 이뤄지면 좋다고 생각했다. 드래그 할때마다 이 과정이 일어나면 성능에 문제가 생길거라도 판단했기때문.(beforeunload 가 떠올랐다!!)

그럼 코드를 짜보자.

3. 구현하기!

function newArrayReturned(htmlList, arrayTask) {
  // 새로운 array를 만든다.
  let editedpendingTask = [];

  // ul array를 순회하면서 list의 인덱스와 LS에 저장된 array에 있는 list와 인덱스를 비교한다.
  htmlList.childNodes.forEach((child, childIdx) => {
    let childIden = child.id;
    arrayTask.map((pendingEle) => {
      // 순회하면서 해당 list와 array에 저장된 list가 같으면 그 list를 불러와서 새로운 array에 해당 list를 paint상의 인덱스위치에 저장한다.
      if (childIden === pendingEle.id) {
        editedpendingTask.splice(childIdx, 0, pendingEle);
      }
    });
  });
  return editedpendingTask;
}

function pendingListOrderModified(htmlList, arrayTask) {
  let editedpendingTask = newArrayReturned(htmlList, arrayTask);

  // 새로운 array를 기존 array에 덮어씌운다음 LS에 저장한다.
  pendingTask = editedpendingTask;
}

function finishedListOrderModified(htmlList, arrayTask) {
  let editedFinishedTask = newArrayReturned(htmlList, arrayTask);
  finishedTask = editedFinishedTask;
}

window.addEventListener("beforeunload", () => {
  pendingListOrderModified(pendingList, pendingTask);
  finishedListOrderModified(finishedList, finishedTask);
  saveState();
});

좋은 개발자가 되려면 항상 코드를 작성한뒤에 '더 성능면에서, 가독성면에서 개선할 방법은 없을까?' 를 끊임 없이 고민하고 의심해야한다. 그래서 pendingListOrderModified와 fisnishedListOrderModified 를 합칠 방법이 없을까를 고민했다. arrayTask = editedFinishedTask; 라고 하면 되지 않을까라고 생각했다. 그렇게 했는데 아무 반응이 없었다. parameter로 전달받은 것은 결국 가상으로 인식하는건가 싶었다.

일단 여기까지다! 끊임없이 개선해나가서 매우 기쁘다:))

profile
'과연 이게 최선일까?' 끊임없이 생각하기

0개의 댓글