【问题标题】:Event toggle listener事件切换监听器
【发布时间】:2019-05-31 17:47:58
【问题描述】:

我正在尝试使用 ui.activeFilter() 方法更改一些样式,但它说:

无法读取toggle 的属性undefined

我将变量filterLinks 设置为全局范围。我不知道为什么它不起作用。

"use strict";

// UI elements
const filterLinks = document.querySelectorAll('a');
const itemsLeft = document.querySelectorAll('span');

// Event listeners
filterLinks.forEach(function(link) {
  link.addEventListener('click', check);
});

// Laptops
class Laptop {
    constructor(availability, price, brand) {
      this.availability = availability;
      this.price = price;
      this.brand = brand;
    }
}

// Filter methods
class UiMethod {
    activeFilter(dddd) {
        dddd.classList.toggle('checked');

        if(dddd.className === 'checked') {
            console.log("test");
        } else {
            console.log('Try again you can do it, you are close to the succes');
        }
    }
}

const ui = new UiMethod;

// Function helpers
function check(e) {

    ui.activeFilter(filterLinks);
    e.preventDefault();
}

【问题讨论】:

    标签: javascript css object methods selectors-api


    【解决方案1】:

    简单的解决方案,您的check(e) 函数需要稍作更新。无需传递整个对象,您只需传递 click 函数的 e.target 即可仅影响该对象。

    改变: ui.activeFilter(filterLinks);

    到: ui.activeFilter(e.target);

    "use strict";
    
    // UI elements
    const filterLinks = document.querySelectorAll('a');
    
    // Event listeners
    filterLinks.forEach(function(link) {
      link.addEventListener('click', check);
    });
    
    // Laptops
    class Laptop {
        constructor(availability, price, brand) {
          this.availability = availability;
          this.price = price;
          this.brand = brand;
        }
    }
    
    // Filter methods
    class UiMethod {
        activeFilter(dddd) {
            dddd.classList.toggle('checked');
    
            if(dddd.className === 'checked') {
                console.log("test");
            } else {
                console.log('Try again you can do it, you are close to the succes');
            }
        }
    }
    
    const ui = new UiMethod;
    
    // Function helpers
    function check(e) {
        ui.activeFilter(e.target);
        e.preventDefault();
    }
    .checked{
    color:red;
    }
    <a href="#">test</a><BR>
    <a href="#">test2</a><BR>
    <a href="#">test3</a>

    【讨论】:

    • 好的,我尝试了this,它的工作方式与我添加 e.target 的方式相同。哪种方式更好?
    • @GrecA 当check(e) 被调用时,event 不仅作为e 传递,而且this 引用了被点击的对象。它实际上与filterLinks 无关。就this 而言,filterLinks 不存在。
    • @GrecA,为了保持一致性,我会使用e.target。我通常使用 jquery,所以这意味着不同的东西。但是,通过这两个中的一个可以解决您的问题(无论您通过 this 还是 e.target)。
    【解决方案2】:

    无法读取未定义的属性toggle

    看起来toggle 在这里被引用:dddd.classList.toggle。因此,dddd.classList 未定义。 classList 是所有 DOM 元素对象的已定义属性,所以 dddd 一定不是你想的那样。

    回顾dddd的定义,我们可以看到它被定义为filterLinks。看filterLinks,很明显是document.querySelectorAll('a')设置的。

    检查querySelectorAll 的文档告诉我们它返回了:

    一个非活动的NodeList 包含一个Element 对象,每个元素至少匹配一个指定的选择器或一个空的NodeList 在没有匹配的情况下。

    因此,要访问查询找到的实际 DOM 元素对象,我们需要从 NodeList 中提取该对象。如果您想对找到的每个 元素执行toggle 操作,最简单的方法是循环遍历NodeList 并在每个元素上运行该函数。 NodeList 类似于数组,但它不是数组,因此我们需要将其转换为数组才能在其上使用forEach。这将产生以下代码:

    Array.from(dddd).forEach(element => element.classList.toggle('checked'));
    

    这将取代这个:

    dddd.classList.toggle('checked');
    

    【讨论】:

    • 是的,但是如果我添加它,它会同时启用每个元素,我希望单个元素切换该类。
    • 然后使用document.querySelector()返回匹配选择器的first元素,让你的选择器更加具体。
    • 我让document.querySelectorAll 添加了 e.target.classList.toggle('checked');这意味着对于每个点击的目标,对吗?这是正确的吗?
    猜你喜欢
    • 2014-01-27
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 2020-10-13
    • 2014-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多