javascript - 使用 querySelectorAll/classList 添加通用类,无需不断循环

标签 javascript jquery arrays selectors-api

我面临以下问题。

每次我必须使用 querySelectorAllElement.classList ,我需要

  1. 将从 Element.querySelectorAll 返回的 NodeList 转换为数组
  2. 对数组执行 forEach 来分别操作每个项目。

jQuery 抽象了上述内容,所以我想开发一个辅助方法,类似于 jQuery 的工作方式,其工作原理如下:

myhelper('.someClass').classList.add('newClass'); // there are more than 1 .someClass items
myhelper('#id').classList.remove('existingClass');

本质上 myhelper(selector) 应该在底层抽象上面的 1+2 点:从 querySelectorAll 获取 NodeList,将其转换为数组,forEach 数组并*执行已执行的方法由用户给出。

PS:为了简化事情,它可以适用于一组特定的 native 方法:例如 classList 方法和 textContent。

最佳答案

我的第一个冲动是建议只使用 jQuery 并在需要的地方进行扩展;)

但是尝试一下:如果 my_Helper 函数用作对象,它可以缓冲元素并包含使用这些元素的函数。如果直接调用my_Helper,它可以强制返回一个新对象。 此外,添加的功能可以返回对象本身,因此可以像在 jquery 中一样使用链接。一个使用 addClass 的简单示例:

function my_Helper(query){
	if(this.constructor !== my_Helper)
  	 return new my_Helper(query); //if called directly (not as new()), return a new object
     
  this.elements = document.querySelectorAll(query);  
  this.addClass = function(className) {
  	for(var el of this.elements)
    	el.classList.add(className);
  	return this; //to be able to use chaining
  }
  return this;
}



my_Helper('.someClass').addClass('newClass').addClass('newClass2'); //2 separate classes to test chaining
.newClass{
  width:100px;
  height:100px;  
}

.newClass2{
  border:1px solid black;
}
<div class= 'someClass'></div>
<div class= 'someClass'></div>
<div class= 'someClass'></div>

编辑,根据评论,手动添加额外的方法不会有问题,但希望在不复制 foreach 的情况下更容易添加单个方法?下面有一个通用的 invoke 函数,可以从使用此调用创建其他方法的对象和辅助函数外部调用(并且还引入了一个仅调用 addClass 的 classList 包装器,以使其更容易迁移代码)

function my_Helper(query){
	if(this.constructor !== my_Helper)
  	 return new my_Helper(query); //if called directly (not as new()), return a new object
  
  this.elements = document.querySelectorAll(query);        
  let self = this;
  
  this.invoke = function(property , func, ...pars){
  	for(let el of self.elements){    
    	if(!func){  //no function given -> property setter
      	if(property)
        	el[property] = [pars]
      }
      else {
        let p = property ? el[property] : el; //if no property is given, use element itself
        if(!p) continue;

        let fn = p[func];
        if(!fn) continue; //function does not exist on the property or element      
        fn.apply(p,pars);
      }
    }
    return self;
  }
  
  function fn(property, functionName, ...pars){
  	return (...pars) => self.invoke(property, functionName, pars);
  }
  
  this.addClass = fn('classList', 'add');
  this.removeClass = fn('classList', 'add');
  this.text = fn('textContent');
  
  this.classList = {add:self.addClass, remove:self.removeClass}; //if classlist has to be used instead of addClass
  
  return this;
}

my_Helper('.someClass').classList.add('newClass').addClass('newClass2').text('aaa');
.newClass{
  width:100px;
  height:100px;  
}

.newClass2{
  border:1px solid black;
}
<div class= 'someClass'></div>
<div class= 'someClass'></div>
<div class= 'someClass'></div>

在此基本实现中,调用需要字符串,但它也可以轻松扩展以接受函数。

关于javascript - 使用 querySelectorAll/classList 添加通用类,无需不断循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44242693/

相关文章:

java - 返回递归中的数字集

c - 如何在 C 中拆分字符串、存储在数组中并传递几个函数

javascript - Jquery 函数不适用于两种或多种形式

javascript - 刷新 token 如何工作以及上次失败的 http 请求如何再次调用并给出 401...?

javascript - 我怎样才能 "performance detect"浏览器

jquery - IE 7/8 专有过滤器和 jQuery 的问题

jquery - 在页面中的每个图像弹出窗口中添加动态文本框以进行图像描述

javascript - 干代码 : Use JQuery to make loop for a similar properties in function attached to different classes

arrays - 在 C 中,是否可以创建没有 '\0(null)' 的字符串?

javascript - 在 React 组件中输入文本