Как использовать JaveScript для имитации пользовательского фильтра / селектора в этом примере? - PullRequest
0 голосов
/ 14 мая 2019

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

Код таблицы, с которой я играю, слишком длинный, поэтому я просто поместил его здесь .


[2019-05-15]

После того, как я изменил свой код на основе примера @ Kévin Bibollet, я столкнулся с новой проблемой.

Вот мой код js, только что добавил новую функцию в одну кнопку для тестирования.

//different types of data from the table
const type = document.querySelectorAll("tr td:nth-last-child(1)");
const kiwameStats = document.querySelectorAll("tr td:nth-last-child(2)");

//buttons
const tantouFilter = document.querySelector("div#Tantou");
const wakiFilter = document.querySelector("div#Wakizashi");
const tokuFilter = document.querySelector("div#Toku");
const kiwameFilter = document.querySelector("div#Kiwame");

//path for buttons' image
const waki = "https://vignette.wikia.nocookie.net/a-normal-playground/images/b/b8/Wakizashi.png";
const wakiClicked = "https://vignette.wikia.nocookie.net/a-normal-playground/images/1/1f/Wakizashi-full.png";

//bind events to buttons
wakiFilter.addEventListener("click", () => (filter(waki, wakiClicked, type)));

//general filter method
function filter(unclickedImageSrc, clickedImageSrc, data){
    //store button's img and img's src for future use
    currentImg = this.querySelector("img");
    currentImgSrc = currentImg.getAttribute("src");
    //is the button being clicked
    isFiltered = (currentImgSrc === clickedImageSrc);
    if(isFiltered){ //button was clicked, undo the filtering
        currentImg.setAttribute("src", unclickedImageSrc);
        for(i = 0; i < data.length; i++){
            if(!data[i].innerHTML.includes(this.id)){ 
                data[i].parentElement.style.display = " ";
            }
        }
    }else{ //button isn't clicked, start filtering
        currentImg.setAttribute("src", clickedImageSrc);
        for(i = 0; i < data.length; i++){
            if(!data[i].innerHTML.includes(this.id)){ 
                data[i].parentElement.style.display = "none";
            }
        }
    }
}

Когда я помещаю их в свой файл common.js и пробую его на тестовой странице , моя консоль сообщает Ошибка: ошибка синтаксического анализа JavaScript: ошибка синтаксического анализа: отсутствует) в скобках в файле 'Пользователь: somebody / common.js 'в строке 16 , которая является строкой, которая связывает прослушиватель событий с кнопкой ( wakiFilter.addEventListener ("click", () => (фильтр (waki, wakiClicked, введите))); )

Затем я бросил код в консоль и после нажатия кнопки получил: TypeError: this.querySelector не является функцией .

Не уверен, что вызвало это. Я пишу свою функцию стрелки неправильно или ...?


[2019-05-14]

Я понял, как использовать addEventListener() для фильтрации определенных столбцов одним щелчком мыши. Добавлено две кнопки для целей тестирования:

//type filter
var type = document.querySelectorAll("tr td:nth-last-child(1)");

//for tantou
const tantouFilter = document.getElementById("Tantou");
tantouFilter.addEventListener("click", function(e){
    for(i = 0; i < type.length; i++){
    if(!type[i].innerHTML.includes(tantouFilter.id)){
        type[i].parentElement.style.display = "none";
    }
  }
});
//for wakizashi
const wakiFilter = document.getElementById("Wakizashi");
wakiFilter.addEventListener("click", function(e){
    wakiFilter.innerHTML = "[[File:Wakizashi-full.png|30px|link=]]";
    for(i = 0; i < type.length; i++){
    if(!type[i].innerHTML.includes(wakiFilter.id)){
        type[i].parentElement.style.display = "none";
    }
  }
});

Во второй функции я одновременно пытался изменить изображение этой кнопки, но я получил:

До щелчка

После нажатия

А сейчас я хочу знать:

- Как изменить изображение кнопки при нажатии?

- Как отменить эту фильтрацию вторым нажатием на ту же кнопку?

И возможно ли переформатировать эту функцию фильтра, чтобы все кнопки могли использовать одну и ту же функцию?

Кстати, я использовал мой личный файл common.js для тестирования, потому что в общедоступном вики-файле Fandom common.js требуется время, чтобы они проверили его перед публикацией.

Если вы хотите поиграть с кодом, просто скопируйте и вставьте мой код в ваш личный файл common.js.

1 Ответ

0 голосов
/ 15 мая 2019

Ваше изображение не обновляется, потому что вы вставили тег " Fandom " для замены HTML вашего элемента.

Сначала это была хорошая идея, но вам нужно знать, что, скажем, " Фэндом страницы ", безусловно, преобразуются в HTML на стороне сервера, и что ваш браузер получает только HTML. Я не совсем уверен в том, что я только что сказал, но думаю, что это процесс.

Объясняется просто, когда вы добавляете теги " Fandom " после загрузки страницы, они не переводятся в HTML, потому что механизм шаблонов не вызывается.

Итак, чтобы обновить ваше изображение, вероятно, есть элемент <img> в элементе, который получает прослушиватель событий. Это атрибут [src] того элемента изображения, который необходимо обновить.

После просмотра дерева DOM вашей страницы, я думаю, вам придется самостоятельно найти правильные URL-адреса изображений.


Теперь, чтобы ответить на ваш вопрос:

  • Вы можете получить значение атрибута элемента с помощью HTMLElement#getAttribute.
  • Вы можете обновить значение атрибута элемента с помощью HTMLElement#setAttribute.

И с помощью оператора if вы можете проверить, какое изображение отображается в данный момент, а затем выбрать изображение для показа.

Чтобы иметь уникальную функцию для всех ваших фильтров, просто создайте ее и используйте в своем прослушивателе событий.

document.querySelector('#Tantou').addEventListener('click', function() {
  filter(this, 'url/to/tantou.png', 'url/to/tantou-filtered.png');
});

document.querySelector('#Wakizashi').addEventListener('click', function() {
  filter(this, 'url/to/wakizashi.png', 'url/to/wakizashi-filtered.png');
});

/**
 * @param {HTMLElement} clickedElement - The element that triggered the event.
 * @param {string} imageSrc - The URL of the picture when it is NOT active/clicked.
 * @param {string} imageSrcFiltered - The URL of the picture when it is active/clicked.
 */
function filter(clickedElement, imageSrc, imageSrcFiltered) {
  const types = document.querySelectorAll("tr td:nth-last-child(1)"),
  // Gets the <img> tag.
    imageElement = clickedElement.querySelector('img'),
  // Gets the current [src] attribute's value of the <img>.
    currentImageSrc = imageElement.getAttribute('src'),
  // It is filtered if the current image URL is the same as the one when it is filtered.
    isFiltered = (currentImageSrc === imageSrcFiltered);

  // If filtered, displays the lines.
  if (isFiltered) {
    // Replaces the image URL.
    imageElement.setAttribute('src', imageSrc);
    // ---- Code snippet testing purpose here!
    imageElement.setAttribute('alt', imageSrc.split('/').pop());

    for(let i = 0; i < types.length; i++) {
      if (!types[i].innerHTML.includes(clickedElement.id)) {
        // Sets a CSS style to an empty string to reset its value.
        types[i].parentElement.style.display = '';
      }
    }
  } // If not, hides the lines.
  else {
    // Replaces the image URL.
    imageElement.setAttribute('src', imageSrcFiltered);
    // ---- Code snippet testing purpose here!
    imageElement.setAttribute('alt', imageSrcFiltered.split('/').pop());

    for(let i = 0; i < types.length; i++) {
      if (!types[i].innerHTML.includes(clickedElement.id)) {
        types[i].parentElement.style.display = 'none';
      }
    }
  }
}
<div id="Tantou">
  <img src="url/to/tantou.png" alt="tantou.png">
</div>

<div id="Wakizashi">
  <img src="url/to/wakizashi.png" alt="wakizashi.png">
</div>

<table>
  <thead>
    <tr>
      <th>ID</th>
      <th>A column</th>
      <th>Column checked by filters</th>
    </tr>
  </thead>
  
  <tbody>
    <tr>
      <td>1</td>
      <td>Cell</td>
      <td>Tantou</td>
    </tr>
    
    <tr>
      <td>2</td>
      <td>Cell</td>
      <td>OtherFilter</td>
    </tr>
    
    <tr>
      <td>3</td>
      <td>Cell</td>
      <td>Wakizashi</td>
    </tr>
  </tbody>
</table>

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

...