4 votes

Naviguer dans les cellules du tableau à l'aide des boutons haut, bas, gauche, droite

Je développe un programme en JavaScript qui est censé permettre à l'utilisateur de naviguer entre les cellules d'un tableau à l'aide des boutons haut, bas, gauche, droite. La cellule de tableau appropriée est mise en évidence lorsque l'on clique sur un bouton directionnel.

Ma table se présente comme suit :

Je travaille sur la construction des fonctions pour contrôler les boutons directionnels, mais je suis extrêmement perdu sur la façon d'aborder cela. Je dois pouvoir passer un argument qui contient la cellule actuellement surlignée, mais je n'arrive pas à comprendre comment faire.

Mon JavaScript jusqu'à présent, qui ne fait pas grand-chose :

function right() {
    document.getElementById("one").nextElementSibling.style.border = '2px solid black';
}

Toute aide pour résoudre ce problème serait la bienvenue, car je n'ai vraiment aucune idée de la marche à suivre.

3voto

A.Sharma Points 2314

UNE SOLUTION DYNAMIQUE UTILISANT PURE JS

Vous pouvez essentiellement stocker les objets du tableau dans une matrice à deux dimensions. Ce faisant, vous disposez de deux coordonnées globales X et Y qui stockent l'emplacement actuel de la grille. Vous pouvez lier des événements de clic et des événements de clavier qui suivent l'endroit où se trouve le centre d'intérêt.

Jetez un coup d'œil au violon : https://jsfiddle.net/cnkr7wqa/5/

Notez que cette solution est dynamique, quelle que soit la taille des lignes ou des colonnes. si chaque ligne a la même longueur et chaque colonne la même longueur.

Notez également que cela fonctionne pour : les clics de souris, les pressions directionnelles sur le clavier et les pressions sur les boutons

HTML

<table>
<tr>
  <td>1</td>
  <td>2</td>
  <td>3</td>
</tr>
<tr>
  <td>4</td>
  <td>5</td>
  <td>6</td>
</tr>
<tr>
  <td>7</td>
  <td>8</td>
  <td>9</td>
</tr>
</table>

<button>Left</button>
<button>Up</button>
<button>Right</button>
<button>Down</button>

Javascript

var dat = document.getElementsByTagName('td');
var numOfColumns = document.getElementsByTagName('tr').length;
var numOfRows = document.getElementsByTagName('tr').length;
var currIndex = 0;
var rowObj = document.getElementsByTagName('tr');
var oneColLength = rowObj[0].children.length;
var colObj = document.getElementsByTagName('td');
var totalData = rowObj.length * colObj.length;
var dataCounter = 0;
var matrixObj = new Array(rowObj.length);
var currentX = 0;
var currentY = 0;
var buttons = document.getElementsByTagName('button');

for(var i = 0; i < matrixObj.length; i++){
   matrixObj[i] = new Array(oneColLength);
}

for(var i = 0; i < numOfRows; i++){
  for(var j = 0; j < oneColLength; j++){
     matrixObj[i][j] = colObj[dataCounter++];
  }
}

for(var i = 0; i < buttons.length; i++){
  buttons[i].addEventListener("click",function(){
    removeAllBorders();
    compareBtnEntity(this);
  });
}

for(var i = 0; i < dat.length; i++){
  dat[i].addEventListener("click",function(){
    removeAllBorders();
    this.style.border = "1px solid red";
    compareEntity(this);
  });
}

window.addEventListener("keyup",function(e){
       switch(e.keyCode){
            case 37: 
                if(currentX > 0){
                  currentX--;
                  repaint();
                }
                break;
            case 38: 
                if(currentY > 0){
                  currentY--;
                  repaint();
                }
                break;
            case 39: 
                if(currentX < oneColLength-1){
                  currentX++;
                  repaint();
                }
                break;
            case 40: 
                if(currentY < matrixObj.length-1){
                  currentY++;
                  repaint();
                }
                break;          
        }
})

function removeAllBorders(){
  for(var i = 0; i < dat.length; i++){
    dat[i].style.border = "1px solid grey";
  }
}

function compareEntity(ele){
  for(var i = 0; i < matrixObj.length; i++){
    for(var j = 0; j < oneColLength; j++){
       if(ele == matrixObj[i][j]){
          currentX = j;
          currentY = i;
       }
    }
  }
}

function compareBtnEntity(ele){
        for(var i = 0; i < buttons.length; i++){
            if(buttons[i] == ele){
                break; 
            }
        }

    switch(i){
                case 0: 
                if(currentX > 0){
                  currentX--;
                  repaint();
                }
                break;
            case 1: 
                if(currentY > 0){
                  currentY--;
                  repaint();
                }
                break;
            case 2: 
                if(currentX < oneColLength-1){
                  currentX++;
                  repaint();
                }
                break;
            case 3: 
                if(currentY < matrixObj.length-1){
                  currentY++;
                  repaint();
                }
                break;       
      }
     repaint();
  }

function repaint(){
  removeAllBorders();
  matrixObj[currentY][currentX].style.border = "1px solid red";
}

2voto

romellem Points 1498

Je sais que vous n'avez pas inclus le jquery sur ce sujet, mais j'ai créé un exemple qui fonctionne aquí ( https://jsfiddle.net/romellem/pg6eveht/ ) en utilisant jQuery pour faciliter les choses.

Il n'y a rien de trop complexe pour lequel vous ne pourriez pas supprimer le jQuery que j'ai utilisé, mais je laisserai cela comme un exercice pour le lecteur :)

J'ai utilisé le modèle de prototype pour créer une classe d'allumeur où l'on passe un sélecteur pour initialiser un tableau. Elle ne prend pas en compte les en-têtes dans le tableau, vous devrez donc les ajouter.

Sinon, j'espère que cela vous aidera à faire un pas dans la bonne direction si vous êtes totalement perdu.

$(document).ready(function() {
  var TableHilighter = function(table, selected) {
    this.table = $(table);
    this.rows = this.table.find('tr').length;
    this.cols = this.table.find('tr').first().find('td').length;
    this.selected = (typeof selected === 'undefined') ? [1, 1] : selected;

    // Hilight our row on initialization
    this.hilight();
  };

  TableHilighter.prototype = {
    "hilight": function(cell) {
      if (typeof cell === 'undefined') {
        cell = this.selected;
      }
      // Clear all hilighted cells
      this.table.find('td').removeClass('hilighted');

      // First find the row, then find the col, and add the .hilighted class
      this.table.find('tr:nth-child(' + this.selected[1] + ')').find('td:nth-child(' + this.selected[0] + ')').addClass('hilighted');
    },
    "move": function(dir) {
      switch (dir) {
        case 'up':
          this._up();
          break;
        case 'down':
          this._down();
          break;
        case 'left':
          this._left();
          break;
        case 'right':
          this._right();
          break;
        default:
          break;
      }
      this.hilight();
      return this.selected;
    },
    "_left": function() {
      if (this._x() > 1) {
        this._x(this._x() - 1);
      }
      return this.selected;
    },
    "_right": function() {
      if (this._x() < this.cols) {
        this._x(this._x() + 1);
      }
      return this.selected;
    },
    "_up": function() {
      if (this._y() > 1) {
        this._y(this._y() - 1);
      }
      return this.selected;
    },
    "_down": function() {
      if (this._y() < this.rows) {
        this._y(this._y() + 1);
      }
      return this.selected;
    },
    "_x": function(x) {
      if (typeof x === 'undefined') {
        return this.selected[0];
      } else {
        this.selected[0] = x;
        return this.selected[0];
      }
    },
    "_y": function(y) {
      if (typeof y === 'undefined') {
        return this.selected[1];
      } else {
        this.selected[1] = y;
        return this.selected[1];
      }
    }
  };

  // Initialize our TableHilighter
  var my_table = new TableHilighter('table');

  // Add button event handlers
  $('.up').on('click', function(e) {
    e.preventDefault();
    my_table.move('up');
  });

  $('.down').on('click', function(e) {
    e.preventDefault();
    my_table.move('down');
  });

  $('.left').on('click', function(e) {
    e.preventDefault();
    my_table.move('left');
  });

  $('.right').on('click', function(e) {
    e.preventDefault();
    my_table.move('right');
  });
});

table tr td {
  border: 1px solid black;
  padding: 2px;
}
.hilighted {
  border: 2px solid red;
  padding: 1px;
}
button.up {
  margin-left: 2em;
}
button.down {
  margin-left: 1.5em;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table>
  <tr>
    <td>1,1</td>
    <td>2,1</td>
    <td>3,1</td>
  </tr>
  <tr>
    <td>1,2</td>
    <td>2,2</td>
    <td>3,2</td>
  </tr>
  <tr>
    <td>1,3</td>
    <td>2,2</td>
    <td>3,3</td>
  </tr>
</table>

<button class="up">Up</button>

<div>
  <button class="left">Left</button>
  <button class="right">Right</button>
</div>

<button class="down">Down</button>

1voto

Julien Points 736

Une façon commode de traiter ce problème est de donner une valeur significative à l'expression "l'esprit d'entreprise". id à vos cellules. La navigation devient alors évidente.

var dimensionX = 4;
var dimensionY = 4;
var selected = "cell-0-0";

$(document).keydown(function(event) {

  event.preventDefault();
  $("#" + selected).removeClass("selected");
  var currentX = parseInt(selected.split("-")[1]);
  var currentY = parseInt(selected.split("-")[2]);

  switch (event.which) {
    case 37:
      selected = "cell-" + (currentX == 0 ? dimensionX - 1 : currentX - 1) + "-" + currentY;
      break;

    case 38:
      selected = "cell-" + currentX + "-" + (currentY == 0 ? dimensionY - 1 : currentY - 1);
      break;

    case 39:
      selected = "cell-" + ((currentX + 1) % dimensionX) + "-" + currentY;
      break;

    case 40:
      selected = "cell-" + currentX + "-" + ((currentY + 1) % dimensionY);
      break;
  }
  $("#" + selected).addClass("selected");
});

$("#up, #down, #left, #right").click(function() {

  var currentX = parseInt(selected.split("-")[1]);
  var currentY = parseInt(selected.split("-")[2]);
  $("#" + selected).removeClass("selected");

  switch (this.id) {
    case "up":
      selected = "cell-" + currentX + "-" + (currentY == 0 ? dimensionY - 1 : currentY - 1);
      break;
    case "down":
      selected = "cell-" + currentX + "-" + ((currentY + 1) % dimensionY);
      break;
    case "left":
      selected = "cell-" + (currentX == 0 ? dimensionX - 1 : currentX - 1) + "-" + currentY;
      break;
    case "right":
      selected = "cell-" + ((currentX + 1) % dimensionX) + "-" + currentY;
      break;
  }
  $("#" + selected).addClass("selected");
});

$("#mark").click(function() {
  if ($("#" + selected).hasClass("marked")) $("#" + selected).removeClass("marked");
  else $("#" + selected).addClass("marked");
});

td {
  border: 1px solid black;
}
td.selected {
  border: 1px solid red;
}
p.buttons > span {
  border: 1px solid grey;
  border-radius: 2px;
  cursor: pointer;
  margin: 0 3px;
  display: inline-block;
  padding: 1px 3px;
}
td.marked {
  background: black;
  color: white;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="sheet">
  <tbody>
    <tr id="row-0">
      <td id="cell-0-0" class="selected">A</td>
      <td id="cell-1-0">B</td>
      <td id="cell-2-0">C</td>
      <td id="cell-3-0">D</td>
    </tr>
    <tr id="row-1">
      <td id="cell-0-1">E</td>
      <td id="cell-1-1">F</td>
      <td id="cell-2-1">G</td>
      <td id="cell-3-1">H</td>
    </tr>
    <tr id="row-2">
      <td id="cell-0-2">I</td>
      <td id="cell-1-2">J</td>
      <td id="cell-2-2">K</td>
      <td id="cell-3-2">L</td>
    </tr>
    <tr id="row-3">
      <td id="cell-0-3">M</td>
      <td id="cell-1-3">N</td>
      <td id="cell-2-3">O</td>
      <td id="cell-3-3">P</td>
    </tr>
  </tbody>
</table>
<p class="buttons"><span id="up">Up</span> <span id="down">Down</span>  <span id="left">Left</span> <span id="right">Right</span> <span id="mark">Mark</span></p>

Vous devez centrer l'extrait pour pouvoir utiliser les flèches pour vous déplacer.

0voto

messerbill Points 2566

Ok, j'ai créé un petit jeu pour vous :

https://jsfiddle.net/c7f3hczs/

mais attention :

cela ne fonctionne que pour la "flèche droite". Vous devez également implémenter les autres touches. Les flèches vers le haut et vers le bas sont un peu délicates... vous devez connaître le nombre de colonnes du tableau (vous pouvez trouver ce nombre en prenant une commande <tr> et en comptant tous les <td> à l'intérieur de celui-ci.

js :

document.addEventListener("keydown", function (e) {
if (e.keyCode == 39) document.getElementsByTagName("td").className = "";
var actualId = document.getElementsByClassName("active")[0].getAttribute("id");
var count = document.getElementsByTagName("td").length;
console.log(count)
document.getElementById(actualId).className="notActive";
if (parseInt(actualId)+1 < count) {
   document.getElementById(parseInt(actualId)+1).className="active";
} else {
   document.getElementById(0).className="active";
}
});

keyCode "39" est la touche flèche droite

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X