Условное отображение Js по щелчку мыши

#javascript #html #conditional-statements #addeventlistener

#javascript #HTML #условные операторы #addeventlistener #addeventlistener добавить eventlistener

Вопрос:

Я делаю онлайн-проект портфолио, где в разделе «обо мне» я хочу иметь 3 разные вкладки: жизнь, образование, опыт. При первой загрузке страницы будет видна первая страница, а после нажатия на другую текст появится вместо предыдущего.

 let about_me_data = [
    {
        "title": "Life",
        "text": "Nullam ac quam non risus dictum viverra non id massa. Donec rhoncus sem at leo iaculis, tempor facilisis sem porttitor. Praesent sit amet quam ultricies, vulputate odio hendrerit, dictum eros. Aenean mattis ultricies tempus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aliquam imperdiet dolor et dignissim luctus. Morbi laoreet tempor feugiat."
    },
    {
        "title": "Education",
        "text": "Sed malesuada porta quam. Proin pretium eu augue vitae pellentesque. Nullam volutpat urna ac tellus bibendum tincidunt. Maecenas ultrices et nunc consectetur cursus. Suspendisse varius vitae risus sed aliquam. Cras nisi leo, scelerisque at dolor sed, sagittis eleifend nisl. Etiam id arcu luctus, vehicula arcu id, dictum nisi. Nullam aliquet ultricies erat. Vivamus a ultrices velit, ac malesuada elit."
    },
    { 
        "title": "Experience",
        "text": "Integer non maximus arcu. Nullam ut odio quis ligula interdum consectetur. Aliquam dignissim eu nibh ut accumsan. Phasellus volutpat nibh lorem, ac efficitur justo cursus ut. Etiam sed rutrum elit. Aenean lacus velit, sollicitudin quis malesuada nec, vestibulum eu tortor. Aenean dapibus commodo nibh ac ornare."
    }
];

for (i = 0; i < about_me_data.length; i  ){
    let title = document.createElement('p');
    title.innerHTML = about_me_data[i].title;
    title.setAttribute('class', 'about-me-tabs hvr-underline-from-center');
    title.addEventListener('click', conditionalDisplay(i));
    document.getElementById('about-me-tabs-titles').appendChild(title);
};

function displayFirstTab(){
    let firstTab = document.createElement('p');
    firstTab.innerHTML = about_me_data[0].text;
    document.getElementById('about-me-tabs-text').appendChild(firstTab);
};
window.onload(displayFirstTab());

function conditionalDisplay(i) {
    let text = document.createElement('p');
    text.innerHTML = about_me_data[i].text;
    document.getElementById('about-me-tabs-text').appendChild(text);
};

  

Это то, что я пытался сделать.
Я просто не знаю, где мне следует написать функцию conditionalDisplay или что я должен передать ей — «i» или заголовок, на который нажат.

Другой способ, который я пробовал, это (все еще не работает):

 for (i = 0; i < about_me_data.length; i  ){
    title.addEventListener('click', conditionalDisplay(title.innerHTML));
};

function conditionalDisplay(title) {
    let text = document.createElement('p');
 
    if (title === about_me_data[0].title) {
        text.innerHTML = about_me_data[0].text;
        document.getElementById('about-me-tabs-text').appendChild(text);
    } else if (title === about_me_data[1].title) {
        text.innerHTML = about_me_data[1].text;
        document.getElementById('about-me-tabs-text').appendChild(text);
    } else if (title === about_me_data[2].title) {
        text.innerHTML = about_me_data[2].text;
        document.getElementById('about-me-tabs-text').appendChild(text);
    };
};
  
 <div id="about-me-tabs-titles"></div>
<div id="about-me-tabs-text"></div>
  

Здесь я пытаюсь отобразить свои тексты.

Используя приведенную выше попытку, отображаются все 3 текста текст из функции displayFirstTab. Мне нужен способ, позволяющий применять к ним скрытый / видимый стиль по одному и удалять его из предыдущего при нажатии на другой.

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

Что я делаю не так?

Комментарии:

1. Пожалуйста, добавьте соответствующий HTML-код

2. Добавлено в конце. Спасибо за чтение!

Ответ №1:

Вы можете попробовать использовать заголовок как класс элементов следующим образом:

 let about_me_data = [
    {
        "title": "Life",
        "text": "Nullam ac quam non risus dictum viverra non id massa. Donec rhoncus sem at leo iaculis, tempor facilisis sem porttitor. Praesent sit amet quam ultricies, vulputate odio hendrerit, dictum eros. Aenean mattis ultricies tempus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aliquam imperdiet dolor et dignissim luctus. Morbi laoreet tempor feugiat."
    },
    {
        "title": "Education",
        "text": "Sed malesuada porta quam. Proin pretium eu augue vitae pellentesque. Nullam volutpat urna ac tellus bibendum tincidunt. Maecenas ultrices et nunc consectetur cursus. Suspendisse varius vitae risus sed aliquam. Cras nisi leo, scelerisque at dolor sed, sagittis eleifend nisl. Etiam id arcu luctus, vehicula arcu id, dictum nisi. Nullam aliquet ultricies erat. Vivamus a ultrices velit, ac malesuada elit."
    },
    { 
        "title": "Experience",
        "text": "Integer non maximus arcu. Nullam ut odio quis ligula interdum consectetur. Aliquam dignissim eu nibh ut accumsan. Phasellus volutpat nibh lorem, ac efficitur justo cursus ut. Etiam sed rutrum elit. Aenean lacus velit, sollicitudin quis malesuada nec, vestibulum eu tortor. Aenean dapibus commodo nibh ac ornare."
    }
];

for (let i = 0; i < about_me_data.length; i  ){
  let title = document.createElement('p');
  title.innerHTML = about_me_data[i].title;
  title.setAttribute('class', 'about-me-tabs hvr-underline-from-center');
  //wrap the function call with anonymous function so that it can be called only when clicked
  title.addEventListener('click', function(){ conditionalDisplay(i, about_me_data[i].title)});
  document.getElementById('about-me-tabs-titles').appendChild(title);
  conditionalDisplay(i, about_me_data[i].title);
};

function displayFirstTab(){
  //get all p
  var all = document.querySelectorAll('#about-me-tabs-text p');
  //show first and hide rest
  all.forEach((i,idx) => idx==0? i.style.display="block":i.style.display="none");
};


function conditionalDisplay(i, cls) {
  //get all
  var all = document.querySelectorAll('#about-me-tabs-text p');
  //hide all
  all.forEach(i => i.style.display="none");
  //get the current element by maching the class
  var current = document.querySelector(`.${cls}`);
  if(current != null){
    //show the current element
    current.style.display="block"
  }
  else{
    //create element if not exist
    let text = document.createElement('p');
    text.innerHTML = about_me_data[i].text;
    text.classList.add(cls);
    document.getElementById('about-me-tabs-text').appendChild(text);
  }
};

displayFirstTab();  
 <div class="d-flex flex-row" id="about-me-tabs-titles"></div>
<div id="about-me-tabs-text"></div>  

Ответ №2:

В вашей кодовой базе есть некоторые ошибки:

  • window.onload должна быть функция, которая будет вызываться, когда страница и связанные с ней материалы уже загружены. Вы пытаетесь вызвать displayFirstTab немедленно, не дожидаясь события загрузки разметки;
  • Обычно каждый код, который взаимодействует с разметкой на странице, следует использовать только тогда, когда такая разметка готова. Вот почему я переместил код, который создает заголовки внутри window.onload ;
  • Поскольку у вас одновременно есть только один текст для выбранного заголовка , использовать его нет смысла appendChild . Вот почему я меняю его на изменение innerText свойства элемента;
  • У вас неправильное представление о том, как addEventListener это работает. Вам нужно передать функцию в качестве аргумента addEventListener , и эта функция будет вызвана, когда будет вызвано такое событие;

Вот исправленный:

     let about_me_data = [
        {
            "title": "Life",
            "text": "Nullam ac quam non risus dictum viverra non id massa. Donec rhoncus sem at leo iaculis, tempor facilisis sem porttitor. Praesent sit amet quam ultricies, vulputate odio hendrerit, dictum eros. Aenean mattis ultricies tempus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aliquam imperdiet dolor et dignissim luctus. Morbi laoreet tempor feugiat."
        },
        {
            "title": "Education",
            "text": "Sed malesuada porta quam. Proin pretium eu augue vitae pellentesque. Nullam volutpat urna ac tellus bibendum tincidunt. Maecenas ultrices et nunc consectetur cursus. Suspendisse varius vitae risus sed aliquam. Cras nisi leo, scelerisque at dolor sed, sagittis eleifend nisl. Etiam id arcu luctus, vehicula arcu id, dictum nisi. Nullam aliquet ultricies erat. Vivamus a ultrices velit, ac malesuada elit."
        },
        {
            "title": "Experience",
            "text": "Integer non maximus arcu. Nullam ut odio quis ligula interdum consectetur. Aliquam dignissim eu nibh ut accumsan. Phasellus volutpat nibh lorem, ac efficitur justo cursus ut. Etiam sed rutrum elit. Aenean lacus velit, sollicitudin quis malesuada nec, vestibulum eu tortor. Aenean dapibus commodo nibh ac ornare."
        }
    ];

    function displayFirstTab(){
        document.getElementById('about-me-tabs-text').innerText = about_me_data[0].text;
    }

    function conditionalDisplay(i) {
        return function() {
            document.getElementById('about-me-tabs-text').innerText = about_me_data[i].text;
        }
    }

    window.onload = function() {
        displayFirstTab();

        for (i = 0; i < about_me_data.length; i  ) {
            let title = document.createElement('p');
            title.innerHTML = about_me_data[i].title;
            title.setAttribute('class', 'about-me-tabs hvr-underline-from-center');
            title.addEventListener('click', conditionalDisplay(i));
            document.getElementById('about-me-tabs-titles').appendChild(title);
        }
    };
  

Для этой разметки:

 <div id="about-me-tabs-titles"></div>
<p id="about-me-tabs-text"></p>