Combine Multiple Click and Keypress Functions - Jquery Optimization

Viewed 52

What I am doing: I've created a troubleshooting guide where you have multiple choice options that you click or press a key in order to move on to the next section in the guide.

What I need Help with: The code works fine, however it's rather bloated at 1000+ lines already with 144 statements currently. As I expand upon the guide this will only continue to balloon in size. I am a novice in Jquery and I am hoping there is a better solution to implementing this code that will use much less resources than it does right now.

I am hoping there's a better way to combine all of this. If you wonder why clicks, buttons, and Options are all separated it's because of differences in styling in CSS. I have included a link to the sampling of the code in case you would like a visual of how it should play out.

https://jsfiddle.net/wsyho3qz/

Example HTML

<div id="page1">
    <p>Introduction & Welcome Message to Guide.</p>
    <button id="button1">Enter</button>
    <div class="KB-Enter" id="click_0">press Enter</div>
</div>

<div id="page2">
     <p>Multiple Chooses listed here.</p>
     <div>
          <div id="click_1">1</div>
          <div><a href="#" id="Option1">Option 1</a></div>
     </div>
     <div>
          <div id="click_2">2</div>
          <div><a href="#" id="Option2">Option 2</a></div>
     </div>
     <div>
          <div id="click_3">3</div>
          <div><a href="#" id="Option3">Option 3</a></div>
     </div>
     <div>
          <div id="click_4">4</div>
          <div><a href="#" id="Option4">Option 4</a></div>
     </div>
</div>

<div id="page3">
     <p>Solution listed here.</p>
    <button id="button2">Enter</button>
    <div class="KB-Enter" id="click_5">press Enter</div>         
</div>

  .... Etc

Example CSS

#page1{opacity:1; width:100%; visibility: visible; display: block;} 
#page2{opacity:0; width:100%; visibility: hidden; display: none;}
#page3{opacity:0; width:100%; visibility: hidden; display: none;}

Example Jquery

jQuery(document).ready(function($) {

$('#button1').click(function() {
$('#page1').fadeTo( 'fast', 0 ).css('visibility' , 'hidden').css('display' , 'none');
$('#page2').delay( 800 ).css('visibility' , 'visible').css('display' , 'block').fadeTo( 'slow', 1 );
});

$(function(){
$(document).on('keypress',(function(e) {
if ($('#click_1').is(':visible') && e.which == 13 ){
$('#page1').fadeTo( 'fast', 0 ).css('visibility' , 'hidden').css('display' , 'none');
$('#page2').delay( 800 ).slideUp( 300 ).css('visibility' , 'visible').css('display' , 'block').fadeTo( 'slow', 1 );
}
}));

$('#button2').click(function() {
$('#page3').fadeTo( 'fast', 0 ).css('visibility' , 'hidden').css('display' , 'none');
$('#signupForm').delay( 800 ).css('visibility' , 'visible').css('display' , 'block').fadeTo( 'slow', 1 );
});

$(function(){
$(document).on('keypress',(function(e) {
if ($('#click_5').is(':visible') && e.which == 13 ){
$('#page3').fadeTo( 'fast', 0 ).css('visibility' , 'hidden').css('display' , 'none');
$('#signupForm').delay( 800 ).slideUp( 300 ).css('visibility' , 'visible').css('display' , 'block').fadeTo( 'slow', 1 );
}
}));

$('#Option1').click(function() {
$('#page2').fadeTo( 'fast', 0 ).css('visibility' , 'hidden').css('display' , 'none');
$('#page3').delay( 800 ).css('visibility' , 'visible').css('display' , 'block').fadeTo( 'slow', 1 );
});

$(function(){
$(document).on('keypress',(function(e) {
if ($('#click_1').is(':visible') && e.which == 49 || e.which == 97 ){
$('#page2').fadeTo( 'fast', 0 ).css('visibility' , 'hidden').css('display' , 'none');
$('#page3').delay( 800 ).slideUp( 300 ).css('visibility' , 'visible').css('display' , 'block').fadeTo( 'slow', 1 );
}
}));

$('#Option4').click(function() {
$('#page2').fadeTo( 'fast', 0 ).css('visibility' , 'hidden').css('display' , 'none');
$('#page4').delay( 800 ).css('visibility' , 'visible').css('display' , 'block').fadeTo( 'slow', 1 );
});

$(function(){
$(document).on('keypress',(function(e) {
if ($('#click_2').is(':visible') && e.which == 50 || e.which == 98 ){
$('#page2').fadeTo( 'fast', 0 ).css('visibility' , 'hidden').css('display' , 'none');
$('#page4').delay( 800 ).slideUp( 300 ).css('visibility' , 'visible').css('display' , 'block').fadeTo( 'slow', 1 );
}
}));

$('#Option3').click(function() {
$('#page2').fadeTo( 'fast', 0 ).css('visibility' , 'hidden').css('display' , 'none');
$('#page5').delay( 800 ).css('visibility' , 'visible').css('display' , 'block').fadeTo( 'slow', 1 );
});

$(function(){
$(document).on('keypress',(function(e) {
if ($('#click_3').is(':visible') && e.which == 51 || e.which == 99  ){
$('#page2').fadeTo( 'fast', 0 ).css('visibility' , 'hidden').css('display' , 'none');
$('#page5').delay( 800 ).slideUp( 300 ).css('visibility' , 'visible').css('display' , 'block').fadeTo( 'slow', 1 );
}
}));

$('#Option4').click(function() {
$('#page2').fadeTo( 'fast', 0 ).css('visibility' , 'hidden').css('display' , 'none');
$('#page6').delay( 800 ).css('visibility' , 'visible').css('display' , 'block').fadeTo( 'slow', 1 );
});

$(function(){
$(document).on('keypress',(function(e) {
if ($('#click_4').is(':visible') && e.which == 52 || e.which == 100 ){
$('#page2').fadeTo( 'fast', 0 ).css('visibility' , 'hidden').css('display' , 'none');
$('#page6').delay( 800 ).slideUp( 300 ).css('visibility' , 'visible').css('display' , 'block').fadeTo( 'slow', 1 );
}
}));
});

+132 more and growing.

Solution

Below is the solution I eventually went with. I started off with a file size of over 100KB. With this code and utilizing php to echo repetitive content throughout the troubleshooting guide I managed to bring it down to 45KB.

jQuery(document).ready(function($) {
    function handleEvent(e){
        var id = null;          
        var fade_out;
        var fade_in;
        
        if (e.type === 'click'){
            id = $(this).attr("id");
        }else{
            id = e.which;
        }

        switch (id){
            case 13:
            if ($('#click_1').is(':visible')){
                fade_out = '#start_1';
                fade_in  = '#step_0';
            }
            break;
            case 'heat':
            if ($('#click_36').is(':visible')){
                fade_out = '#step_Heat_1';
                fade_in  = '#step_heat_2';
            }
            break;
            .......etc.......
        }       
        $(fade_out).fadeTo( 'fast', 0 ).css('visibility','hidden').css('display','none');
        $(fade_in).delay( 800 ).css('visibility','visible').css('display','block').fadeTo( 'slow', 1 );
    }
    $('#ts_container').on('click', 'button, a', handleEvent);
    $(document).on('keypress', handleEvent);  
});
1 Answers

I suggest you to declare your scenario in an object and build your page following the item selected (either a new page option, or a new page solution)

its just the beginning of an idea

var scenario = {
  /*level1*/
  titleX: "title pageX",
  opt1: "option1",
  opt2: "option2",
  opt3: "option3",

  /*level2*/
  title1_X: "title page 1_x",
  opt1_1: "option1_1",

  title2_X: "title page 2_x",
  opt2_1: "option2_1",
  opt2_2: "option2_2",
  opt2_3: "option2_3",

  title3_X: "title page 3_x",
  opt3_1: "option3_1",
  opt3_2: "option3_2",

  /*level3*/
  title1_1_X: "title page 1_1_x",
  sol1_1_1: "sol1_1_1",
  /*level3*/
  title2_1_X: "title page 2_1_x",
  opt2_1_1: "option2_1_1",
  opt2_1_2: "option2_1_2",
  opt2_1_3: "option2_1_3",

  title2_2_X: "title page 2_2_x",
  opt2_2_1: "option2_2_1",

  title2_3_X: "title page 2_3_x",
  sol2_3_1: "sol2_3_1",

  title3_1_X: "title page 3_1_x",
  sol3_1_1: "sol3_1_1",

  title3_2_X: "title page 3_2_x",
  opt3_2_1: "opt3_2_1"

};
var level = "";

$(document).on("click", ".main a", function() {
  var id =  $(this).attr("id"); 
  title = scenario["title" + id.replace("opt","") + "_X"];

  var listopt = [];
  var solution = "";
  var idx = 1;
  var ind = $(this).attr("id") + "_" + idx;
  var sol = ind.replace("opt", "sol");
  if (scenario[ind]){
    listopt.push(scenario[ind]);
  }else{
    solution = scenario[sol];  
  }
  
  if(solution != "") { //its a page with new option
    for(idx = 2; idx < 100; idx++){
      ind = $(this).attr("id") + "_" + idx;
      if (scenario[ind]){ 
        listopt.push(scenario[ind]);        
      }else{
        break;
      }
    }
  
  }else{
    //its solution page
  }
  
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="page0">
  <p>Introduction & Welcome Message to Guide.</p>
  <button id="button1">Enter</button>
  <div class="KB-Enter" id="click_0">press Enter</div>
</div>

<div class="main"  >
     <p>Multiple Chooses listed here.</p>
     <div>
          <div id="click_1">1</div>
          <div><a href="#" id="opt2_1">Option 1</a></div>
     </div>
     <div>
          <div id="click_2">2</div>
          <div><a href="#" id="opt2_2">Option 2</a></div>
     </div>
     <div>
          <div id="click_3">3</div>
          <div><a href="#" id="opt2_3">Option 3</a></div>
     </div>
</div>

Related