【问题标题】:Is there a way to refactor this JS code so that I am not repeating myself so much?有没有办法重构这个 JS 代码,这样我就不会重复自己了?
【发布时间】:2018-11-28 17:51:37
【问题描述】:

我对 JS 非常陌生,正在努力重构以下代码。它按预期运行并打开和关闭模态窗口,但至少可以说并不是特别干...

// Open modal windows

document.querySelector('#modal-btn1').addEventListener('click', 
  function() {
    document.querySelector('.modal1').style.display = 'block';
    document.querySelector('body').style.overflow = 'hidden';
  });

document.querySelector('#modal-btn2').addEventListener('click', 
  function() {
    document.querySelector('.modal2').style.display = 'block';
    document.querySelector('body').style.overflow = 'hidden';
  });

document.querySelector('#modal-btn3').addEventListener('click', 
  function() {
    document.querySelector('.modal3').style.display = 'block';
    document.querySelector('body').style.overflow = 'hidden';
  });

document.querySelector('#modal-btn4').addEventListener('click', 
  function() {
    document.querySelector('.modal4').style.display = 'block';
    document.querySelector('body').style.overflow = 'hidden';
  });

// Close modal windows

document.querySelector('.close-box1').addEventListener('click', 
  function () {
    document.querySelector('.modal1').style.display = 'none';
    document.querySelector('body').style.overflow = 'visible';
  });

document.querySelector('.close-box2').addEventListener('click', 
  function () {
    document.querySelector('.modal2').style.display = 'none';
    document.querySelector('body').style.overflow = 'visible';
  });

document.querySelector('.close-box3').addEventListener('click', 
  function () {
    document.querySelector('.modal3').style.display = 'none';
    document.querySelector('body').style.overflow = 'visible';
  });

document.querySelector('.close-box4').addEventListener('click', 
  function () {
    document.querySelector('.modal4').style.display = 'none';
    document.querySelector('body').style.overflow = 'visible';
  });

任何正确方向的指针将不胜感激。

【问题讨论】:

  • 使用类和自定义属性!
  • 您可以编写一个函数来接收模态编号(看起来这就是您所需要的)并添加事件侦听器。
  • 感谢所有非常有用的建议 :)

标签: javascript dom event-handling dom-events


【解决方案1】:

您可以使用类来创建事件并使用自定义属性将每个点击事件链接到其模式

查看代码示例

document.querySelectorAll('.modal-btn').forEach(function(item){  
  item.addEventListener('click', 
  function(e) {
    var target = item.getAttribute("data-modal");
    document.querySelector(target).style.display = 'block';
    document.querySelector('body').style.overflow = 'hidden';
  });
})
.modal {
  display:none;
  background:black;
  width:150px;
  height:50x;
  color:white;
}
<button class="modal-btn" data-modal="#modal1">open modal 1</button>

<button class="modal-btn" data-modal="#modal2">open modal 2</button>

<button class="modal-btn" data-modal="#modal3">open modal 3</button>

<div id="modal1" class="modal">Modal 1</div>

<div id="modal2" class="modal">Modal 2</div>

<div id="modal3" class="modal">Modal 3</div>

【讨论】:

    【解决方案2】:
    const ID = "#";
    const CLASS = ".";
    
    const addEvent = (idOrClass, name, elementsLength, modalDisplay, bodyOverflow) => {
       for(let i=1; i <= elementLength; i++){
         document.querySelector(`${idOrClass}${name}${i}`).addEventListener('click', () => {
           document.querySelector(`.modal{i}`).style.display = modalDisplay;
           document.querySelector('body').style.overflow = bodyOverflow;
         });
       }
    }
    
    addEvent(ID, 'modal-btn', 4, 'block', 'hidden');
    addEvent(CLASS, 'close-box', 4, 'none', 'visible');
    

    不是最漂亮的,但这是我能想到的。通常你会使用像 Bootstrap 这样的框架来为你处理模态

    【讨论】:

      【解决方案3】:

      通过编写使用变量的函数,您可以轻松减少重复代码的次数。这就是编程的魅力!

      例如,为所有按钮提供某种描述符,您可以使用该描述符来唯一标识它们应该打开哪个模式,然后您可以编写一个事件侦听器来打开正确的事件侦听器。

      例子:

      如果你有这样的元素和模态:

      <button class='modal-button' data-target-modal='modal-1'>
       Open Modal 1
      </button>
      
      <div id='modal-1' class='modal'>
        Hi I am modal 1
      </div>
      

      然后你可以有一个单一的功能来为所有这些供电:

      document.addEventListener('click', (event) => {
      
        let clickedEl = event.target;
      
        // do this when we click a modal-button
        if(clickedEl.classList.contains('modal-button')) {
      
           // get the id of the modal via getAttribute
           let modalId = clickedEl.getAttribute('data-target-modal');
      
           // now get a reference to the actual modal html element
           let modalEl = document.getElementById(modalId);
      
           // open it!
           modalEl.classList.add('open');
      
      
        }
        else
        if(clickedEl.classList.contains('modal-close-button')) {
           // do something similar here for closing!
        }
      })
      

      https://jsfiddle.net/ryc8xzan/

      【讨论】:

      • let 变量是块作用域{ ... },因此它不能在if 语句上方声明,也不能在其块if () { ... } 内使用。如果它有效,我不知道为什么,但它不应该。
      猜你喜欢
      • 1970-01-01
      • 2021-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-09
      • 2020-11-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多