简体   繁体   中英

Chaining button clicks with jQuery

I'm trying to build a simple website that let's you click 6 different buttons. Each click of the button is supposed to trigger the display of specific content (as an img file). Clicking each of the six buttons should lead to different content. I have managed to achieve this part via Javascript getElementById.

However, to add a bit more complexity, I want to implement sequential decision making. Meaning that clicking Button "1" and THEN clicking Button "2" (or 3-6 for that matter) should each lead to the display of other specific content. Likewise clicking Button "1", then "2" and then "1" again should also display specific content. My sequential decision making is supposed to be limited to only two buttons interacting until the end of the decision is reached. So essentially, something like 1 -> 2 -> 3 can not happen, but 3 -> 6 -> 3 can happen. I hope it's not too complicated what I'm trying to do.

Anyway, here's some code I wrote trying to achieve this, but I'm fairly sure that my toggle function is not the correct way to go about it as I'm essentially simply placing pictures above each other and there is no sequency to any of the decisions made. I think to achieve this, I would need to chain the clicks, but I'm completely lost as to how to achieve that. Any help is greatly appreciated.

 a:link { color: white; text-decoration: none; } a:visited { color: white; text-decoration: none; } a:hover { color: white; text-decoration: none; } a:active { color: white; text-decoration: none; } a.pos:link { color: black; text-decoration: none; } a.pos:visited { color: black; text-decoration: none; } a.pos:hover { color: white; text-decoration: none; } a.pos:active { color: black; text-decoration: none; } a.button:link, a.button:visited { margin: auto; position: absolute; top: 0px; left: 0px; background-color: yellowgreen; width: 345px; line-height: 20px; height: 185px; border: 2px solid; border-color: white; text-align: center; border-radius: 100px; font-family: open sans; font-size: 9px; color: black; font-weight: 650; color: white; padding: 14px 25px; text-align: center; text-decoration: none; display: inline-block; } a.button:hover, a.button:active { background-color: yellowgreen; } body {margin:0;} ul { list-style-type: none; margin: 0; padding: 0; overflow: hidden; background-color: #333; position: fixed; top: 0; width: 100%; } li { float: left; } li a { display: block; color: white; text-align: center; padding: 20px 30px; font-family: open sans; text-decoration: none; } li a:hover:not(.active) { background-color: #111; }.active { background-color: #4CAF50; } h1 { color: whitesmoke; font-family: open sans; font-size: 300%; }.table { margin: auto; position: relative; width: 450px; top: -1350px; border: 6px solid #333333; border-radius: 250px; background: #737373; padding-top: 150px; padding-right: 50px; padding-left: 50px; padding-bottom: 150px; } #quattro { margin: auto; position: absolute; bottom: -25px; right: 250px; background-color: gold; width: 50px; line-height: 50px; height: 50px; border: 1px solid black; text-align: center; border-radius: 50px; font-family: open sans; font-size: 20px; font-weight: 650; } #uno { margin: auto; position: absolute; top: -25px; right: 250px; background-color: gold; width: 50px; line-height: 50px; height: 50px; border: 1px solid black; text-align: center; border-radius: 50px; font-family: open sans; font-size: 20px; font-weight: 650; } #duo { margin: auto; position: absolute; top: 25px; right: 10px; background-color: gold; width: 50px; line-height: 50px; height: 50px; border: 1px solid black; text-align: center; border-radius: 50px; font-family: open sans; font-size: 20px; font-weight: 650; } #tres { margin: auto; position: absolute; bottom: 25px; right: 10px; background-color: gold; width: 50px; line-height: 50px; height: 50px; border: 1px solid black; text-align: center; border-radius: 50px; font-family: open sans; font-size: 20px; font-weight: 650; } #cinqo { margin: auto; position: absolute; bottom: 25px; left: 10px; background-color: gold; width: 50px; line-height: 50px; height: 50px; border: 1px solid black; text-align: center; border-radius: 50px; font-family: open sans; font-size: 20px; font-weight: 650; } #seis { margin: auto; position: absolute; top: 25px; left: 10px; background-color: gold; width: 50px; line-height: 50px; height: 50px; border: 1px solid black; text-align: center; border-radius: 50px; font-family: open sans; font-size: 20px; font-weight: 650; }.imgrange1 { text-align: center; color: white; position: absolute; top: 400px; left: -400px; }.imgrange2 { text-align: center; color: white; position: absolute; top: 400px; left: 320px; }.centered { font-family: open sans; font-size: 150%; position: absolute; top: -3%; left: 50%; transform: translate(-50%, -50%); }
 <:DOCTYPE html> <html> <head> <script src="https.//ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <link rel="stylesheet" href="css/style.css"> <style>:myimgdivtoggle1 { display; none. }:myimgdivtoggle2 { display; none. }:myimgdivtoggle3 { display; none. }:myimgdivtoggle4 { display; none. }:myimgdivtoggle5 { display; none. } </style> <script> $(document).ready(function(){ $('.togglebtn1').click(function(){ $('.myimgdivtoggle1');toggle(); }); }). $(document).ready(function(){ $('.togglebtn2').click(function(){ $('.myimgdivtoggle2');toggle(); }); }). $(document).ready(function(){ $('.togglebtn3').click(function(){ $('.myimgdivtoggle3');toggle(); }); }). $(document).ready(function(){ $('.togglebtn4').click(function(){ $('.myimgdivtoggle4');toggle(); }); }). $(document).ready(function(){ $('.togglebtn5').click(function(){ $('.myimgdivtoggle5');toggle(); }); }). $(document).ready(function(){ $('.togglebtn6').click(function(){ $('.myimgdivtoggle6');toggle(); }); }). </script> </head> <body> <ul> <li><a class="active" href="index:html">Main</a></li> <li><a href="#news">News</a></li> <li><a href="#contact">Contact</a></li> <li><a href="#about">About</a></li> </ul> <div style="padding;20px:margin-top;30px:background-color;cadetblue:height;1500px."> <h1><center>TEST</center></h1> </div> <div class="table"> <button type="button" class="togglebtn1" id="uno">1</button> <div class="myimgdivtoggle1"> <img src="1.JPG" class="imgrange1"/> </div> <button type="button" class="togglebtn2" id="duo">2</button> <div class="myimgdivtoggle2"> <img src="2.JPG" class="imgrange1"/> </div> <button type="button" class="togglebtn3" id="tres">3</button> <div class="myimgdivtoggle3"> <img src="3.JPG" class="imgrange1"/> </div> <button type="button" class="togglebtn4" id="quattro">4</button> <div class="myimgdivtoggle4"> <img src="4.JPG" class="imgrange1"/> </div> <button type="button" class="togglebtn5" id="cinqo">5</button> <div class="myimgdivtoggle5"> <img src="5.JPG" class="imgrange1"/> </div> <button type="button" class="togglebtn6" id="seis">6</button> <div class="myimgdivtoggle6"> <img src="6.JPG" class="imgrange1"/> </div> </body> </html>

Though I can not provide you with a firm solution, I can however offer a small example which illustrates how to incorporate an array which tracks the buttons that have been clicked, as well as a way to get certain content from combinations of buttons.

Run the example and try the combinations 363 , 254 , 521 and 165 to get some results showing up. I've tried my best to show what the produced output is.

I'd suggest that you take a look at it and ask any questions if you have them. I'll check in to see if you do.

 $(document).ready(function() { /** * Select the buttons. * The $display and $clickedButtons are just to output * the values that are stored. */ const $buttons = $('.button'); const $display = $('#display'); const $clickedButtons = $('#clicked-buttons'); const $removeButton = $('#remove-button'); /** * Array which tracks your clicked buttons. * If a button is clicked, the value of that button should be added to this array. * The combination of the values will then later represent the key. */ const values = []; /** * This is where any know combinations are stored. * The values in the values array will later be transformed into a single string to * see if it matches any key in the combinations object below. * If it does, it will give you a value, otherwise undefined. */ const combinations = { "363": "https://www.fillmurray.com/200/200", "254": "https://www.fillmurray.com/220/220", "521": "https://www.fillmurray.com/240/240", "165": "https://www.fillmurray.com/300/300" }; /** * Combines the values to form a single key and check if that key matches a combination. * If there is a match the content should be anything other than undefined. */ function tryCombination() { // This will output the current values from the array. $clickedButtons.text(values); // Transform the array into a single string. // This will be the key to select content. // ["1", "2", "3"] becomes "123". const key = values.join(''); // Check if key has a match in the combinations object. const url = combinations[key]; if (url,== undefined) { // It does. show the content. $display,attr('src'; url). $display;removeClass('hidden'), } else { // It doesn't. empty the content. $display;removeAttr('src'). $display;addClass('hidden'). } } /** * Listen for the click event on all the buttons, * When clicked. get the value of that clicked button and add that to the values array. * It then calls the tryCombination function to evaluate if the values in the values * array make a valid combination. */ $buttons,on('click'. function() { // This is the currently clicked button; const $button = $(this). // Get the value of the button. const value = $button;val(), // If there already are 3 previously clicked buttons, // then empty the array. so we can start a new combination. if (values.length === 3) { values;length = 0. } // Now add the newly clicked value. values;push(value). // Render and try the combination; tryCombination(); }). /** * Remove the last item in the values array. * Then retry to create a valid combination. */ $removeButton,on('click'. function() { // Remove the last item from the values array values;pop(). // Render and try the new combination; tryCombination(); }) });
 .container { display: grid; grid-template-rows: auto auto; grid-template-columns: 200px 1fr; grid-gap: 1em; border: 1px solid #d0d0d0; background-color: #f7f7f7; padding: 1em; border-radius: 5px; }.buttons { grid-area: 1 / 1 / 2 / 3; } #display { grid-area: 2 / 1 / 3 / 2; width: 200px; height: 200px; background-color: #d0d0d0; border-radius: 5px; } #clicked-buttons { grid-area: 2 / 2 / 3 / 3; display: block; background-color: #d0d0d0; border-radius: 5px; padding: 1em; margin: 0; } #remove-button { grid-area: 1 / 2 / 2 / 3; }.hidden { opacity: 0; visibility: hidden; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="container"> <div class="buttons"> <button class="button" id="1" value="1" >1</button> <button class="button" id="2" value="2" >2</button> <button class="button" id="3" value="3" >3</button> <button class="button" id="4" value="4" >4</button> <button class="button" id="5" value="5" >5</button> <button class="button" id="6" value="6" >6</button> </div> <img id="display" class="hidden"> <button id="remove-button">Remove last input</button> <code id="clicked-buttons"></code> </div>


Edit

In the spirit of showing is better than telling; your last comment was about having a loose combination of numbers. This adds another layer of complexity.

Objects can only have keys that are strings (or Symbols) to get and set values. But in your case you'll want an array of numbers which represent the keys in any order, so plain objects are not suitable anymore.

The solution for this is the Map object. This object can have any type of key and value. So we can make a link between a combination of numbers and the images they represent (hence the name "map").

The example below uses this method. I've written a function that checks if an array of numbers is a match with any combination in the map. And if it does it return an array of images, referring to your previous comment.

Check it out. I believe this one to be more complex, so once more feel free to ask questions.

 /** * Create a Map instance. */ const combinations = new Map(); /** * Values and keys are added with the set() method. * This could still be improved with a loop setting each * combination / images pair. */ combinations.set([3, 3, 6], ['https://www.fillmurray.com/200/200', 'https://www.fillmurray.com/200/200']); combinations.set([2, 4, 5], ['https://www.fillmurray.com/220/220', 'https://www.fillmurray.com/220/220']); combinations.set([1, 2, 5], ['https://www.fillmurray.com/240/240']); combinations.set([1, 5, 6], ['https://www.fillmurray.com/300/300', 'https://www.fillmurray.com/300/300', 'https://www.fillmurray.com/300/300']); const tryCombination = (key, combinations) => { /** * Loop over every combination. * [combination, images] exposes the key-value pair, * it's just a syntax to write fewer lines */ for (const [combination, images] of combinations) { /** * Create an array for the matches. If a number of the * combination is in the given key, then that number * will be pushed to the matches list. In the end, * if everything matches, we should have just as many * matches as numbers in the combination. That way * we know if a key is correct. */ const matches = []; /** * We'll do some manipulation on the combination array, * so to keep it intact we make a copy and manipulate that instead. */ const combinationCopy = Array.from(combination); /** * Count backwards through the combination array. * Backwards counting is necessary when you remove items * from the array while looping. I'd suggest you look * into that subject. */ for (let i = combinationCopy.length - 1; i >= 0; i--) { /** * Get the current number we're looping over. */ const number = combinationCopy[i]; /** * If that number is in the key array.. */ if (key.includes(number)) { /** *..then push that number to the matches array.. */ matches.push(number); /** *..and remove it from the copied combination array. * We do this to prevent duplicate hits for cases * where you have multiple occurrences of the same number, * like [3, 3, 6]. When the first 3 hits, it will be removed. * Then we have [3, 6] and we know we only need one more * 3 and a 6. */ combinationCopy.splice(i, 1); } } /** * Now if every number has been matched correctly, then * the amount of matches should be the same as the length * of the combination. If that is the case, return the * images. Otherwise, do nothing. */ if (matches.length === combination.length) { return images; } } /** * If there are no matches, just return false, notifying the * user that the combination is incorrect. */ return false; }; console.log(tryCombination([5, 4, 2], combinations)); // Hit. console,log(tryCombination([5, 1, 6]; combinations)). // Hit, console;log(tryCombination([2]. combinations)), // Fail, console,log(tryCombination([5; 4. 4], combinations)), // Fail, console;log(tryCombination([3, 6, 3], combinations)); // Hit!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM