this 없는 JS 오류

17378 단어 JavaScript

입문


JS에서 TODO 응용 프로그램을 만들고 이를 교재로 개작했다.교재의 규격에 따라 화살표 함수를 사용하면 일을 잘 할 수 없다.이게 뭐야?나는 단지 잠시 생각했을 뿐이다.

문제


문제는 TODO 컨텐트를 클릭하여 기존 작업을 편집하는 것입니다.지금까지의 function은 OK였지만, 아로 함수로서는 늘 이상하다.

코드


문제점을 분명히 하기 위해 그곳만 뽑아서 코드를 따로 썼다.'테스트'를 누르면 아로 함수를 실행하는 녀석,'테스트 2'라면 일반적인 함수를 실행한다.
테스트를 클릭하여 입력 양식의 커서를 제거합니다.
 「Uncaught TypeError: Cannot read property 'classList' of null」
의 오류.
 
test.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8"/>
    <link rel ="stylesheet" href="todo.css">
    <title>イベントハンドラテスト</title>
</head>
<body>
  <header>
    <h1>TODOテスト</h1>
  </header>
  <div class="container">
    <div class="todo-container">
      <ul class="todo-list">
        <li>
          <span class="todo-content1">テスト</span>
        </li>
        <li>
          <span class="todo-content2">テスト2</span>
        </li>
      </ul>
    </div>
  </div>
    <script src = "test.js"></script>
</body>
</html> 
const editTodo = (e) => {
  let itemToEdit = e.target;
  if(!itemToEdit.classList.contains('on')) {
    itemToEdit.classList.add('on');
    let contentBeforeEdit = itemToEdit.textContent;
    itemToEdit.innerHTML = '<input type="text" class="editbox1" value="'+contentBeforeEdit+'" />';
    const editContent1 = document.querySelector('.editbox1');

    const saveTodoContent  = (e) => {
        let itemToSave = e.target;
        itemToSave.parentNode.classList.remove('on');
        let txtvalue = itemToSave.value;
        if (txtvalue ==''){
         txtvalue = itemToSave.defaultValue;
        }
        itemToSave.parentNode.innerHTML = txtvalue;

    }
    editContent1.addEventListener('blur',saveTodoContent);
  }
}

function editTodo2(e) {
  if(!this.classList.contains("on")) {
    this.classList.add("on");
    let contentBeforeEdit = this.textContent
    this.innerHTML = '<input type="text" class="editbox2" value="'+contentBeforeEdit+'" />'
    const editContent2 = document.querySelector(".editbox2")

    let saveTodoContent = function(){
      this.parentNode.classList.remove('on')
      let txtvalue = this.value
      if (txtvalue ==""){
       txtvalue = this.defaultValue
      }
      this.parentNode.innerHTML = txtvalue

    }
    editContent2.addEventListener("blur",saveTodoContent)
  }
}

//Select DOM
const todoContent = document.querySelector('.todo-content1');
todoContent.addEventListener('click', editTodo);
const todoContent2 = document.querySelector('.todo-content2');
todoContent2.addEventListener('click', editTodo2);

문제를 추구하다


커서를 내리면 "classList가 비어 있습니다"오류가 발생합니다.바로 이 업종이다.
 const saveTodoContent  = (e) => {
//
      itemToSave.parentNode.classList.remove('on');
//
Chrome의 개발자 모드에서 조금씩 검증했습니다.그래서 커서를 내릴 때 실행된 이벤트saveTodoContent가 두 번 실행된 것을 발견했습니다.그리고 두 번째 실행 중 오류가 발생했습니다.왜?
아마 this 때문일 거예요.

원인


이 기능은 항목의 상태를 알아야 한다.즉, 임무가 현재 입력 모드인지 알고 싶습니다.코드에서,classlist에 이 class를 부여하거나 꺼내서 조작합니다.
지금까지 그 검측에서this를 사용했지만, 이번에 아로 함수를 개작한 일로this를 사용할 수 없게 되어 다른 기법으로 개작하였다.거기 안 좋아요.
여기야.
변경 전
function editTodo2(e) {
  if(!this.classList.contains("on")) {
// .. クリックときに編集モードでなければ以下を実行
수정 후
const editTodo = (e) => {
  let itemToEdit = e.target;
  if(!itemToEdit.classList.contains('on')) {
// .. クリックときに編集モードでなければ以下を実行

this/e.target


this와 e.target은 뭐가 달라요?this는 장면에 따라 다양한 병세가 바뀔 수 있습니다. 여기서 아래의 보도를 참고하면'호출 함수의 원래 대상'입니다.
e.target은 클릭할 때의 물체입니다.텍스트 문자 또는 입력 양식
this의 내용과 작업이 편집 모드인지 여부도 변하지 않았습니다.하지만 e.target의 내용이 바뀌었다.콘솔을 시도해 보세요.로그로 읽어주세요.
const editTodo = (e) => {
  let itemToEdit = e.target;
  console.log(e.target);
  console.log(this);

//


function editTodo2(e) {
  console.log(e.target);
  console.log(this);
 

위의 네 줄은 아로 함수다.다음은 지금까지의 함수다.확실히 좀 달라요.

왜 그래?


아로 함수는 이벤트를 실행하는 조건을 증가시켰다.
const editTodo = (e) => {
  let itemToEdit = e.target;
  if(!itemToEdit.classList.contains('todo-content1')){
    return;
  }
  if(!itemToEdit.classList.contains('on')) {
//....

이렇게 하면 문제가 해결된다.

끝내다


문장이 정리되지 않아 이것을 썼다.그래도 어딘가에 두지 않으면 나중에 곤란해진다.
그렇게 지도 모른다, 아마, 아마...
 

좋은 웹페이지 즐겨찾기