Добавление списков событий ‘mouseover’ и ‘mouseout’ к чему-либо с применением getElementByTagName() только к последнему элементу

#javascript #html #css #addeventlistener #getelementbyid

#javascript #HTML #css — файл #addeventlistener #getelementbyid

Вопрос:

все. В настоящее время у меня возникла проблема с головоломкой из 15 слайдов, которую я пытаюсь создать. Критерием является то, что когда я наведу курсор мыши на фрагмент в моем слайдовом пазле, предполагается, что граница на этом фрагменте будет красной, а когда я уберу с него курсор мыши, граница должна вернуться к черному. Проблема в том, что события mouseover и mouseout, похоже, работают только с последним элементом, переданным через цикл for, и у меня возникли проблемы с разработкой решения.

Я перепробовал много разных способов, включая написание списков событий с помощью других комбинаций кода, но не получил успешного результата. На самом деле это самое близкое, что я получил.

Вот конкретный код, о котором идет речь:

 function movePiece(){
    var elements = document.getElementById("puzzlearea").getElementsByTagName('div');

    for(var i=0; i<elements.length; i  ){

        var item = elements.item(i);

        elements[i].addEventListener('mouseover', function(e){
            item.style.border = "5px solid red";
        },false);

        elements[i].addEventListener('mouseout', function(e){
            console.log(item);
            item.style.border = "5px solid black";
        },false);
    }
}
  

И сопутствующего ему HTML (я хотел бы отметить, что это присвоение класса, поэтому, к сожалению, изменение этого HTML не разрешено):

         <div id="puzzlearea">
            <!-- the following are the actual fifteen puzzle pieces -->
            <div>1</div>  <div>2</div>  <div>3</div>  <div>4</div>
            <div>5</div>  <div>6</div>  <div>7</div>  <div>8</div>
            <div>9</div>  <div>10</div> <div>11</div> <div>12</div>
            <div>13</div> <div>14</div> <div>15</div>
        </div>
  

И вот часть кода, который показывает, как I. создайте головоломку, а затем перетасуйте ее после нажатия кнопки shuffle:

 window.onload = onPageLoad;

/*
 * Loads the page with the initial puzzle, and operates all game logic.
 */
function onPageLoad() {
  createPuzzle();
  document.getElementById("shufflebutton").onclick = makeShuffle;
}

function playGame() {
    movePiece();
}

/*
 * Creates the initial puzzle. We go through each div in the puzzlearea
 * and set the position of the tile, as well as the image. This puzzle is
 * created in the correct, or completed, order.
 */
function createPuzzle() {
  var puzzlePiece = document.getElementById("puzzlearea").getElementsByTagName('div');
  for(let i = 0; i < puzzlePiece.length; i  ) {
    var item =  puzzlePiece.item(i);
    item.style.left = getLeftPosition(i);
    item.style.top = getTopPosition(i);
    item.style.backgroundPosition = getBackgroundPosition(i);
  }
}

/*
 * Shuffles the puzzle board. We go through each div in the puzzlearea
 * and set the position of the tile, as well as the image, based on the
 * shuffled order.
 */
function makeShuffle() {
  var puzzlePiece = document.getElementById("puzzlearea").getElementsByTagName('div');
  // Array of 0-14 in random order.
  var order = shuffleBoard();
  for(let i = 0; i < puzzlePiece.length; i  ) {
    var loc = order[i];
    var item =  puzzlePiece.item(i);
    item.style.position = "absolute";
    item.style.left = getLeftPosition(loc);
    item.style.top = getTopPosition(loc);
    item.style.backgroundPosition = getBackgroundPosition(i);
  }
    playGame();
}
  

И, при необходимости, немного соответствующего CSS:

 #puzzlearea {
  width: 400px;
  height: 400px;
  font-size: 40pt;
  color: white;
  margin-left: auto;
  margin-right: auto;
  position: relative;
}

#puzzlearea div {
  background-image: url('background.jpg');
  width: 90px;
  height: 90px;
  border: 5px solid black;
  float: left;
  cursor: defau<
}
  

Я ценю любую помощь!

Комментарии:

1. чего не стоит просто использовать CSS: наведите курсор

2. Избавьте себя от лишних хлопот и используйте CSS: #puzzlearea > div {border:5px solid black;} #puzzlearea > div:hover {border:5px solid red;}

3. Если вам разрешено добавлять в свой код немного CSS , вы можете использовать псевдокласс с именем :hover

Ответ №1:

Для этого вам вообще не нужны события javascript, просто используйте новый селектор CSS

 #puzzlearea div:hover {
  border-color: red;
}
  

вот демонстрация с большей частью вашего кода

 #puzzlearea {
  width: 400px;
  height: 400px;
  font-size: 40pt;
  color: white;
  margin-left: auto;
  margin-right: auto;
  position: relative;
}

#puzzlearea div {
  background-image: url('background.jpg');
  width: 90px;
  height: 90px;
  border: 5px solid black;
  float: left;
  cursor: defau<
}

#puzzlearea div:hover {
  border-color: red;
}

#puzzlearea div.state-1:hover {
  border-color: green;
}

#puzzlearea div.state-2:hover {
  border-color: purple;
}  
 <div id="puzzlearea">
    <!-- the following are the actual fifteen puzzle pieces -->
    <div class="state-1">1</div>  <div class="state-2">2</div>  <div>3</div>  <div>4</div>
    <div class="state-1">5</div>  <div class="state-2">6</div>  <div>7</div>  <div>8</div>
    <div>9</div>  <div>10</div> <div>11</div> <div>12</div>
    <div>13</div> <div>14</div> <div>15</div>
</div>  

Комментарии:

1. Это здорово, и я сожалею, что не указал это, но следующий шаг, который я собираюсь сделать, это изменить цвет границы фрагмента, только если выполнено определенное условие. Есть ли более простой способ включить это в это? Или мы говорим о чем-то более глубоком? По сути, если фрагмент можно переместить в пустое место слайдовой головоломки, то он должен измениться на красную рамку при наведении курсора мыши.

2. Вы могли бы добавить классы CSS для разных условий, а затем иметь правила CSS, которые переопределяют предыдущие состояния наведения. Я обновил код в своем ответе, чтобы показать это.

Ответ №2:

Вы могли бы просто добавить селектор наведения курсора в свой css

 border: 5px solid black;

:hover {
    border: 5px solid red;
}
  

Ответ №3:

Как упоминали другие, вы можете легко добиться этого с помощью CSS. Но поскольку это всего лишь шаг в рамках более масштабного плана действий, ваша функция должна работать, изменив item.style.border на e.target.style.border .

Это потому, что во время применения прослушивателя событий цикл завершен, и функции EventHandler (прикрепленные к каждому элементу) ссылаются на item как на последний элемент в for loop .

 function movePiece(){
    var elements = document.getElementById("puzzlearea").getElementsByTagName('div');

    for(var i=0; i<elements.length; i  ) {

        elements[i].addEventListener('mouseover', function(e){
            e.target.style.border = "5px solid red";
        },false);

        elements[i].addEventListener('mouseout', function(e){
            console.log(e.target);
            e.target.style.border = "5px solid black";
        },false);
    }
};
  

Тот же результат можно было бы использовать с forEach() insead for loop или с использованием let вместо var внутри самого цикла, но для новичка было бы лучше просто создать автономные обработчики событий.

Я бы рекомендовал поискать в Google ‘for loop eventlistener’, поскольку по этому вопросу доступно много ресурсов.