Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
72 views
in Technique[技术] by (71.8m points)

javascript - Displaying images through series of button clicks

I'm trying to build a website with a very basic functionality. Essentially the website is supposed to contain various buttons and display images based on which series of buttons are clicked. Unfortunately my experience in web development is limited (to non-existent), but I've found some code that works to some extent here on stackoverflow. Building on that, I wanted to alter the code in a way that allows me to achieve the functionality I desire.

Here's how the website is supposed to look like:

supposed to look like this

As you can notice, the website contains various buttons from A-D and 0-9. The button clicks are logged in the field beneath and once a combination has been put in that matches the name of a file, the image will be displayed.

Here's the code:

              
    $(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 $reset = $('#reset');
      $reset.on('click', function() {
        values = [];
        $clickedButtons.text(values);
      });
      
      /**
       * 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.
       */
      var values = [];
      
      /**
       * 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.
       * After that the clicked button values will be combined
       * 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.
       */

      $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 15 previously clicked buttons,
        // then empty the array, so we can start a new combination.
        if (values.length === 15) {
          values = [];
        }
        
        // Now add the newly clicked value.
        values.push(value);
        
        // This will output the current values in 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.
        $display.attr('src', 'output/' + key + '.png');
      });
    }); 

Now to my problem: The code requires that they combination of buttons is clicked exactly in the order of the name of the image. So for example, inputting A-B-C-1-2-3 will display ABC123.png. For my purpose however, I would need the code to display ABC123.png even if the inputs are 31B2AC or any other combination of these 6 inputs. I've looked into the option of 'sorting' but this creates a problem on the other hand, namely that some of the pictures are named like this e.g. D9B6C4.png so there is no applicable logic like alphabetic or numerical that would be required for a sorting algorithm to function. Every image in the folder has an unique however so when ABC123.png exists, BCA321 cannot.

What I would need the script to do is to parse through the pictures and find the unique picture that contains all letters & numbers that are entered regardless of their order. Is that even possible? How would I go about achieving this?

///////// EDIT ////////

My attempt to add a display, a tracker of clicked buttons and as well as a remove button:

So not really sure why literally nothing is working. Neither the inputs are displayed in the appropriate field nor is a picture being displayed ...

       
  const $buttons = $('.button');
  const $display = $('#display');
  const $clickedButtons = $('#clicked-buttons');
  const $removeButton = $('#remove-button');    
  const values = [];
        
var imgs = ["ABC123.png", "1A2B4C.png", "ABC132.png", "123ABC.png"];

function case_insensitive_comp(strA, strB) {
  return strA.toLowerCase().localeCompare(strB.toLowerCase());
}

function reSortFiles() {
  var all = {};
  imgs.forEach(function(a) {
    d = a.split(".");
    img = d[0].split("");
    img = sortStr(img);
    img = img.join("");

    all[img] ? all[img].push(a) : all[img] = [a];
  });

  return all;
}

function sortStr(str) {
  return str.sort(case_insensitive_comp)
}

function tryCombination() {
    // This will output the current values from the array.
    $clickedButtons.text(values);        
    
const key = values.join('');  
        
allImages = reSortFiles()
console.log(allImages)


buttons = document.querySelectorAll("button")

clicked = "";

buttons.forEach(function(btn) {
  btn.addEventListener("click", function(e) {
    clicked += e.target.dataset.value;
    clicked_s = sortStr(clicked.split("")).join("")
    console.log(clicked, clicked_s)
    img = allImages[clicked_s]
    if (img) {
      console.log("Found: ", img.join(","))
      clicked=""; 
    }
  });
});
   
.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>
question from:https://stackoverflow.com/questions/66050867/displaying-images-through-series-of-button-clicks

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here is my working solution, albeit its kind of hacky.

Have all of your images loaded in an array, just the file names.

Then loop through ALL of those files and create an object with the sorted name as the key and the file name as the value. That way no matter how the images are named, they will have a key like 999XXX.

Then it's just a matter of getting the buttons clicked and sorting its string until that string exists as a key.

var imgs = ["ABC123.png", "1A2B4C.png"];

function case_insensitive_comp(strA, strB) {
  return strA.toLowerCase().localeCompare(strB.toLowerCase());
}

function reSortFiles() {
  var all = {};
  imgs.forEach(function(a) {
    d = a.split(".");
    img = d[0].split("");
    img = sortStr(img);
    img = img.join("");

    all[img] = a;
  });

  return all;
}

function sortStr(str) {
  return str.sort(case_insensitive_comp)
}

allImages = reSortFiles()

buttons = document.querySelectorAll("button")

clicked = "";

buttons.forEach(function(btn) {
  btn.addEventListener("click", function(e) {
    clicked += e.target.dataset.value;
    clicked = sortStr(clicked.split("")).join("")
    img = allImages[clicked]
    if (img) {
      console.log(img)
    }
  });
});
<button type="button" data-value="A">A</button>
<button type="button" data-value="B">B</button>
<button type="button" data-value="C">C</button>
<button type="button" data-value="1">1</button>
<button type="button" data-value="2">2</button>
<button type="button" data-value="3">3</button>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...