事件切换监听器

时间:2019-05-31 17:47:58

标签: javascript css object methods selectors-api

我正在尝试使用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();
}

2 个答案:

答案 0 :(得分: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');

答案 1 :(得分:2)

简单的解决方案,您的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>