抽象重复的addEventListener('click'...函数来优化代码

时间:2014-03-17 23:35:16

标签: javascript html css html5

编辑:寻找非Jquery答案

就目前而言,这段代码的简单程度令人难以置信。特定实例之间的唯一区别是指示目标ID的数字。有没有办法用单个函数来实现相同的结果,该函数根据点击的div得到变量?

var $ = Sizzle,
p0 = $("#p0")[0];
p1 = $("#p1")[0];
p2 = $("#p2")[0];
p3 = $("#p3")[0];
p4 = $("#p4")[0];
p5 = $("#p5")[0];
p6 = $("#p6")[0];
p7 = $("#p7")[0];
lp0 = $("#productMenu li")[0];
lp1 = $("#productMenu li")[1];
lp2 = $("#productMenu li")[2];
lp3 = $("#productMenu li")[3];
lp4 = $("#productMenu li")[4];
lp5 = $("#productMenu li")[5];
lp6 = $("#productMenu li")[6];
lp7 = $("#productMenu li")[7];


lp0.addEventListener('click',open0,false);
lp1.addEventListener('click',open1,false);
lp2.addEventListener('click',open2,false);
lp3.addEventListener('click',open3,false);
lp4.addEventListener('click',open4,false);
lp5.addEventListener('click',open5,false);
lp6.addEventListener('click',open6,false);
lp7.addEventListener('click',open7,false);



function open0(){
p0.classList.toggle('off');
}

function open1(){
p1.classList.toggle('off');
}
function open2(){
p2.classList.toggle('off');
}

function open3(){
p3.classList.toggle('off');
}
function open4(){
p4.classList.toggle('off');
}

function open5(){
p5.classList.toggle('off');
}
function open6(){
p6.classList.toggle('off');
}

function open7(){
p7.classList.toggle('off');
}

2 个答案:

答案 0 :(得分:0)

您可以尝试以下代码:

$('#productMenu li').on('click', function () {
  var index = $("#productMenu li").index($(this));
  $('#p' + index).toggleClass('off');
});

答案 1 :(得分:0)

在简单的脚本中,类似下面的内容应该有效:

// Helper to convert a list to an array
function toArray(list) {
  var array = [];
  for (var i=0, iLen=list.length; i<iLen; i++) {
    array[i] = list[i];
  }
  return array;
}

// Helper to add a listener without closure
function addFunction(source, target) {
  source.addEventListener('click', function(){target.classList.toggle('off')}, false);  
}

function addListeners() {
  var nodes = [];

  for (var i=0; i<8; i++) {
    pNodes.push(document.getElementById('p' + i));
  }

  var lpNodes = toArray(document.getElementById('productMenu').getElementsByTagName('li'));

  for (var j=0, jLen=lpNodes.length; j<jLen; j++) {
    addFunction(lpNodes[j],pNodes[j]); 
  }
}

当然未经测试,但该方法应该有所帮助。没有必要将 getElementsByTagName 返回的NodeList转换为数组,但它可能有助于提高性能。

还有其他方法,最明显的是使用事件委托并将单个侦听器放在父元素(UL?)上,以查看点击来自何处,然后根据需要切换相关元素。例如如果点击来自lp0,则切换p0(尽管你应该使用类,而不是ID)。

类似的东西:

function handleClick(event) {
  var element;
  var target = event.target;

  if (target.tagName && target.tagName.toLowerCase() == 'li') {
    var id = target.id.match(/\d+/$);

    if (id) {
      element = document.getElementById('p' + id[0]);
    }

    if (element) {
      element.classList.toggle('off');
    }
  }
}

window.onload = function() {
  document.getElementById('productMenu').addEventListener('click', handleClick, false);
}