javascript React JS中的滑动效果

dy2hfwbg  于 2023-10-14  发布在  Java
关注(0)|答案(4)|浏览(112)

我正在尝试使用React创建一个swipe事件。我不想使用任何外部组件或jquery。
css是这样的:

.outter{
  position:relative;
  width: 100%;
  height: 150px;
  background-color: blue;
}

.inner{
  position: absolute;
  width: 1000%; 
  left: 50px;
}
.child{
  float: left;
  margin-right: 15px;
}

在react组件中,我试图做这样的事情:

class Test extends React.Component {
    constructor(props){
    super(props);

    this.state = {
        left: 0
    }
  }

  handleSwipe(){
    this.setState({left: -350})
  }

  render(){
    return(
        <div className="outter">
            <div className="inner" style={{left: this.state.left}} onSwipe={this.handleSwipe.bind(this)}>
                 <div className="child"><img src="http://placehold.it/350x150" /></div>
                 <div className="child"><img src="http://placehold.it/350x150" /></div>
                 <div className="child"><img src="http://placehold.it/350x150" /></div>
                 <div className="child"><img src="http://placehold.it/350x150" /></div>
            </div>
      </div>
    )
  }
}

React.render(<Test />, document.getElementById('container'));

如何识别刷卡事件?
如果我在我的例子中,而不是onSwipe添加onClick它的工作,但我如何才能使滑动效果?
这里是jsfiddle

agxfikkp

agxfikkp1#

您可以将onTouch事件处理程序添加到React组件中:

onTouchStart={touchStartEvent => this.handleTouchStart(touchStartEvent)}
onTouchMove={touchMoveEvent => this.handleTouchMove(touchMoveEvent)}
onTouchEnd={() => this.handleTouchEnd()}

您可能还希望为鼠标事件添加事件处理程序,以实现跨平台兼容性:

onMouseDown={mouseDownEvent => this.handleMouseDown(mouseDownEvent)}
onMouseMove={mouseMoveEvent => this.handleMouseMove(mouseMoveEvent)}
onMouseUp={() => this.handleMouseUp()}
onMouseLeave={() => this.handleMouseLeave()}

在事件处理程序中更新状态的left属性是正确的,但是如果你想让滑动功能感觉自然,你需要通过使用事件的clientX属性更新left来跟踪指针的位置(无论是鼠标还是触摸)。
为此,您需要存储第一次触摸的位置,并将left设置为等于触摸位置的变化。为了增加真实感,您还可以跟踪触摸的速度,并在触摸完成后继续为组件设置动画。
这是我制作的一个快速而肮脏的Codepen,用于从列表中删除项目:
https://codepen.io/swingthing/pen/ZBGBJb/

9o685dep

9o685dep2#

我使用最流行的答案作为基础的解决方案来构建我所需要的。也许有人需要这样的东西。
想法是移动我的自定义滑块左右滑动效果。如果你想让它更敏感-调整值150至75。

const [touchStart, setTouchStart] = React.useState(0);
const [touchEnd, setTouchEnd] = React.useState(0);

function handleTouchStart(e) {
    setTouchStart(e.targetTouches[0].clientX);
}

function handleTouchMove(e) {
    setTouchEnd(e.targetTouches[0].clientX);
}

function handleTouchEnd() {
    if (touchStart - touchEnd > 150) {
        // do your stuff here for left swipe
        moveSliderRight();
    }

    if (touchStart - touchEnd < -150) {
        // do your stuff here for right swipe
        moveSliderLeft();
    }
}
u3r8eeie

u3r8eeie3#

也许我的解决方案对某人也有用:

export const useSwipe = ({left, right, up, down}: {left?: () => void; right?: () => void; up?: () => void; down?: () => void;}) => {
  const touchCoordsRef = useRef({touchStart: {x: 0, y: 0, time: Date.now()}});
  const fnsRef = useRef({up, down, left, right});
  fnsRef.current = {
    up,
    left,
    down,
    right,
  };
  useEffect(() => {
    const handleTouchStart = (e: TouchEvent) => {
      touchCoordsRef.current.touchStart.x = e.targetTouches[0].clientX;
      touchCoordsRef.current.touchStart.y = e.targetTouches[0].clientY;
      touchCoordsRef.current.touchStart.time = Date.now();
    };
    const handleTouchEnd = (e: TouchEvent) => {
      const threshold = 150;
      const swipeSpeed = 1; // sec;
      const touchEndX = e.changedTouches[0].clientX;
      const touchEndY = e.changedTouches[0].clientY;
      const touchStartX = touchCoordsRef.current.touchStart.x;
      const touchStartY = touchCoordsRef.current.touchStart.y;
      const elapsedTime = (Date.now() - touchCoordsRef.current.touchStart.time) / 1000;
      if(elapsedTime > swipeSpeed) {
        return;
      }
      const xDistance = touchStartX - touchEndX;
      const yDistance = touchStartY - touchEndY;

      if(Math.abs(xDistance) < threshold && Math.abs(yDistance) < threshold) {
        return;
      }

      if(Math.abs(xDistance) >= Math.abs(yDistance)) {
        xDistance > 0 ? fnsRef.current.right?.() : fnsRef.current.left?.();
      } else {
        yDistance > 0 ? fnsRef.current.down?.() : fnsRef.current.up?.();
      }
    };
    window.addEventListener('touchstart', handleTouchStart);
    window.addEventListener('touchend', handleTouchEnd);
    return () => {
      window.removeEventListener('touchstart', handleTouchStart);
      window.removeEventListener('touchend', handleTouchEnd);
    };
  });
};
7d7tgy0s

7d7tgy0s4#

刚刚发现了一个可能有用的DOM事件。将.ontouchend添加到HTML标记中以检测源自该标记的任何滑动事件。
https://www.w3schools.com/jsref/event_touchend.asp-参考

相关问题