Задать вопрос
@Dbtzhv

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

В проекте джанго есть игровая комната. Решил сделать, чтобы заходящий в неё игрок добавлялся без перезагрузки. Но у каждого игрока есть несколько кнопок (смена уровня/расы и т.д.), которые работают через 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);
    });
});


Вот 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>
  • Вопрос задан
  • 77 просмотров
Подписаться 1 Простой 1 комментарий
Пригласить эксперта
Ответы на вопрос 1
@maksam07
Вешай событие на боди:

$('body')
        .on('click', '.player-date', e => {});
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы