How to create function with SINGLE BUTTON to open multiple class together?

Asked

Viewed 155 times

0

In the current function below, opens an ID (title) in each click.

And you can open several if you click on each.

It is great and working perfect (I believe)

But I I need to have a single separate button that opens all together and close all.

(and maintain the current open/close function each)

I thought of using the class="align", which is common in all titles but, for days I searched, I tested several examples and could not. Help an old apprentice avoid a stroke.

Thank you all for your help.

ps: is it possible to further reduce functions? I think it is redundant.

<script src="/1.3.1/jquery.min.js"></script>
<script>
$(document).ready(function(){ //aqui troca a cor do titulo
$('.cor').click(function(){
$trClass = $(this).attr('class');
	if ($trClass == undefined || $trClass == 'desclicado'){
	$(this).attr('class', 'clicado');
	}else{
		$(this).attr('class', 'desclicado');
        }
	});
});
function abre(ab){ //aqui abre e fecha cada uma
if	(document.getElementById(ab).style.display=='block')
	{document.getElementById(ab).style.display='none';}
else{document.getElementById(ab).style.display='block';}
}
</script>

PHP/HTML5
$consulta=$pdo->query("select titulo,texto from...
while...
<div class="alinha" onclick="abre('texto<?=$id?>')"><span class="cor"><b><?=$titulo?></b></span>
	<span id="texto<?=$id?>" style="display:none">
	<div>TEXTO</div>
	</span>
</div>	

4 answers

2


You could make a single button that controls the open/close state, but in my humble opinion, the state control for a button that opens and closes time all elements is somewhat confusing, whether for the developer or user. Because, time you can have all the elements open and the status marked is closed, and you click the button and did the opposite of what you expected

In that case, I suggest creating two buttons with specific functions, one to open all and the other to close all.

The first step is to define HTML. You will need to create both buttons and set a class to the span you want to show/hide. It is not required to set the class, but it will facilitate.

$(document).ready(function(){
    $('#exibir-todos').click(function(){
        $('.alinha .texto').show();
    });
    $('#esconder-todos').click(function(){
        $('.alinha .texto').hide();
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js"></script>
<button type="button" id="exibir-todos" >exibir todos</button>
<button type="button" id="esconder-todos" >esconder todos</button>

<div class="alinha">
  <span class="cor">cor</span>  
  <span class="texto">texto</span>  
</div>

<div class="alinha">
  <span class="cor">cor</span>  
  <span class="texto">texto</span>  
</div>

<div class="alinha">
  <span class="cor">cor</span>  
  <span class="texto">texto</span>  
</div>

<div class="alinha">
  <span class="cor">cor</span>  
  <span class="texto">texto</span>  
</div>

Javascript was written using jQuery 1.3.1, as in your example.

The same example is also available on codepen.io using more current jQuery.

Update

Comments questioned the difference between jQuery 1.3.1 and 3.2.1 and the use of an entire library to use only a single function.

About the differences between library versions, can be viewed in the links below:

What is the Difference with jquery version 1, version 2 and version 3 versions release?

jQuery 3.0: The Next Generations

Briefly (free translation of the first link):

  • jQuery 1: the first stable version;
  • jQuery 2: removed IE 6-8 support for performance gain and library size reduction;
  • jQuery 3: Support Promises/A+ for Deferreds, $.ajax and $.when. .data() HTML5 compatible.

What should be borne in mind is that jQuery has as its main purpose to normalize differences and provide compatibility between browsers and between different versions of the same browser. Next, it is to provide functions that facilitate the work of a developer and reduce the development code. Facilitation which can be compared to syntactic sugar (although this is not the case).

However, I agree with the size generated by the library for something so simple. The example was only developed with jQuery, because in the question example it was already used. Which ultimately left the answer/function more "lean".

In this case, your problem can also be solved with pure javascript, with a little more code:

function addListener(elem, type, fn) {
    if (elem.addEventListener) {
        elem.addEventListener(type, fn, false);

    } else if (elem.attachEvent) {
        elem.attachEvent("on" + type, function() {
            return fn.call(elem, window.event);
        });
    } else {
        elem["on" + type] = fn;
    }
}

var exibirTodos = document.getElementById('exibir-todos');

var callbackExibirTodos = function() {
  var elements = document.getElementsByClassName('texto');
  
  for(var i = 0; i < elements.length ; i++)
  {
    elements[i].style.display='inline';
  }
};

addListener(exibirTodos , 'click' , callbackExibirTodos);

var esconderTodos = document.getElementById('esconder-todos');

var callbackEsconderTodos = function() {
  var elements = document.getElementsByClassName('texto');
  
  for(var i = 0; i < elements.length ; i++)
  {
    elements[i].style.display='none';
  }
};
addListener(esconderTodos , 'click' , callbackEsconderTodos);
<button type="button" id="exibir-todos" >exibir todos</button>
<button type="button" id="esconder-todos" >esconder todos</button>

<div class="alinha">
  <span class="cor">cor</span>  
  <span class="texto">texto</span>  
</div>

<div class="alinha">
  <span class="cor">cor</span>  
  <span class="texto">texto</span>  
</div>

<div class="alinha">
  <span class="cor">cor</span>  
  <span class="texto">texto</span>  
</div>

<div class="alinha">
  <span class="cor">cor</span>  
  <span class="texto">texto</span>  
</div>

To improve function compatibility addEventListener, the function developed has been used in this answer stack overflow.

What was created, in the final answer, was practically the same thing that was developed using jQuery. Add an event to each button with its respective callback (display/hide).

  • Gabriel, it worked for 1, congratulations. Can you tell me which is the most current version of Jquery, which you used in codepen? Is it lighter? Do you have in Google CDN? Thank you for your valuable time

  • I’ve seen it’s 3.2.1. This is lighter and faster than the 1.3.1 I use?

  • @Newer Geo does not mean faster or lighter, however, it is very likely to be more stable and have more implementations/Features.

  • Gabriel, my use is only for your function. Vi that 321 has 85Kb and 131 has +-52kb. I know there’s a lot of resources in Jq, but it’s the same thing as taking a pound of sugar in a trailer. I still haven’t found a place that explains the differences of versions to use the smallest possible. Abs.

  • @Geo the response has been updated.

  • Gabriel, you’re a genius... and you urged me to study JQ. I was impressed with the resources. I’ve applied some, using your function as a basis. It’s actually much easier to operate. I’m excited to "play" with the functions. I won’t take up your precious time anymore. Thank you very much for your attention.

Show 1 more comment

1

You can use the property slideToggle and slideDown of Jquery

$( "button" ).click(function() {
  if(!$(this).hasClass('todos')){
    $( this ).prev('.cor').slideToggle( "fast" );
  }else{
    $('.cor').slideDown( "fast" );
  }
});
.ctn {
  display: flex;
}
.cor {
  height: 58px;
  width: 58px;
  display: none;
}
.verde{
  background: green;
}
.amarelo{
  background: yellow;
}
.azul{
  background: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="ctn">
  <div class="items">
     <div class="verde cor">
       
     </div>
     <button>
       Ver cor
     </button>
  </div>
  <div class="items">
     <div class="azul cor">
       
     </div>
     <button>
       Ver cor
     </button>
  </div>
  <div class="items">
     <div class="amarelo cor">
       
     </div>
     <button>
       Ver cor
     </button>
  </div>
  <div class="items">
     <button class="todos">
       Ver todos
     </button>
  </div>
</div>

If you do not want the transition pass 0 as parameter.

  • Sannyas, thank you for your attention, but unfortunately it is not this function (very beautiful). See in my template what color refers to the title, which changes as it opens or closes individually. There are no buttons on the titles, there is onclick. I just need a separate button at the top or footer that opens and closes everything. I tried to adapt your suggestion but did not. I still need to learn a lot. I appreciate your help. Abs

1

You can put a class in the tags <span/>

<div class="alinha" onclick="abre('texto<?=$id?>')"><span class="cor"><b><?=$titulo?></b></span>
    <span id="texto<?=$id?>" class="alinha-texto" style="display:none">
        <div>TEXTO</div>
    </span>
</div>

With this class you can change the property display of all elements alinha-texto using the following function

function abreOuFechaTextos() {
    var textos = document.getElementsByClassName('alinha-texto');
    Array.prototype.forEach.call(textos, (el) => el.style.display = (el.style.display === 'none') ? 'block' : 'none');
}

Follow an example:

    function abreOuFechaTextos() {
        var textos = document.getElementsByClassName('alinha-texto');
        Array.prototype.forEach.call(textos, (el) => el.style.display = (el.style.display === 'none') ? 'block' : 'none');
    }
<button onclick="abreOuFechaTextos()">Botão</button>

<div class="alinha" onclick="abre(texto-1)"><span class="cor"><b><?=$titulo?></b></span>
    <span id="texto-1" class="alinha-texto" style="display:none">
        <div>TEXTO</div>
    </span>
</div>


<div class="alinha" onclick="abre(texto-2)"><span class="cor"><b><?=$titulo?></b></span>
    <span id="texto-2" class="alinha-texto" style="display:none">
        <div>TEXTO 2</div>
    </span>
</div>


<div class="alinha" onclick="abre(texto-3)"><span class="cor"><b><?=$titulo?></b></span>
    <span id="texto-3" class="alinha-texto" style="display:none">
        <div>TEXTO 3</div>
    </span>
</div>


<div class="alinha" onclick="abre(texto-4)"><span class="cor"><b><?=$titulo?></b></span>
    <span id="texto-4" class="alinha-texto" style="display:none">
        <div>TEXTO 4</div>
    </span>
</div>

<div class="alinha" onclick="abre(texto-5)"><span class="cor"><b><?=$titulo?></b></span>
    <span id="texto-5" class="alinha-texto" style="display:none">
        <div>TEXTO 5</div>
    </span>
</div>

  • I thank you all for the quick responses. I will test and soon return. Thanks for the help. Abs

  • André Luiz, I started with your suggestion and it worked on 1st. Congratulations. Now I’m going to the others. I foresee that it will be difficult to choose.

  • @Geo you better make the comment in his reply, so get a notification to him.

  • Thanks for the tip, I’m still "new" here, but I learn fast. Abs

0

André and Gabriel: Your guidelines were great and functional and helped me a lot. I thank you for your help and I consider myself satisfied.

Gabriel, your attention and patience are commendable. I am studying Jquery and discovered numerous resources that help a lot.

And thanks to stackoverflow we can expand our knowledge

Thank you all.

Browser other questions tagged

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