如何简化冗长的代码?

时间:2017-12-18 17:14:18

标签: javascript arrays loops

我做了click to reveal互动。设置是一个背景图像,顶部有7个区域,具有悬停状态并且可以单击。

单击可点击区域时,会在周围区域显示单独的图像(7个中的1个),直到所有7个图像都显示出来。

我已经成功实现了这一目标,但我认为可以采用更有效的方式来实现这一目标,而不必反复重复类似的功能。

以下是js fiddle

上我当前代码的简化版本

HTML     

   <!-- Background img of character-->
   <img src="https://s2.postimg.org/g9iokigk9/man_cartoon.jpg" width="500px" />

   <!-- Hover circles -->
   <a class="hover-btn-face" style="top:80px; left:225px;">
      <img src="https://s2.postimg.org/mzz5tybft/red-dot.png" />
   </a>

   <a class="hover-btn-shoulder" style="top:150px; left:180px;">
      <img src="https://s2.postimg.org/mzz5tybft/red-dot.png" />
   </a>

   <a class="hover-btn-hand" style="top:320px; left:170px;">
      <img src="https://s2.postimg.org/mzz5tybft/red-dot.png" />
   </a>


   <!-- Icons that are revealed on click of hover circles -->
   <div class="icon icon-face" style="top:70px; left:0">
     <p>Face</p>
   </div>

   <div class="icon icon-shoulder" style="top:150px; left:0">
     <p>Shoulder</p>
   </div>

   <div class="icon icon-hand" style="top:320px; left:0">
     <p>Hand</p>
   </div>

</div>

CSS

    <style>

    .container {
        position:relative;
    }   

    a {
       position:absolute;
       width:50px;
       height:50px;
    }

    a img {
       display:none;
       width: 100%;
       height: 100%;
      }

    a:hover img {
      display:block;
    }

   .icon {
      width:100px;
      padding:5px;
      background:blue;
      position:absolute;
      color:#fff;
      text-align:center;
      font-family:arial;
      border-radius:10px;
    }

    </style>

JS

var parts = ['face', 'shoulder', 'hand'];

var icon, i;

for (i = 0; i < parts.length; i++) {
    icon = document.querySelector('.icon-' + parts[i]) ;
      icon.style.display = 'none';

}


document.querySelector('.hover-btn-' + parts[0]).addEventListener('click', function() {

    document.querySelector('.icon-' + parts[0]).style.display = "block";

});

document.querySelector('.hover-btn-' + parts[1]).addEventListener('click', function() {

    document.querySelector('.icon-' + parts[1]).style.display = "block";

});

document.querySelector('.hover-btn-' + parts[2]).addEventListener('click', function() {

document.querySelector('.icon-' + parts[2]).style.display = "block";

});

1 个答案:

答案 0 :(得分:0)

以下是一种方法;虽然值得注意的是我对您的HTML进行了微小的更改,但是为定义或显示在正文部分上的每个data-*元素添加了自定义<a>属性,转换:

<a class="hover-btn-face" style="top:80px; left:225px;">
  <img src="https://s2.postimg.org/mzz5tybft/red-dot.png" />
</a>

成:

<a class="hover-btn-face" data-anatomy="face" style="top:80px; left:225px;">
  <img src="https://s2.postimg.org/mzz5tybft/red-dot.png" />
</a>

尽管如此,我对你的方法的修改如下:

// creating a named function to handle the (repeated) behaviours:
function showDetails() {

  // declaring local variables using the 'let' statement,
  // retrieving the attribute-value of the 'data-anatomy'
  // custom attribute (set in the HTML) from the 'this'
  // DOM node (passed to the function from
  // eventTarget.addEventListener():
  let part = this.dataset.anatomy;

  // here we find the single element which has a class name
  // comprised of the string 'icon' concatenated  with the
  // anatomical 'part' retrieved earlier, and updating its
  // 'display' property to 'block':
  document.querySelector('.icon-' + part).style.display = 'block';
}

// here we use document.querySelectorAll() to retrieve all
// elements with a class of 'icon', that nodeList is passed
// to Array.from() and converted to an Array, in order to use
// Array methods:
Array.from(document.querySelectorAll('.icon'))

  // here we use Array.prototype.forEach() to iterate over
  // all elements in the resulting Array:
  .forEach(

    // using an Arrow function, 'icon' is a reference to the
    // current array-element of the array over which we're
    // iterating; and here we update its 'display' property
    // to 'none' (to hide the element(s) on page-load):
    icon => icon.style.display = 'none'
);

// retrieving a NodeList of all <a> elements with a custom
// 'data-anatomy' attribute, and converting that NodeList
// into an Array using Array.from():
let parts = Array.from(document.querySelectorAll('a[data-anatomy]'));

// iterating over that Array of elements using
// Array.prototype.forEach():
parts.forEach(

  // Using an Arrow function, here 'part' is a reference to the
  // current array element of the array of DOM nodes; here we
  // use EventTarget.addEventListener() to bind the showDetails
  // function (note the deliberate lack of parentheses) as the
  // event-handler for the 'click' event:
  part => part.addEventListener('click', showDetails)
);

&#13;
&#13;
function showDetails() {
  let part = this.dataset.anatomy;
  document.querySelector('.icon-' + part).style.display = 'block';
}

Array.from(document.querySelectorAll('.icon')).forEach(
  icon => icon.style.display = 'none'
);

let parts = Array.from(document.querySelectorAll('a[data-anatomy]'));

parts.forEach(
  part => part.addEventListener('click', showDetails)
);
&#13;
.container {
  position: relative;
}

a {
  position: absolute;
  width: 50px;
  height: 50px;
}

a img {
  display: none;
  width: 100%;
  height: 100%;
}

a:hover img {
  display: block;
}

.icon {
  width: 100px;
  padding: 5px;
  background: blue;
  position: absolute;
  color: #fff;
  text-align: center;
  font-family: arial;
  border-radius: 10px;
}
&#13;
<div class="container">

  <!-- Background img of character-->
  <img src="https://s2.postimg.org/g9iokigk9/man_cartoon.jpg" width="500px" />

  <!-- Hover circles -->
  <!-- note the addition of the custom data-* attribute, in order to
       avoid having to hard-code the 'part' in the JavaScript without
       having to parse the relevant 'part' from the class-name(s) -->
  <a class="hover-btn-face" data-anatomy="face" style="top:80px; left:225px;">
    <img src="https://s2.postimg.org/mzz5tybft/red-dot.png" />
  </a>

  <a class="hover-btn-shoulder" data-anatomy="shoulder" style="top:150px; left:180px;">
    <img src="https://s2.postimg.org/mzz5tybft/red-dot.png" />
  </a>

  <a class="hover-btn-hand" data-anatomy="hand" style="top:320px; left:170px;">
    <img src="https://s2.postimg.org/mzz5tybft/red-dot.png" />
  </a>


  <!-- Icons that are revealed on click of hover circles -->
  <div class="icon icon-face" style="top:70px; left:0">
    <p>Face</p>
  </div>

  <div class="icon icon-shoulder" style="top:150px; left:0">
    <p>Shoulder</p>
  </div>

  <div class="icon icon-hand" style="top:320px; left:0">
    <p>Hand</p>
  </div>

</div>
&#13;
&#13;
&#13;

JS Fiddle demo

与ES5兼容的方法,为了支持旧版本的Internet Explorer:

function showDetails() {
  let part = this.dataset.anatomy;
  document.querySelector('.icon-' + part).style.display = 'block';
}

// here we use Function.prototype.call(), to supply
// the array-like NodeList (returned from
// document.querySelectorAll()) as the object to be
// sliced into a new array by Array.prototype.call():
Array.prototype.slice.call(document.querySelectorAll('.icon'))

  // because we now have an Array, we can use the
  // Array.prototype.forEach() method to iterate over
  // the resulting Array:
  .forEach(function(icon) {

    // here we set the display property of the
    // current array-element ('icon') of the
    // array of DOM nodes/elements to 'none':
    icon.style.display = 'none'
});

// this works in exactly the same way as the above,
// but the returned Array is assigned to the 'parts'
// variable:
let parts = Array.prototype.slice.call(document.querySelectorAll('a[data-anatomy]'));

parts.forEach(function(part) {
  part.addEventListener('click', showDetails)
});

&#13;
&#13;
function showDetails() {
  let part = this.dataset.anatomy;
  document.querySelector('.icon-' + part).style.display = 'block';
}

Array.prototype.slice.call(document.querySelectorAll('.icon')).forEach(function(icon) {
  icon.style.display = 'none'
});

let parts = Array.prototype.slice.call(document.querySelectorAll('a[data-anatomy]'));

parts.forEach(function(part) {
  part.addEventListener('click', showDetails)
});
&#13;
.container {
  position: relative;
}

a {
  position: absolute;
  width: 50px;
  height: 50px;
}

a img {
  display: none;
  width: 100%;
  height: 100%;
}

a:hover img {
  display: block;
}

.icon {
  width: 100px;
  padding: 5px;
  background: blue;
  position: absolute;
  color: #fff;
  text-align: center;
  font-family: arial;
  border-radius: 10px;
}
&#13;
<div class="container">

  <!-- Background img of character-->
  <img src="https://s2.postimg.org/g9iokigk9/man_cartoon.jpg" width="500px" />

  <!-- Hover circles -->
  <a class="hover-btn-face" data-anatomy="face" style="top:80px; left:225px;">
    <img src="https://s2.postimg.org/mzz5tybft/red-dot.png" />
  </a>

  <a class="hover-btn-shoulder" data-anatomy="shoulder" style="top:150px; left:180px;">
    <img src="https://s2.postimg.org/mzz5tybft/red-dot.png" />
  </a>

  <a class="hover-btn-hand" data-anatomy="hand" style="top:320px; left:170px;">
    <img src="https://s2.postimg.org/mzz5tybft/red-dot.png" />
  </a>


  <!-- Icons that are revealed on click of hover circles -->
  <div class="icon icon-face" style="top:70px; left:0">
    <p>Face</p>
  </div>

  <div class="icon icon-shoulder" style="top:150px; left:0">
    <p>Shoulder</p>
  </div>

  <div class="icon icon-hand" style="top:320px; left:0">
    <p>Hand</p>
  </div>

</div>
&#13;
&#13;
&#13;

参考文献: