Function Optimization (probably with for loop)

4

I'm having difficulty developing when we talk about for ... The basics I can understand now in practice ... People have developed this code and I believe it can be reduced to a few lines with.

Notice that in the input range change it appears different buttons (the ones determined) and closes the open button divs. When we press these buttons he opens his div and closes the others.

If necessary, please provide the simplified code below!

Here begins Js

                      

        /* Dinâmica do Input Range */
        function updateTextInput(val) {

            /* Para controlar os Botões */
            if(val == 1){ 
                document.getElementById('um').style.display = "block";
                document.getElementById('dois').style.display = "block";
                document.getElementById('tres').style.display = "none";
                document.getElementById('quatro').style.display = "none";
                document.getElementById('cinco').style.display = "none";

            }
            if(val == 2){ 
                document.getElementById('um').style.display = "block";
                document.getElementById('dois').style.display = "block"; 
                document.getElementById('tres').style.display = "block";
                document.getElementById('quatro').style.display = "none";
                document.getElementById('cinco').style.display = "none";
            }
            if(val == 3){ 
                document.getElementById('um').style.display = "block";
                document.getElementById('dois').style.display = "block"; 
                document.getElementById('tres').style.display = "block";
                document.getElementById('quatro').style.display = "block";
                document.getElementById('cinco').style.display = "none";
            }
            if(val == 4){ 
                document.getElementById('um').style.display = "block";
                document.getElementById('dois').style.display = "block"; 
                document.getElementById('tres').style.display = "block";
                document.getElementById('quatro').style.display = "block";
                document.getElementById('cinco').style.display = "block";
            }

            /* Para controlar as Slide's Div */
            document.getElementById('slideum').style.display = "none";
            document.getElementById('slidedois').style.display = "none"; 
            document.getElementById('slidetres').style.display = "none";
            document.getElementById('slidequatro').style.display = "none";
            document.getElementById('slidecinco').style.display = "none";
        }

        /* Dinâmica do Input Button */
        function slideumf(){
            document.getElementById('slideum').style.display = "block";
            document.getElementById('slidedois').style.display = "none"; 
            document.getElementById('slidetres').style.display = "none";
            document.getElementById('slidequatro').style.display = "none";
            document.getElementById('slidecinco').style.display = "none";
        }
        function slidedoisf(){
            document.getElementById('slideum').style.display = "none";
            document.getElementById('slidedois').style.display = "block"; 
            document.getElementById('slidetres').style.display = "none";
            document.getElementById('slidequatro').style.display = "none";
            document.getElementById('slidecinco').style.display = "none";
        }
        function slidetresf(){
            document.getElementById('slideum').style.display = "none";
            document.getElementById('slidedois').style.display = "none"; 
            document.getElementById('slidetres').style.display = "block";
            document.getElementById('slidequatro').style.display = "none";
            document.getElementById('slidecinco').style.display = "none";
        }
        function slidequatrof(){
            document.getElementById('slideum').style.display = "none";
            document.getElementById('slidedois').style.display = "none"; 
            document.getElementById('slidetres').style.display = "none";
            document.getElementById('slidequatro').style.display = "block";
            document.getElementById('slidecinco').style.display = "none";
        }
        function slidecincof(){
            document.getElementById('slideum').style.display = "none";
            document.getElementById('slidedois').style.display = "none"; 
            document.getElementById('slidetres').style.display = "none";
            document.getElementById('slidequatro').style.display = "none";
            document.getElementById('slidecinco').style.display = "block";
        }
    </script>

Here begins CSS

        /* Style Inicial dos Inputs Button */
        #um{display: none;}
        #dois{display: none;}
        #tres{display: none;}
        #quatro{display: none;}
        #cinco{display: none;}

        /* Style Inicial das Div's dos Slides */
        #slideum{display: none;}
        #slidedois{display: none;}
        #slidetres{display: none;}
        #slidequatro{display: none;}
        #slidecinco{display: none;}
    </style>
</head>

Here begins HTML5

          <input type="range" name="rangeInput" min="1" max="4" onchange="updateTextInput(this.value);">
         <input id="um" type="button" value="1º Slide" onclick="slideumf()">
         <div id="slideum">
         <input type="range" min="1" max="5"><div id="slideum">1º Slide</div>
    <input id="dois" type="button" value="2º Slide" onclick="slidedoisf()">
    <div id="slidedois">2º Slide</div>
    <input id="tres" type="button" value="3º Slide" onclick="slidetresf()">
    <div id="slidetres">3º Slide</div>
    <input id="quatro" type="button" value="4º Slide" onclick="slidequatrof()">
    <div id="slidequatro">4º Slide</div>
    <input id="cinco" type="button" value="5º Slide" onclick="slidecincof()">
    <div id="slidecinco">5º Slide</div>
</body>

    
asked by anonymous 24.01.2017 / 22:47

2 answers

5

This code can be very reduced ... it has huge repetition there.

Suggestion (with slight modifications to HTML% like% see example below):

var slides = Array.from(document.querySelectorAll('input[type="button"]'));
var slideTexts = Array.from(document.querySelectorAll('div'));

/* Dinâmica do Input Range */
function onSliderChange(val) {
    slides.forEach(function(slide, i) {
        slide.style.display = i <= val ? 'block' : 'none';
    });
    toggleSlidetext();
}

function toggleSlidetext(id) {
    var which = document.getElementById(id);
    slideTexts.forEach(function(div) {
        div.style.display = div == which ? 'block' : 'none';
    });
}

Explanation:

The idea is to put the elements in memory. -> and slides that's right, arrais with pointers to the elements.

When slideTexts is called, it traverses all onSliderChange and compares the index ( slides ) with the i that is passed to it. Then it calls val with no value, to hide all.

The logic of toggleSlidetext is similar. It traverses all elements and compares if the toggleSlidetext to be iterated is the same as div . We could also compare this way:

div.style.display = div.id == id ? 'block' : 'none';

and dispense with the logic of which .

Example: link

var slides = Array.from(document.querySelectorAll('input[type="button"]'));
var slideTexts = Array.from(document.querySelectorAll('div'));

/* Dinâmica do Input Range */
function onSliderChange(val) {
    slides.forEach(function(slide, i) {
        slide.style.display = i <= val ? 'block' : 'none';
    });
    toggleSlidetext();
}

function toggleSlidetext(id) {
    var which = document.getElementById(id);
    slideTexts.forEach(function(div) {
        div.style.display = div == which ? 'block' : 'none';
    });
}
/* Style Inicial dos Inputs Button */

#um {
    display: none;
}

#dois {
    display: none;
}

#tres {
    display: none;
}

#quatro {
    display: none;
}

#cinco {
    display: none;
}


/* Style Inicial das Div's dos Slides */

#slideum {
    display: none;
}

#slidedois {
    display: none;
}

#slidetres {
    display: none;
}

#slidequatro {
    display: none;
}

#slidecinco {
    display: none;
}
<input type="range" name="rangeInput" min="1" max="4" onchange="onSliderChange(this.value);">
<input id="um" type="button" value="1º Slide" onclick="toggleSlidetext('slideum')">
<div id="slideum">1º Slide</div>
<input id="dois" type="button" value="2º Slide" onclick="toggleSlidetext('slidedois')">
<div id="slidedois">2º Slide</div>
<input id="tres" type="button" value="3º Slide" onclick="toggleSlidetext('slidetres')">
<div id="slidetres">3º Slide</div>
<input id="quatro" type="button" value="4º Slide" onclick="toggleSlidetext('slidequatro')">
<div id="slidequatro">4º Slide</div>
<input id="cinco" type="button" value="5º Slide" onclick="toggleSlidetext('slidecinco')">
<div id="slidecinco">5º Slide</div>
    
24.01.2017 / 23:05
3

Your code has some CSS issues (and, as @Sergio explained in his response) a lot of repetition. As your question is "how to optimize the function" I decided to give another one. ( link for example in JSBin )

We started by redesigning your HTML: a slide, in fact, is nothing more than a section of your site. In your case, with a button that toggle the content.

<input type="range" value="6" name="rangeInput" min="1" max="6" onchange="onSliderChange(this.value);" />
<section class="slide-wrap">
    <button class="toggle-slide" onclick="toggleSliderContent(this)">1º Slide</button>
    <div class="slide-content hidden">Conteudo do 1º Slide</div>
</section>

Removing Ids and adding classes means that not only is our CSS much smaller but our javascript is more concise - since we can point to multiple elements at once.

All classes in the section above, with the exception of hidden , are for our Javascript.

Then, we add to CSS the simple rule of .hidden { display:none }

Let's now go to Javascript: Now that we have a better HTML and we already have the onclick of the button, let's attack that first one:

/** Quando clicamos no botão de mostrar o slide, o botão envia-se a ele mesmo
* como argumento, depois é só subirmos a DOM Tree até ao elemento parente e descermos
* à procura do element que contém o conteúdo do slide. Procuramos depois por um
* elemento que seja "slide-content" mas que não tenha a class "hidden" (e podemos 
* assumir que esse é o element que está visivel) - se este existir, então adicionarmos
* a class "hidden" e por fim removemos a class "hidden" do slide que queremos mostrar
*/
function toggleSliderContent(element) {
  var showSlideContent = element.parentNode.querySelector('.slide-content');
  var hidePrevious = document.querySelector('.slide-content:not(.hidden)');
  if (hidePrevious) hidePrevious.classList.add('hidden');
  showSlideContent.classList.remove('hidden');
}

We've enclosed the functionality with the reference of onchange of the input:

var slides = document.querySelectorAll('section.slide-wrap');
/** Podias estar tentado a fazer um cast desta NodeList para array
* mas existem iteradores expecificos para a NodeList */

function onSliderChange(number) {
  var entry, slideElement, slideIndex;

  /** Para cada node na lista de slides, */
  for (entry of slides.entries()) {
    slideElement = entry[1];
    slideIndex = entry[0];

    /** se o index do slide que estamos a ver for menor que o numero
    * de slides que queremos mostrar e o elemento tiver a class "hidden"
    * então, remove a class para esse elemento aparecer: */
    if (slideIndex <= number && slideElement.classList.contains('hidden')) {
      slideElement.classList.remove('hidden');
    } else if (slideIndex >= number && !slideElement.classList.contains('hidden')) {
      /** de contrario, adiciona a class "hidden" para o elmento desaparecer */
      slideElement.classList.add('hidden');
    }
  }
}
    
25.01.2017 / 03:39