处理多个页面上的事件侦听器

斯蒂芬妮·帕克

我编写了一个javascript文件,其中包含一些事件监听器,用于处理选项卡,手风琴等。但是这些并不是在每个页面中都存在,因此它正在寻找不存在的元素并将整个js丢掉。

我知道我可以通过使用多个if语句来解决它,但这听起来并不正确。

// Accordion
const accordions = document.querySelectorAll('.accordion li');

accordions.forEach(accordion =>{
    accordion.addEventListener('click', (e) => {
        e.preventDefault();
        accordion.classList.toggle('open');
    })
});

// Inline toggle
const inlineToggle = document.getElementById('inline-toggle');

inlineToggle.addEventListener('click', () => {
    inlineToggle.nextElementSibling.classList.toggle('active');
});

const inlineToggleOptions = document.querySelectorAll('.inline-toggle-options button');
inlineToggleOptions.forEach(option => {
    option.addEventListener('click', (e) => {
        // Prevent default
        e.preventDefault();
        // Update sentence text
        inlineToggle.innerHTML = option.dataset.payType;
        // Remove selected class from options
        inlineToggleOptions.forEach(option => {
            option.classList.remove('selected');
        });
        // Add selected class to chosen option
        option.classList.add('selected');
        // Close dialog
        inlineToggle.nextElementSibling.classList.remove('active');
    })
});

// Cover bubbles

// Create the slidepanel
const placeholder = document.getElementById('slidepanel');

// Find all buttons
const button = document.querySelectorAll('.trigger-aside');

button.forEach((button => {

    // Listen for clicks on buttons
    button.addEventListener('click',(e) => {

        // Prevent default
        e.preventDefault();

        // Get the target
        const target = button.dataset.target;
        console.log(target);

        // Call the API
        fetch(`http://****.****.uk/****/****/****/${target}`)
            .then((res) => res.json())
            .then(function(res) {

                // Load HTML into slider panel
                placeholder.innerHTML = res.object.content;

                // Stop body overflow
                document.body.classList.add('overflow-hidden');

                // Create overlay and append
                const overlay = document.querySelector('.overlay');
                overlay.classList.add('active');
                document.body.appendChild(overlay);

                // Show the panel
                placeholder.classList.add('active');
                document.body.appendChild(placeholder);

                // Listen for close
                overlay.addEventListener('click', (e) =>{
                    // Close requested
                    document.body.classList.remove('overflow-hidden');
                    placeholder.classList.remove('active');
                    overlay.classList.remove('active');
                });

            })
            .catch(function(err) {
                // Log error
                console.log(err);
            });

    })
}));

其他人通常如何解决这个问题?任何指导表示赞赏!

贝尔克斯

事件委托模式

如果您将这些UI元素归为所有页面(例如div包装器)共有的父元素下的一部分,则可以尝试使用事件委托模式本质上,您可以为该父元素分配一个click事件,并利用一个函数仅在返回所需元素(即您的按钮)时才采取措施。它会像...

const parent = document.querySelector('div.wrapper'); //Change selector to suit a common parent
const buttons = [...document.querySelectorAll('.inline-toggle-options button')]; // convert to array to make it easier to work with
const elementsToChange = document.querySelectorAll('.elements .to .change');

parent.addEventListener('click', toggleOptions);

function getEventTarget(e) {
  e = e || window.event;
  return e.target || e.srcElement; // For IE compatibility
}

function toggleOptions {
  let target = getEventTarget(e);
  if(buttons.includes(target)) {
    // Trigger options on UI elements if any of the buttons are among the clicked elements
    // Target refers to the buttons in particular, not the UI elements you want to change
  }
}

您想以哪种方式重构代码以对特定元素采取行动,取决于您。您可以按特定功能将按钮分组到不同的数组中。如果您有2或3个数组,则只需要从条件语句中编写2或3个选项。

为此,您还可以使用这种模式来节省内存,因为您只分配了一个事件处理程序,并使子元素上的子事件冒泡,由单个处理程序来处理。另外,您不应遇到错误,因为初始事件处理程序已分配给所有页面上通用的父元素。

一些警告

从上面链接的指南中:

并非所有事件都会冒泡。模糊,聚焦,加载和卸载事件不会像其他事件那样冒泡。实际上,可以使用捕获阶段(在IE以外的浏览器中)而不是冒泡阶段来访问模糊和聚焦事件,但这是另一回事了。

管理某些鼠标事件时,您需要小心。如果您的代码正在处理mousemove事件,则您很可能会创建性能瓶颈,因为mousemove事件被触发得非常频繁。mouseout事件具有古怪的行为,很难通过事件委托来管理。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章