Javascript - Make <article> appear by clicking on a <li>

Asked

Viewed 259 times

5

I have a little doubt in my project that I am developing.

I need to make that determined <article> appears when a certain <li>.

Example <li>'s

<li id="menu-CARD">USAR CARD</li>

<li id="menu-SLIP">USAR SLIP</li>

Example <article>'s

<article id="CARD">CONTEÚDO CARD</article>

<article id="SLIP">CONTEÚDO SLIP</article>

I need two things.

  • 1° When clicking on one of the <li>, be added to class "Selected" à <li> clicked. (class="selected")
  • 2° When clicking on a <li>, will be shown the <article> that is referred to that <li> that was clicked.

Example: by clicking on <li> "SLIP":

<li id="menu-SLIP">USAR SLIP</li>

Will be added a style="display:block" at the <article> id "SLIP":

<article id="SLIP">CONTEÚDO SLIP</article>

Thus remaining:

<article id="SLIP" style="display:block">CONTEÚDO SLIP</article>

Obsevation:

Its function will be similar to a tab.

When you click USE CARD, you will see the <article> id "CARD".

When you click USE SLIP, you will see the <article> id "SLIP".

That is, as long as one receives display:block, the other receives display:None.

3 answers

3


This code does the basics you need, but take a look at jQuery selectors, especially how to select elements by attributes.

var scrollDuration = 800; // 1000ms = 1 segundo

//ao clicar em uma <li>
$('li').click(function(){

  //pegamos a id do elemento clicado,
  //dividimos o nome da id no ponto "menu-" e
  // pegamos o lado da direita, de índice 1  

  var target = $(this).attr('id').split('menu-')[1];

  //remove classe do 'selected' do elemento com ela
  $('.selected').removeClass('selected');

  //adiciona classe no 'selected' no elemento clicado
  $(this).addClass('selected');  

  //escondemos o <article> com classe 'visible'  
  $('article.visible')
    .css('display','none')
    .removeClass('visible');

  //podemos concatenar a var target com '#', o que forma
  //uma query para o jquery: '#SLIP' ou '#CARD'
  $('#'+target)
    .css('display','block')
    .addClass('visible');

  //agora que o elemento está visível, vamos dar scroll até ele
  //http://stackoverflow.com/a/6677069/2467235      
  $('html, body').animate({
      scrollTop: $( '#'+target ).offset().top
  }, scrollDuration);

});

Another interesting alternative may be to add/remove classes that hide/show the elements. In the example I use a class called "Visible" to mark the current article. If in your css you put

.article{ /* todos os article's começam escondidos */
  display:none;
}
article.visible{ /* mostra um article que tenha a class visible */
  display:block;
}

It will not be necessary to use JS lines with .css('display','none')

  • Buddy, I tested your code. There are two problems, first, it gives the "display:None" in all the Articles of the page (is it possible to do somentes in Articles with a certain class? guy: <article class="este-pode") ?. Second, it does not remove the class "Selected". The correct is while one li stays with "Selected" the other is without "Selected".

  • Buddy, I solved the part where I choose which <articles> will receive the display:none, I switched to $('.essesim').css('display','none');... Now just need to make that only 1 <li> stay with the class=selected.

  • 1

    I adjusted this question in the answer, take a look.

  • It was perfect! Congratulations on your knowledge and for helping people with it! Thank you very much. I only have one additional question :3, it is possible to make that when the person clicks on the li, the screen descends to the beginning of the <li>? Very bomm!

  • Like that smooth scroll that makes hers go down <li> clicked.

  • 1

    The scroll can be implemented with this snippet here, I will include in the answer: http://stackoverflow.com/a/6677069/2467235

  • PERFECT!!! You are a genius!

Show 2 more comments

3

First of all, its elements <li> need to have a class. Second, you don’t need the attribute ID. Within the <li> put a <a> with a HREF pointing to the ID the <article>

Assign a property in the CSS so that the first appear as default and in the first <li> in the HTML as selected.

$('.showArticle > a').on('click', function(){
   var id = $(this).attr('href'); // Pega o HREF do A que é o ID do Article
   var articles = $('article');

   $('.showArticle').removeClass('selected'); // Remove a classe selected dos LIS
   $(this).parent().addClass('selected'); // Aplica a classe selected ao LI selecionado 

   articles.css('display', 'none'); // Esconde todos os Articles
   $(id).css('display', 'block'); // Mostra apenas o selecionado.
});
article{
    display: none;
}

section article:first-child{
    display: block; /* ou block */
}

ul li a{
    color: #000;
    text-decoration:none;
}

ul li.selected a{
  color: #F00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<ul>
  <li class="showArticle selected"><a href="#card">Tab 1</a></li>
  <li class="showArticle"><a href="#slip">Tab 2</a></li>
  <li class="showArticle"><a href="#folk">Tab 3</a></li>
</ul>

<section>
  <article id="card">Article 1</article>
  <article id="slip">Article 2</article>
  <article id="folk">Article 3</article>
</section>

3

The question looks more like a request, so I will answer only with an example code :p

var defaultArticle
var articles$ = {}

articles$[defaultArticle = "CARD"] = $("#CARD")
articles$.SLIP = $("#SLIP")

var selectArticle = identifier => {
  for (var i in articles) {
    var method = i === identifier ?
                 "show" : "hide"
    articles$[i][method]()
  }
}

var $lis;

var selectLi = identifier => {
  $lis.each(function(i) {
    var method = i === identifier ?
                 "addClass" : "removeClass"
    this[method]("selected")
  })
}

$lis.click(function() {
  var articleId = this.id.split('-')[1]
  selectArticle(articleId)
  selectLi(this.id)
})

/* Visualiza o article padrão */
selectArticle(defaultArticle)

/* e seleciona o li padrão (dá para melhorar essa seleção) */
selectLi($lis[0].id)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.