Как навесить AJAX на элемент, добавляемый вебсокетом без перезагрузки страницы?

Ссылка скопирована
1 ответ

В проекте джанго есть игровая комната. Решил сделать, чтобы заходящий в неё игрок добавлялся без перезагрузки. Но у каждого игрока есть несколько кнопок (смена уровня/расы и т.д.), которые работают через AJAX. Теперь получается, что мой добавляемый вебсокетами игрок не имеет этих работающих кнопок (они просто ничего не делают).
Мне вроде посоветовали вручную навесить addEventListener, но я хз, насколько это правильно и как это вообще делается)

Вот AJAX:

$(document).ready(function() {     // Открытие модального окна при клике на имя игрока     $('.player-date').on('click', function() {         var $player = $(this).closest('.player');         var $modal = $('#playerDataEditModal');          // Заполнение полей модального окна         $modal.find('.name').text($player.find('.player-name').text());         $modal.find('.name').attr('player', $player.attr('player'));         $modal.find('.total').text($player.find('.total').text());         $modal.find('.level').val($player.find('.level').text());         $modal.find('.power').val($player.find('.power').text());          // Открытие модального окна         $player.addClass("active");         $modal.modal('show');     });      // Закрытие модального окна и обновление значений на странице     $("#playerDataEditModal").on("hide.bs.modal", function () {         var $player = $('.player.active');         var $modal = $('#playerDataEditModal');                  var obj = new Object();         obj.player = $modal.find('.name').attr('player');         obj.level = $modal.find('.level').val();         obj.power  = $modal.find('.power').val();         obj.total = $modal.find('.total').text();         obj.user_room = $modal.find('.total').text()                  $player.removeClass("active");         $player.find('.level').text(obj.level);         $player.find('.power').text(obj.power);         $player.find('.total').text(obj.total);          sendData(obj);     });      // Увеличение и уменьшение уровня игрока     $('.increase-level').on('click', function() {         var $level = $(this).closest('.player').find('.level');         var levelValue = parseInt($level.val());         $level.val(levelValue + 1);     });      $('.decrease-level').on('click', function() {     var $level = $(this).closest('.player').find('.level');     var levelValue = parseInt($level.val());         if (levelValue > 1) {         $level.val(levelValue - 1);         }     });      // Увеличение и уменьшение силы игрока     $('.increase-power').on('click', function() {         var $power = $(this).closest('.player').find('.power');         var powerValue = parseInt($power.val());         $power.val(powerValue + 1);     });      $('.decrease-power').on('click', function() {         var $power = $(this).closest('.player').find('.power');         var powerValue = parseInt($power.val());         if (powerValue > 1) {         $power.val(powerValue - 1);         }     });      // Расчет общей силы игрока     $('#playerDataEditModal').on('click', '.player-data-edit', function() {         var $modal = $('#playerDataEditModal');         var levelValue = parseInt($modal.find('.level').val());         var powerValue = parseInt($modal.find('.power').val());         var total = levelValue + powerValue;         $modal.find('.total').text(total);     }); });

$(document).ready(function() { // Открытие модального окна при клике на имя игрока $('.player-date').on('click', function() { var $player = $(this).closest('.player'); var $modal = $('#playerDataEditModal'); // Заполнение полей модального окна $modal.find('.name').text($player.find('.player-name').text()); $modal.find('.name').attr('player', $player.attr('player')); $modal.find('.total').text($player.find('.total').text()); $modal.find('.level').val($player.find('.level').text()); $modal.find('.power').val($player.find('.power').text()); // Открытие модального окна $player.addClass("active"); $modal.modal('show'); }); // Закрытие модального окна и обновление значений на странице $("#playerDataEditModal").on("hide.bs.modal", function () { var $player = $('.player.active'); var $modal = $('#playerDataEditModal'); var obj = new Object(); obj.player = $modal.find('.name').attr('player'); obj.level = $modal.find('.level').val(); obj.power = $modal.find('.power').val(); obj.total = $modal.find('.total').text(); obj.user_room = $modal.find('.total').text() $player.removeClass("active"); $player.find('.level').text(obj.level); $player.find('.power').text(obj.power); $player.find('.total').text(obj.total); sendData(obj); }); // Увеличение и уменьшение уровня игрока $('.increase-level').on('click', function() { var $level = $(this).closest('.player').find('.level'); var levelValue = parseInt($level.val()); $level.val(levelValue + 1); }); $('.decrease-level').on('click', function() { var $level = $(this).closest('.player').find('.level'); var levelValue = parseInt($level.val()); if (levelValue > 1) { $level.val(levelValue - 1); } }); // Увеличение и уменьшение силы игрока $('.increase-power').on('click', function() { var $power = $(this).closest('.player').find('.power'); var powerValue = parseInt($power.val()); $power.val(powerValue + 1); }); $('.decrease-power').on('click', function() { var $power = $(this).closest('.player').find('.power'); var powerValue = parseInt($power.val()); if (powerValue > 1) { $power.val(powerValue - 1); } }); // Расчет общей силы игрока $('#playerDataEditModal').on('click', '.player-data-edit', function() { var $modal = $('#playerDataEditModal'); var levelValue = parseInt($modal.find('.level').val()); var powerValue = parseInt($modal.find('.power').val()); var total = levelValue + powerValue; $modal.find('.total').text(total); }); });

Вот script в джанго-шаблоне на добавление игрока:

<script language="javascript">     var code = "{{ room.code }}"     var races = "{{ races }}"     var ws_url = 'ws://' + window.location.host + '/ws/room_player/';     var gendersSocket = new WebSocket(ws_url);      gendersSocket.onmessage = function(event) {         var data = JSON.parse(event.data);      if (data.code == code) {         console.log(data)         addNewPlayer(data)      }      };   function addNewPlayer(playerData) {     var tableBody = document.querySelector('.table tbody');      // Create a new row     var newRow = document.createElement('tr');     newRow.classList.add('inner-box', 'player');     newRow.setAttribute('player', playerData.pk);      var genderIcon;     if (playerData.gender === 'M') {         genderIcon = '<i class="fa fa-mars" gender="true" aria-hidden="true"></i>';     } else if (playerData.gender === 'F') {         genderIcon = '<i class="fa fa-venus" gender="true" aria-hidden="true"></i>';     } else {         genderIcon = '<i class="fa fa-tree" gender="true" aria-hidden="true"></i>';     }      // Create the HTML content for the row     var rowContent = `         <th scope="row">             <div class="player-date" data-toggle="modal" data-target="#playerDataEditModal">                 <h2><i class="fa fa-bolt" aria-hidden="true"></i> <span class='total' data-player-id-total1=${playerData.playerId}>${playerData.power + playerData.level}</span></h2>                 <p><i class="fa fa-line-chart" aria-hidden="true"></i> <span class='level' data-player-id-level=${playerData.playerId}>${playerData.level}</span>                         <i class="fa fa-gavel" aria-hidden="true"></i> <span class='power' data-player-id-power=${playerData.playerId}>${playerData.power}</span></p>             </div>         </th>          <td>             <div class="player-img player-gender" data-player-id-gender=${playerData.playerId}>                 ${genderIcon}                 <img src=${playerData.image} alt="Аватар пользователя />             </div>             <div class="username">                 <p>${playerData.username}</p>             </div>         </td>          <td>             <div class="player-wrap">                 <div class="meta d-inline-flex">                     <div class="race px-2">                         <div class="d-flex align-items-center">                             <i class="fa fa-user" aria-hidden="true"></i>                         <a href="#" class="btn btn-link dropdown-toggle player-race" data-bs-toggle="dropdown" aria-expanded="false" data-player-id=${playerData.playerId}>                             ${playerData.race}                         </a>                          <ul class="dropdown-menu">                             {% for player_race in races %}                                 <li><a class="dropdown-item" href="#">{{ player_race.1 }}</a></li>                             {% endfor %}                          </ul>                     {% comment %} </div> {% endcomment %}                     <div class="class px-2">                         <div class="btn-group">                             <i class="fa fa-gamepad" aria-hidden="true"></i>                         </div>                             <a href="#" class="btn btn-link dropdown-toggle player-class" data-bs-toggle="dropdown" aria-expanded="false"  data-player-id-2=${playerData.playerId}>                                 ${playerData.class}                             </a>                             <ul class="dropdown-menu">                                 {% for player_class in classes %}                                     {% comment %} <li><a class="dropdown-item" href="#">{{ player_class.0 }}</a></li> {% endcomment %}                                     <li><a class="dropdown-item" href="#">{{ player_class.1 }}</a></li>                                 {% endfor %}                              </ul>                         </div>                     </div>                  </div>             </div>         </td>          <td>             <div class="primary-btn">                 <a class="btn btn-primary" href="#"><i class="fa fa-bolt"                         aria-hidden="true"></i></a>             </div>         </td>     `;      newRow.innerHTML = rowContent;      // Append the new row to the table     tableBody.appendChild(newRow);   }   </script>

<script language="javascript"> var code = "{{ room.code }}" var races = "{{ races }}" var ws_url = 'ws://' + window.location.host + '/ws/room_player/'; var gendersSocket = new WebSocket(ws_url); gendersSocket.onmessage = function(event) { var data = JSON.parse(event.data); if (data.code == code) { console.log(data) addNewPlayer(data) } }; function addNewPlayer(playerData) { var tableBody = document.querySelector('.table tbody'); // Create a new row var newRow = document.createElement('tr'); newRow.classList.add('inner-box', 'player'); newRow.setAttribute('player', playerData.pk); var genderIcon; if (playerData.gender === 'M') { genderIcon = '<i class="fa fa-mars" gender="true" aria-hidden="true"></i>'; } else if (playerData.gender === 'F') { genderIcon = '<i class="fa fa-venus" gender="true" aria-hidden="true"></i>'; } else { genderIcon = '<i class="fa fa-tree" gender="true" aria-hidden="true"></i>'; } // Create the HTML content for the row var rowContent = ` <th scope="row"> <div class="player-date" data-toggle="modal" data-target="#playerDataEditModal"> <h2><i class="fa fa-bolt" aria-hidden="true"></i> <span class='total' data-player-id-total1=${playerData.playerId}>${playerData.power + playerData.level}</span></h2> <p><i class="fa fa-line-chart" aria-hidden="true"></i> <span class='level' data-player-id-level=${playerData.playerId}>${playerData.level}</span> <i class="fa fa-gavel" aria-hidden="true"></i> <span class='power' data-player-id-power=${playerData.playerId}>${playerData.power}</span></p> </div> </th> <td> <div class="player-img player-gender" data-player-id-gender=${playerData.playerId}> ${genderIcon} <img src=${playerData.image} alt="Аватар пользователя /> </div> <div class="username"> <p>${playerData.username}</p> </div> </td> <td> <div class="player-wrap"> <div class="meta d-inline-flex"> <div class="race px-2"> <div class="d-flex align-items-center"> <i class="fa fa-user" aria-hidden="true"></i> <a href="#" class="btn btn-link dropdown-toggle player-race" data-bs-toggle="dropdown" aria-expanded="false" data-player-id=${playerData.playerId}> ${playerData.race} </a> <ul class="dropdown-menu"> {% for player_race in races %} <li><a class="dropdown-item" href="#">{{ player_race.1 }}</a></li> {% endfor %} </ul> {% comment %} </div> {% endcomment %} <div class="class px-2"> <div class="btn-group"> <i class="fa fa-gamepad" aria-hidden="true"></i> </div> <a href="#" class="btn btn-link dropdown-toggle player-class" data-bs-toggle="dropdown" aria-expanded="false" data-player-id-2=${playerData.playerId}> ${playerData.class} </a> <ul class="dropdown-menu"> {% for player_class in classes %} {% comment %} <li><a class="dropdown-item" href="#">{{ player_class.0 }}</a></li> {% endcomment %} <li><a class="dropdown-item" href="#">{{ player_class.1 }}</a></li> {% endfor %} </ul> </div> </div> </div> </div> </td> <td> <div class="primary-btn"> <a class="btn btn-primary" href="#"><i class="fa fa-bolt" aria-hidden="true"></i></a> </div> </td> `; newRow.innerHTML = rowContent; // Append the new row to the table tableBody.appendChild(newRow); } </script>

Дополнительно:

https://yandex.ru/search/?text=javascript+делегиро...

Ответы:

Вешай событие на боди:

$('body')         .on('click', '.player-date', e => {});

$('body') .on('click', '.player-date', e => {});

Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Анна SEO Ответ

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

1. Добавьте обработчик события для вебсокета, который будет вызываться при получении новых данных с сервера. В этом обработчике вы будете обновлять содержимое страницы и инициировать AJAX-запрос для дополнительной загрузки данных.

2. Настройте AJAX-запрос для получения дополнительных данных с сервера. Обычно это делается с использованием jQuery или чистого JavaScript. Вы можете отправить запрос на определенный URL и получить ответ в формате JSON или HTML.

3. Обновите содержимое страницы с помощью полученных данных. Вы можете использовать jQuery или чистый JavaScript для обновления DOM-элементов с новой информацией.

Пример кода для реализации этого подхода:

// Обработчик события для вебсокета
websocket.onmessage = function(event) {
  // Получаем новые данные с сервера
  var newData = JSON.parse(event.data);
 
  // Обновляем содержимое страницы
  updatePage(newData);
 
  // Инициируем AJAX-запрос для получения дополнительных данных
  $.ajax({
    url: 'your-api-url',
    method: 'GET',
    success: function(response) {
      // Обновляем страницу с полученными данными
      updatePage(response);
    },
    error: function(xhr, status, error) {
      console.error(error);
    }
  });
};
 
// Функция для обновления содержимого страницы
function updatePage(data) {
  // Обновляем DOM-элементы на странице с новыми данными
  // Например, обновляем таблицу или список элементов
}

// Обработчик события для вебсокета websocket.onmessage = function(event) { // Получаем новые данные с сервера var newData = JSON.parse(event.data); // Обновляем содержимое страницы updatePage(newData); // Инициируем AJAX-запрос для получения дополнительных данных $.ajax({ url: 'your-api-url', method: 'GET', success: function(response) { // Обновляем страницу с полученными данными updatePage(response); }, error: function(xhr, status, error) { console.error(error); } }); }; // Функция для обновления содержимого страницы function updatePage(data) { // Обновляем DOM-элементы на странице с новыми данными // Например, обновляем таблицу или список элементов }

Этот подход позволит вам динамически обновлять содержимое страницы при получении данных через вебсокеты и загружать дополнительные данные с сервера без перезагрузки страницы.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно