在功能上对变量进行分组

时间:2017-07-29 14:03:00

标签: javascript html

我觉得这很明显我会在(如果)解决时感到羞耻 - 但我无法让它发挥作用。

我有一个html + javascript页面,其中有多个项目都需要通过用户点击显示或隐藏。 所以我有一些数量的div,如:

<div id="myDIVA" style="display:none;">blabla 1</div>
<div id="myDIVB" style="display:none;">blabla 2</div>
<div id="myDIVC" style="display:none;">blabla 3</div>

通过点击div来隐藏和/或显示它们:

<div onClick="myClickFunctionA()">Show only ONE</div>
<div onClick="myClickFunctionB()">Show only TWO</div>
<div onClick="myClickFunctionC()">Show only THREE</div>

简单的脚本:

<script>
    var a = document.getElementById('myDIVA');
    var b = document.getElementById('myDIVB');
    var c = document.getElementById('myDIVC');
function myClickFunctionA() {
        a.style.display = 'block';
        b.style.display = 'none';
        c.style.display = 'none';
}
function myClickFunctionB() {
        a.style.display = 'none';
        b.style.display = 'block';
        c.style.display = 'none';
}
</script>

我想做的是能够对变量进行分组,以便我可以拥有如下函数:

function myClickFunctionA() {
        a.style.display = 'block';
        b + c.style.display = 'none';
}

我有很多div!所以这可能看起来很愚蠢,但是对我来说能够#34; group&#34; vars更容易编辑。

所以我希望有人能找到一个简单的解决方案:-) 感谢

4 个答案:

答案 0 :(得分:1)

可能是数组的好用例:

var elemsById = ["myDIVA","myDIVB","myDIVC"]
 .map(id=>[id,document.getElementById(id)]);

因此,每当我们想要显示其中一个元素时,我们会遍历所有元素,并根据其ID隐藏/显示它们:

function showThisAndHideRest(showId){
  elemsById.forEach(function([id,el]){
    el.style.display=id===showId?"block":"none";
  });
}

所以你可以这样做:

showThisAndHideRest("myDIVA");

注意:鞋面使用了一些很酷的ES6功能,所有浏览器都不支持。并且实际上不需要在数组中存储id,因为它已经是el( el.id )的一部分,但我只是想使用一些参数解构......

Run

答案 1 :(得分:1)

我假设您想要为每个div分别设置一个函数。你不需要。 :-)你可以使用一个函数来处理点击,并使用一组div。

首先,让我们得到一些div:

var divs = Array.prototype.slice.call(document.querySelectorAll("[id^=myDIV]"));

(如果我们可以给他们一个共同的课程会更好。这会在他们的ID开始时抓住他们。)

然后,让我们让可点击的div说出与之相关的div:

<div onClick="myClickFunction('myDIVA')">Show only ONE</div>

然后,让我们有一个处理点击的功能:

function myClickFunction(id) {
    divs.forEach(function(div) {
        div.style.display = div.id === id ? "block" : "none";
    });
}

(请参阅最后的兼容性说明。)

但是,使用onxyz - 属性样式的事件处理程序通常是一个坏主意。它们要求你使用的函数是全局函数。

相反,让我们动态连接它们,并使用data-*属性来说明它们与哪个目标相关:

// Scoping function to avoid globals
(function() {
  var divs = Array.prototype.slice.call(document.querySelectorAll(".showable"));
  Array.prototype.forEach.call(document.querySelectorAll("div[data-show]"), function(dshow) {
      dshow.addEventListener("click", myClickFunction, false);
  });

  function myClickFunction() {
    var idToShow = this.getAttribute("data-show");
    divs.forEach(function(div) {
      div.style.display = div.id === idToShow ? "block" : "none";
    });
  }
})();
<div data-show="myDIVA">Show A</div>
<div data-show="myDIVB">Show B</div>
<div data-show="myDIVC">Show C</div>
<div class="showable" id="myDIVA">A</div>
<div class="showable" id="myDIVB" style="display: none">B</div>
<div class="showable" id="myDIVC" style="display: none">C</div>

现在我们没有全局函数,标记定义了元素之间的关系。

兼容性说明:

如果你必须支持那些没有addEventListener的过时浏览器(比如IE8 - 可悲的是很多),this answer有一个跨浏览器hookEvent功能你可以使用。

请注意,如果你支持IE8,你还必须使用for循环而不是Array.prototype.forEach,因为IE8没有它,你无法合理地填充它(因为IE8也不支持向JavaScript对象添加非可枚举属性。)

答案 2 :(得分:0)

以下是使用addEventListener的解决方案,无需onclick属性:

// Select the buttons and items
var buttons = Array.prototype.slice.call(document.querySelectorAll('.showhidebutton'))
var items = Array.prototype.slice.call(document.querySelectorAll('.showhideitem'))

// Add a click eventListener for each button
buttons.forEach(function(button, i) {
  button.addEventListener('click', function() {
    // When a button is clicked, loop through the items
    items.forEach(function(item, j) {
      // If this is the item that should be shown, show it
      if (i === j) item.style.display = 'block'
      // Otherwise, hide it
      else item.style.display = 'none'
    })
  })
})

// This code hides all but item 1 on pageload
// can remove this code if you don't want that
items.forEach(function(item, j) {
  // Arrays are zero-indexed in JS, so the first item is 0
  if (i === 0) return
  // Hide all the other items
  else item.style.display = 'none'
})
<div class="showhideitem">blabla 1</div>
<div class="showhideitem">blabla 2</div>
<div class="showhideitem">blabla 3</div>

<div class="showhidebutton">Show only ONE</div>
<div class="showhidebutton">Show only TWO</div>
<div class="showhidebutton">Show only THREE</div>

答案 3 :(得分:0)

您可以使用带有选择器click的{​​{1}}为需要.querySelectorAll()事件的每个元素定义公共类,使用".myClickFunction"迭代NodeList环;将每个元素的for设置为当前迭代索引;将Element.dataset处理程序附加到元素;再次使用带有选择器click的{​​{1}}来选择.querySelectorAll()"[id^myDIV]"开头的所有元素;在id事件中,每个"myDIV" click设置为"myDIV";将索引.style "display:none"设置为"myDIV"Element.dataset

.style
"display:block"