简体   繁体   中英

How can I shorten the next repeated statement?

How can I shorten the next repeated statement? I want to show 4~7, 5~7, 6~7, 7 for case 1,2,3,4.

function selectTeeShotCount() {
    console.log(document.teeShotInfoForm.TeeCount);
    const radioTeeShot = document.teeShotInfoForm.TeeCount;
    let prev = null;
    for (const radioTeeShotElement of radioTeeShot) {
        radioTeeShotElement.addEventListener('change', event => {
            (prev) ? console.log(prev.value): null;
            if (this !== prev) {
                prev = this;
            }

            document.querySelector('#teeShotInfoForm > div:nth-child(3)').classList.remove('d-none');
            document.querySelector('#teeShotInfoForm > div:nth-child(4)').classList.remove('d-none');
            document.querySelector('#teeShotInfoForm > div:nth-child(5)').classList.remove('d-none');
            document.querySelector('#teeShotInfoForm > div:nth-child(6)').classList.remove('d-none');
            document.querySelector('#teeShotInfoForm > div:nth-child(7)').classList.remove('d-none');

            switch (parseInt(radioTeeShot.value)) {
                case 1:
                    document.querySelector('#teeShotInfoForm > div:nth-child(4)').classList.add('d-none');
                    document.querySelector('#teeShotInfoForm > div:nth-child(5)').classList.add('d-none');
                    document.querySelector('#teeShotInfoForm > div:nth-child(6)').classList.add('d-none');
                    document.querySelector('#teeShotInfoForm > div:nth-child(7)').classList.add('d-none');
                    break;
                case 2:
                    document.querySelector('#teeShotInfoForm > div:nth-child(5)').classList.add('d-none');
                    document.querySelector('#teeShotInfoForm > div:nth-child(6)').classList.add('d-none');
                    document.querySelector('#teeShotInfoForm > div:nth-child(7)').classList.add('d-none');
                    break;
                case 3:
                    document.querySelector('#teeShotInfoForm > div:nth-child(6)').classList.add('d-none');
                    document.querySelector('#teeShotInfoForm > div:nth-child(7)').classList.add('d-none');
                    break;
                case 4:
                    document.querySelector('#teeShotInfoForm > div:nth-child(7)').classList.add('d-none');
                    break;
            }
        });
    }
}

Instead of using a separate selector for each element, you can select each block of divs by modifying the syntax to

document.querySelectorAll("#teeShotInfoForm div:nth-child(YOUR_NUMBER)~div")

You can wrap the repeated functionality into a method.

eg

const remove = (...childs) => {
    for (const child in childs) {
        document.querySelector('#teeShotInfoForm > div:nth-child(' + child + ')').classList.remove('d-none');
    }
}

const add = (...childs) => {
    for (const child in childs) {
        document.querySelector('#teeShotInfoForm > div:nth-child(' + child + ')').classList.add('d-none');
    }
}

then use it.

eg

function selectTeeShotCount() {
    const radioTeeShot = document.teeShotInfoForm.TeeCount;
    let prev = null;
    for (const radioTeeShotElement of radioTeeShot) {
        radioTeeShotElement.addEventListener('change', event => {
            (prev) ? console.log(prev.value): null;
            if (this !== prev) {
                prev = this;
            }
            remove(3, 4, 5, 6, 7);
            switch (parseInt(radioTeeShot.value)) {
                case 1:
                    add(4, 5, 6, 7);
                    break;
                case 2:
                    add(5, 6, 7);
                    break;
                case 3:
                    add(6, 7);
                    break;
                case 4:
                    add(7);
                    break;
            }
        });
    }
}

Another Idea is to save querySelectors result in a variable, or an array like below ( which will prevent some extra unnecessary DOM selection as well )

function selectTeeShotCount() {
    console.log(document.teeShotInfoForm.TeeCount);
    const radioTeeShot = document.teeShotInfoForm.TeeCount;
    let prev = null;
    for (const radioTeeShotElement of radioTeeShot) {
        radioTeeShotElement.addEventListener('change', event => {
            (prev) ? console.log(prev.value): null;
            if (this !== prev) {
                prev = this;
            }
            const teeShotInfoFormChilds = [
                document.querySelector('#teeShotInfoForm > div:nth-child(3)'),
                document.querySelector('#teeShotInfoForm > div:nth-child(4)'),
                document.querySelector('#teeShotInfoForm > div:nth-child(5)'),
                document.querySelector('#teeShotInfoForm > div:nth-child(6)'),
                document.querySelector('#teeShotInfoForm > div:nth-child(7)')
            ];

            teeShotInfoFormChilds.forEach(el => el.classList.remove('d-none'));
            
            switch (parseInt(radioTeeShot.value)) {
                case 1:
                    teeShotInfoFormChilds.slice(1).forEach(el => el.classList.add('d-none'));
                    break;
                case 2:
                    teeShotInfoFormChilds.slice(2).forEach(el => el.classList.add('d-none'));
                    break;
                case 3:
                    teeShotInfoFormChilds.slice(3).forEach(el => el.classList.add('d-none'));
                    break;
                case 4:
                    teeShotInfoFormChilds.slice(4).forEach(el => el.classList.add('d-none'));
                    break;
            }
        });
    }
}

you can provide document.querySelector to the function.

Like this.

function selectTeeShotCount() {
  const teeShotInfoFormChild = (nthChildNumber = 0) => document.querySelector(`#teeShotInfoForm > div:nth-child(${nthChildNumber})`)

  console.log(document.teeShotInfoForm.TeeCount);
  const radioTeeShot = document.teeShotInfoForm.TeeCount;
  let prev = null;
  
  for (const radioTeeShotElement of radioTeeShot) {
      radioTeeShotElement.addEventListener('change', event => {
          (prev) ? console.log(prev.value): null;
          if (this !== prev) {
              prev = this;
          }

          teeShotInfoFormChild(3).classList.remove('d-none');
          teeShotInfoFormChild(4).classList.remove('d-none');
          teeShotInfoFormChild(5).classList.remove('d-none');
          teeShotInfoFormChild(6).classList.remove('d-none');
          teeShotInfoFormChild(7).classList.remove('d-none');

          switch (parseInt(radioTeeShot.value)) {
              case 1:
                  teeShotInfoFormChild(4).classList.add('d-none');
                  teeShotInfoFormChild(5).classList.add('d-none');
                  teeShotInfoFormChild(6).classList.add('d-none');
                  teeShotInfoFormChild(7).classList.add('d-none');
                  break;
              case 2:
                  teeShotInfoFormChild(5).classList.add('d-none');
                  teeShotInfoFormChild(6).classList.add('d-none');
                  teeShotInfoFormChild(7).classList.add('d-none');
                  break;
              case 3:
                  teeShotInfoFormChild(6).classList.add('d-none');
                  teeShotInfoFormChild(7).classList.add('d-none');
                  break;
              case 4:
                  teeShotInfoFormChild(7).classList.add('d-none');
                  break;
          }
      });
  }
}

In next step you can add teeShotInfoFromChild 3-7 to the array and use forEach, like this:

function selectTeeShotCount() {
  const teeShotInfoFormChild = (nthChildNumber = 0) => document.querySelector(`#teeShotInfoForm > div:nth-child(${nthChildNumber})`)

  console.log(document.teeShotInfoForm.TeeCount);
  const radioTeeShot = document.teeShotInfoForm.TeeCount;
  let prev = null;
  
  for (const radioTeeShotElement of radioTeeShot) {
      radioTeeShotElement.addEventListener('change', event => {
          (prev) ? console.log(prev.value): null;
          if (this !== prev) {
              prev = this;
          }


          [
            teeShotInfoFormChild(3),
            teeShotInfoFormChild(4),
            teeShotInfoFormChild(5),
            teeShotInfoFormChild(6),
            teeShotInfoFormChild(7)
          ].forEach((child) => child.classList.remove('d-none'))

          switch (parseInt(radioTeeShot.value)) {
              case 1:
                  teeShotInfoFormChild(4).classList.add('d-none');
                  teeShotInfoFormChild(5).classList.add('d-none');
                  teeShotInfoFormChild(6).classList.add('d-none');
                  teeShotInfoFormChild(7).classList.add('d-none');
                  break;
              case 2:
                  teeShotInfoFormChild(5).classList.add('d-none');
                  teeShotInfoFormChild(6).classList.add('d-none');
                  teeShotInfoFormChild(7).classList.add('d-none');
                  break;
              case 3:
                  teeShotInfoFormChild(6).classList.add('d-none');
                  teeShotInfoFormChild(7).classList.add('d-none');
                  break;
              case 4:
                  teeShotInfoFormChild(7).classList.add('d-none');
                  break;
          }
      });
  }
}

The next step to optimise your code is to fix your switch with remove "break" and duplicating code.

function selectTeeShotCount() {
  const teeShotInfoFormChild = (nthChildNumber = 0) =>
    document.querySelector(
      `#teeShotInfoForm > div:nth-child(${nthChildNumber})`
    );

  console.log(document.teeShotInfoForm.TeeCount);
  const radioTeeShot = document.teeShotInfoForm.TeeCount;
  let prev = null;

  for (const radioTeeShotElement of radioTeeShot) {
    radioTeeShotElement.addEventListener("change", (event) => {
      prev ? console.log(prev.value) : null;
      if (this !== prev) {
        prev = this;
      }

      [
        teeShotInfoFormChild(3),
        teeShotInfoFormChild(4),
        teeShotInfoFormChild(5),
        teeShotInfoFormChild(6),
        teeShotInfoFormChild(7)
      ].forEach((child) => child.classList.remove("d-none"));

      switch (parseInt(radioTeeShot.value)) {
        case 1:
            teeShotInfoFormChild(4).classList.add("d-none");
        case 2:
            teeShotInfoFormChild(5).classList.add("d-none");
        case 3:
            teeShotInfoFormChild(6).classList.add("d-none");
        case 4:
            teeShotInfoFormChild(7).classList.add("d-none");
            break;
        default:
          break;
      }
    });
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM