0

Итак, я пытаюсь объединить Javascript для моего сайта портфолио фотографий. Моя цель - нажать кнопку, обозначенную Show Only Sunsets, и скрыть каждое изображение без класса Sunsets. Код, который я придумал ниже, ALMOST работает, но есть главный недостаток:Ориентация на одну из нескольких классов/только часть класса string - className vs classList

Этот код сохраняет только видимость изображений, таких как «1.jpg» ниже, чей класс точно/только «Sunsets» (или «Sunsets») NSFW "или что-то еще). Но часто мне нужно давать изображения более одного класса, например, чтобы отличать вертикали или изображения, которые попадают в несколько категорий. Поэтому мне нужен код, чтобы сохранить видимость любого изображения, такого как «2.jpg», ниже которого есть «Sunsets» (или что-то еще) в любом месте своего класса.

JS:

<script> 
     function filterOn(imageClass) { 
      var image = document.getElementsByTagName('figure'); 
      for (i = 0; i < image.length; i++) { 
       if (image[i].className != imageClass) { 
        image[i].style.display = 'none'; 
       } 
      } 
      document.getElementById(imageClass + '-off').innerHTML = 'Undo Filter'; 
      document.getElementById(imageClass + '-off').setAttribute('onClick', "filterOff('" + imageClass + "')"); 
      document.getElementById(imageClass + '-off').id = imageClass + '-on'; 
     } 
     function filterOff(imageClass) { 
      var image = document.getElementsByTagName('figure'); 
      for (i = 0; i < image.length; i++) { 
       if (image[i].className != imageClass) { 
        image[i].style.display = 'inline-block'; 
       } 
      } 
      document.getElementById(imageClass + '-on').innerHTML = 'Show Only ' + imageClass; 
      document.getElementById(imageClass + '-on').setAttribute('onClick', "filterOn('" + imageClass + "')"); 
      document.getElementById(imageClass + '-on').id = imageClass + '-off'; 
     } 
    </script> 

HTML:

<ul> 
     <li id="Sunsets-off" onClick="filterOn('Sunsets')">Show Only Sunsets</li> 
     <li id="NSFW-off" onClick="filterOn('NSFW')">Show Only NSFW</li> 
    </ul> 
    <img class="Sunsets" src="1.jpg"> 
    <img class="vertical Sunsets" src="2.jpg"> 
    <img class="NSFW vertical" src="3.jpg"> 
    <img class="Architectural" src="4.jpg"> 
    <img class="Sunsets Landscapes" src="5.jpg"> 
    <img class="Abstract" src="6.jpg"> 
    <img class="NSFW LondonAndrews" src="7.jpg"> 
+1

придираться: не устанавливать события с SetAttribute. Для этого используется addEventListener. – epascarello

+1

Вы пропустили «imageclass» в последней строке filterOff() и почему ваш код обнаружил «фигурный» тег? Я думаю, что это должно быть «img». – margincall

+0

@epascarello Спасибо! Я был знаком только с синтаксисом getElementById.innerHTML, который использовался для статического атрибута, поэтому, когда я обнаружил, что это не работает для атрибута onClick, я в основном угадывал/Googling. Можете ли вы дать мне точный синтаксис? –

ответ

1

Этот тест:

if (image[i].className != imageClass) { 

действительно будет делать чек со строкой целого класса. Там в classList API для делать то, что вы хотите, заменив тест с:

if (!image[i].classList.contains(imageClass)) { 
+0

Вот что мне нужно! Большое спасибо!! –

+0

Добро пожаловать – lleaff

1

Я бы упростить ее, добавив имя класса для всех изображений, так что вы можете легко настроить таргетинг на все изображения, а затем использовать переключены класс скрыть изображения, которые вы не хотите видеть. это также дает вам возможность использовать анимацию css3 для выцветания изображений, которые вы не хотите видеть.

function filterOn(clazz){ 
 
    // get all the images using the additional img class 
 
    var images = slice(document.getElementsByClassName('img')); 
 
    // hide all the images 
 
    var ret = images.map(function(image){ 
 
    image.classList.add('hide'); 
 
    return image; 
 
    }) 
 
    // reduce the images to only contain those you want to show 
 
    .filter(function(image){ 
 
    return image.classList.contains(clazz); 
 
    }) 
 
    // show the image by removing the hide class 
 
    .forEach(function(image){ 
 
    image.classList.remove('hide'); 
 
    }); 
 
} 
 

 
// show all images 
 
function showAll(){ 
 
    var images = slice(document.getElementsByClassName('img')); 
 
    images.forEach(function(image){ 
 
    image.classList.remove('hide'); 
 
    }); 
 
} 
 
// helper function to get an array from an array like object 
 
function slice(arrayLike){ 
 
    return Array.prototype.slice.call(arrayLike); 
 
}
.img { 
 
    display: block; 
 
    float: left; 
 
    margin-left: .8em; 
 
    border: .3em solid #aaa; 
 
} 
 

 
.hide { 
 
    display: none; 
 
} 
 

 
.filters { 
 
    display: block; 
 
    width: 100%; 
 
    float: left; 
 
} 
 

 
.Sunsets { 
 
    border: .3em solid orange; 
 
} 
 

 
.NSFW { 
 
    border: .3em solid magenta; 
 
}
<nav class="filters"> 
 
    <button id="Sunsets-off" onClick="filterOn('Sunsets')">Show Only Sunsets</button> 
 
    <button id="NSFW-off" onClick="filterOn('NSFW')">Show Only NSFW</button> 
 
    <button id="show-all" onClick="showAll()">Show All</button> 
 
</nav> 
 
<!-- I added an img class to the images for ease of use later --> 
 
<section class="images"> 
 
    <img class="img Sunsets" src="http://placehold.it/50/50"> 
 
    <img class="img vertical Sunsets" src="http://placehold.it/50/50"> 
 
    <img class="img NSFW vertical" src="http://placehold.it/50/50"> 
 
    <img class="img Architectural" src="http://placehold.it/50/50"> 
 
    <img class="img Sunsets Landscapes" src="http://placehold.it/50/50"> 
 
    <img class="img Abstract" src="http://placehold.it/50/50"> 
 
    <img class="img NSFW LondonAndrews" src="http://placehold.it/50/50"> 
 
</section>