Я пытаюсь сделать список смахивания в javascript, что-то вроде приложения Gmail на Android.Я использую такие события, как touchstart
, touchmove
и touchend
.Все работает нормально, когда я провожу элемент списка влево или вправо, но когда я пытаюсь прокрутить список вниз, он перемещает элемент списка, на котором находится мой палец (потому что я не перетаскиваю палец полностью вертикально при прокрутке).Есть ли простой способ решить эту проблему, отличая событие свайпа от события прокрутки или что-то в этом роде?
const SwipeOutList = function(listId, items) {
const listElement = document.getElementById(listId);
let touchStart = null;
let movedTo = null;
const findContentParent = function(element) {
if(!element.parentNode) {
return null;
}
if(element.className === 'content') {
return element;
} else {
return findContentParent(element.parentNode);
}
};
const fja = function(e) {
movedTo = e.changedTouches[0].clientX;
let contentElement;
if(e.target.className === 'content') {
contentElement = e.target;
} else {
contentElement = findContentParent(e.target);
}
console.log(contentElement);
if(touchStart > movedTo) {
contentElement.style.transform = `translate3d(${-Math.abs(touchStart - movedTo)}px, 0px, 0px)`;
} else {
contentElement.style.transform = `translate3d(${Math.abs(touchStart - movedTo)}px, 0px, 0px)`;
}
};
const handleTouchEnd = function(e) {
let contentElement = e.target;
if(contentElement.className !== 'content') {
contentElement = findContentParent(contentElement);
}
let a = parseInt(contentElement.style.transform.split('(')[1]);
if(Math.abs(a) > contentElement.offsetWidth/2) {
swipeOut(a, contentElement);
} else {
snapBack(a, contentElement);
}
};
const snapBack = function(currentTransform, element) {
let interval = setInterval(() => {
if(currentTransform > 0) {
element.style.transform = `translate3d(${currentTransform - 5}px, 0px, 0px)`;
currentTransform -= 5;
} else {
element.style.transform = `translate3d(${currentTransform + 5}px, 0px, 0px)`;
currentTransform += 5;
}
if(Math.abs(currentTransform) <= 5) {
element.style.transform = `translate3d(0px, 0px, 0px)`;
clearInterval(interval);
}
if(currentTransform === 0) {
clearInterval(interval);
}
}, 10);
};
const composeListItem = function(content) {
let listItem = document.createElement('div');
listItem.className = 'swipe-out-list-item';
listItem.style.cssText = 'position: relative; height: 100px; transition: height .5s;';
let contentElement = document.createElement('div');
contentElement.className = 'content';
contentElement.style.cssText = 'box-sizing: border-box; background-color: white; position:absolute; top: 0; left: 0; border-bottom: solid 1px blue; min-height: 2em; width: 100%; height: 100%;';
if(content.nodeType === Node.ELEMENT_NODE) {
contentElement.appendChild(content);
} else {
contentElement.innerText = content;
}
listItem.appendChild(contentElement);
let backgroundElement = document.createElement('div');
backgroundElement.className = 'background';
backgroundElement.style.cssText = 'display: flex; align-items: center; justify-content: space-between; transition: all 0.5s; z-index: -1; background-color: red; position: absolute; top: 0; left: 0; width: 100%; height: 100%;';
backgroundElement.innerHTML = `
<div style="transition: all .5s;">trash</div>
<div style="transition: all .5s;">trash</div>
`;
listItem.appendChild(backgroundElement);
return listItem;
};
const swipeOut = function(currentTransform, element) {
let interval = setInterval(() => {
if(currentTransform > 0) {
element.style.transform = `translate3d(${currentTransform + 5}px, 0px, 0px)`;
currentTransform += 5;
} else {
element.style.transform = `translate3d(${currentTransform - 5}px, 0px, 0px)`;
currentTransform -= 5;
}
if(Math.abs(currentTransform) >= element.offsetWidth + 20) {
const parent = element.parentNode;
parent.removeChild(element);
parent.style.height = '0px';
parent.children[0].children[0].style.opacity = 0;
parent.children[0].children[1].style.opacity = 0;
setTimeout(() => {
parent.parentNode.removeChild(parent);
}, 500);
clearInterval(interval);
}
}, 5);
};
for (let i = 0; i < items.length; i++) {
listElement.appendChild(composeListItem(items[i]));
}
let array2 = document.querySelectorAll('.content');
for(let i = 0; i < array2.length; i++) {
array2[i].addEventListener('touchstart', function(e) {
touchStart = e.touches[0].clientX;
})
array2[i].addEventListener('touchmove', fja);
array2[i].addEventListener('touchend', handleTouchEnd);
}
};