@Olddd

Как обрабатывать события drag and drop на touch устройствах?

Имеется следующий код, предназначеный для реализации механики мини-игры:
var music = {"a": new Audio("{% static 'mini_games/music/fo_la.mp3' %}"),
                "b": new Audio("{% static 'mini_games/music/fo_si.mp3' %}"),
                "c": new Audio("{% static 'mini_games/music/fo_do.mp3' %}"),
                "d": new Audio("{% static 'mini_games/music/fo_re.mp3' %}"),
                "e": new Audio("{% static 'mini_games/music/fo_mi.mp3' %}"),
                "f": new Audio("{% static 'mini_games/music/fo_fa.mp3' %}"),
                "g": new Audio("{% static 'mini_games/music/fo_sol.mp3' %}")}
    const draggableListItems = document.querySelectorAll('.draggable-list li');
    
    let selectedId;

    let dropTargetId;

    let matchingCounter = 0;

    addEventListeners();

    function dragStart() {
        selectedId = this.id;
    }

    function dragEnter() {
        this.classList.add('over');
    }

    function dragLeave() {
        this.classList.remove('over');
    }

    function dragOver(ev) {
        ev.preventDefault();
    }

    function dragDrop() {
    dropTargetId = this.id;

    if (checkForMatch(selectedId, dropTargetId)) {
        document.getElementById(selectedId).remove();
        document.getElementById(dropTargetId).classList.add("color");
        document.getElementById(dropTargetId).textContent = selectedId;
        audio = music[selectedId]
        audio.play()
        matchingCounter++;
    } else if (checkForMatch2(selectedId, dropTargetId)) {
        document.getElementById(selectedId).remove();
        document.getElementById(dropTargetId).classList.add("color");
        document.getElementById(dropTargetId).textContent = selectedId;
        matchingCounter++;
    }

    if (matchingCounter === 7) {
        window.setTimeout(1000)
        document.getElementById("overlay").style = "display: block";
    }

    this.classList.remove('over');
    }

    function checkForMatch(selected, dropTarget) {
        return dropTarget.indexOf(selected) >= 0
    }

    function checkForMatch2(selected, dropTarget) {
        return selected === dropTarget
    }

    function playAgain() {
            matchingCounter = 0;
            endMessage.style.display = 'none';
            draggableListItems.forEach(item => {
            document.getElementById(item.id).style.display = 'block';
        })
    }

    function addEventListeners() {
        draggableListItems.forEach (item => {
            item.addEventListener('dragstart', dragStart);
            item.addEventListener('dragenter', dragEnter);
            item.addEventListener('drop', dragDrop);
            item.addEventListener('dragover', dragOver);
            item.addEventListener('dragleave', dragLeave);
        })
    }


Работает это со следующим html кодом:
{% load static %}




<style>
    .match_game{
        width: 35.6vw;
        height: 17.6vw;
        margin: auto;
        background-image: url("{% static 'homepage/images/mini_games/notes_stan.svg' %}");
        background-size: contain;
        background-repeat: no-repeat;
    }
    li {
        list-style: none;
        width: 1.6vw;
        height: 1.6vw;
        background: #FFFFFF;
        border-radius: 0.8vw;
        display: flex;
        align-items: center;
        justify-content: space-around;
        color: #FFFFFF;
    }
    .seatings {
        display: flex;
        width: 19.24vw;
        height: 6.8vw;
        padding: 6vw 0 0 10.5vw;
        justify-content: space-between;
        transition-duration: .4s;
    }
    .seatings #a1 {margin-top: 0.88vw}
    .seatings #c1 {margin-top: 5.28vw}
    .seatings #d1 {margin-top: 4.4vw}
    .seatings #e1 {margin-top: 3.52vw}
    .seatings #f1 {margin-top: 2.64vw}
    .seatings #g1 {margin-top: 1.76vw}

    #a.color, #a1.color {background-color: #5993FF;}
    #b.color, #b1.color {background-color: #6D4FB8;}
    #c.color, #c1.color {background-color: #EE7273;}
    #d.color, #d1.color {background-color: #F0885C;}
    #e.color, #e1.color {background-color: #F8D981;}
    #f.color, #f1.color {background-color: #7BC46C;}
    #g.color, #g1.color {background-color: #72D3EE;}

    @media (max-width: 600px) {
        .match_game{
            width: 67vw;
            height: 30vw;
        }
        li {
            width: 3vw;
            height: 3vw;
            border-radius: 1.5vw;
            font-size: 2vw;
        }
        .seatings {
            width: 36.4vw;
            height: 12.9vw;
            padding: 11.5vw 0 0 19.7vw;
        }
        .seatings #a1 {margin-top: 1.5vw}
        .seatings #c1 {margin-top: 9.5vw}
        .seatings #d1 {margin-top: 7.9vw}
        .seatings #e1 {margin-top: 6.3vw}
        .seatings #f1 {margin-top: 4.7vw}
        .seatings #g1 {margin-top: 3vw}
    }
</style>

    
<div class="match_game">
    <ul class="draggable-list seatings">
        <li id="c1"></li>
        <li id="d1"></li>
        <li id="e1"></li>
        <li id="f1"></li>
        <li id="g1"></li>
        <li id="a1"></li>
        <li id="b1"></li>
    </ul>
    <div class="variants">
        <ul class="draggable-list" tabindex="1">
            <li id="d" class="color" draggable="true">d</li>
            <li id="e" class="color" draggable="true">e</li>
            <li id="f" class="color" draggable="true">f</li>
            <li id="c" class="color" draggable="true">c</li>
            <li id="g" class="color" draggable="true">g</li>
            <li id="a" class="color" draggable="true">a</li>
            <li id="b" class="color" draggable="true">b</li>
        </ul>
    </div>
</div>


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

P.S. замена touch events на mouse events не помогла
  • Вопрос задан
  • 460 просмотров
Пригласить эксперта
Ответы на вопрос 1
miraage
@miraage
Старый прогер
https://codesandbox.io/s/angry-booth-4pinuu?file=/...

const draggable = document.getElementById("draggable");

let isDragging = true;

draggable.addEventListener("touchstart", () => {
  isDragging = true;
});

draggable.addEventListener("touchend", () => {
  isDragging = false;
});

draggable.addEventListener("touchmove", (event) => {
  if (isDragging) {
    const { pageX, pageY } = event.touches[0];
    draggable.style.top = pageY + "px";
    draggable.style.left = pageX + "px";
  }
});
Ответ написан
Комментировать
Ваш ответ на вопрос

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

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