使用Javascript模拟滚动事件

8

我正在尝试使用Javascript模拟移动Safari的滚动事件。

我正在使用以下代码:

var evt = document.createEvent("MouseEvents");    
evt.initMouseEvent("scroll", true, true, window,0, 0, 0, 0, 0, false, false, false, false, 0, null);

上面的代码是jQuery插件jQuery.UI.Ipad的一部分,它基本上将触摸事件(如touchstart,touchmove,touchend)映射到鼠标事件(如mouseover,mousedown等)。
然而,由于某些原因,模拟滚动事件的代码无法正常工作...请帮助我。因此,我的问题实质上是如何模拟滚动事件。
5个回答

3

所以,我知道我也需要模拟它。对于我来说,当您有一个带有溢出框的灯箱时,您将需要它。这只是我可以想到的许多情况之一。正在寻找答案。只是想分享我现在所在的位置,虽然没有使用jQuery.Ui.Ipad,但我会搜索一下..但到目前为止,这就是我得到的东西,确实起作用但不完美。

    var inTouch=false;
    var timers_arr = new Array();
    var c=0;
    var t;
    var timer_is_on=0;
    //-------------------------------------------------------------------------------------------------------------------------------------------------------------
    // jeremy's timer functions
    //-------------------------------------------------------------------------------------------------------------------------------------------------------------
        function clearCount(timer){
                /// clear the time from timer
                clearTimeout(timers_arr[timer]);
                /// Make sure it's clear  
                timers_arr[''+timer+'']=0;
                delete timers_arr[''+timer+''];

        }
        function setCount(timer,time,func){
                clearCount(timer);
                if(timers_arr[timer]==0||typeof(timers_arr[timer]) === 'undefined'){
                  timers_arr[timer]=setTimeout(function(){
                                        func();                                                 
                        },time);
                }
        }

    function updatePos(evt,startY){
        setCount('touchmove',1,function(){
            var orig = evt.originalEvent;
            var curY = orig.changedTouches[0].pageY;
            var y = curY - startY;
            var sliderVal = $("#slider-vertical").slider("value");
            sliderVal += (y*.008);
            $("#slider-vertical").slider("value", sliderVal);
            updatePos(evt,startY);
        });
        setCount('touchmove_anitMotion',200,function(){
            clearCount('touchmove');
            clearCount('touchmove_anitMotion');
        });
    }
    var startX=0;
    var startY=0;
    var x=0;
    var y=0;
    var direction='';
    $('body').bind("onorientationchange", updateOrientation, false);
    $('#scroll-pane').live("touchstart", function(evt){
       inTouch=true;
       startX = event.targetTouches[0].pageX; 
       startY = event.targetTouches[0].pageY; 
    }); 
    $('#scroll-pane').live("touchmove", function(evt){
        evt.stopPropagation();
        evt.preventDefault();
        updatePos(evt,startY);
    }); 
    $('#scroll-pane').live("touchend", function(evt){
        startX=0;
        startY=0;
        clearCount('touchmove');
        inTouch=false;
    }); 
    $('#scroll-pane').live("touchcancel", function(evt){
        startX=0;
        startY=0;
        clearCount('touchmove');
        inTouch=false;
    });

再次说明并非完美,正在修复中......但至少它已经可以使用。现在注意,这是一个div,它使用jQuery UI滑块作为滚动条(尽管在我的示例中是垂直的),如http://jqueryui.com/demos/slider/#side-scroll所示。

希望这能激发一些想法。如果我得到一个超级稳定的答案,我会回来的。 谢谢 -Jeremy


3

我认为人们对于为什么要重写滚动控制感到困惑。我可以理解你想模拟鼠标事件的原因,但滚动可能不应该是其中之一。

通常情况下,你只需要使用以下代码获取滚动条即可实现滚动变化:

var top = document.body.scrollTop;

并设置为:

document.body.scrollLeft = sX;
document.body.scrollTop = sY;

这个可能吗?window.document.body.onscroll = doSomething; - MrHayman
或者?window.scrollTo(0, 1); - MrHayman

1
我需要这个来编写一个单元测试,为此我需要模拟滚动事件。
function dispatchScroll(target,newScrollTop) {
      target.scrollTop = newScrollTop;
      var e = document.createEvent("UIEvents");
      // creates a scroll event that bubbles, can be cancelled,
      // and with its view and detail property initialized to window and 1,
      // respectively
      e.initUIEvent("scroll", true, true, window, 1);
      target.dispatchEvent(e);
    }

更多细节请查看:https://developer.mozilla.org/en-US/docs/Web/API/event.initUIEvent


1
我使用的事件是mousewheel,第五个参数应该为正数以进行向下滚动,为负数则向上滚动。
var evt = document.createEvent("MouseEvents");    
evt.initMouseEvent("mousewheel", true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);

请注意,对于FireFox,事件类型是DOMMouseScroll

0
现在应该使用CustomEvent创建事件,例如:new CustomEvent("wheel", { detail: { deltaY: 1 } })document.createEvent已被弃用。

https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent

我编写了这个实用函数,它可以在每一帧滚动1像素。
const startFakeScrolling = (container: HTMLDivElement) => {
  const cb = () => {
    container.dispatchEvent(
      new CustomEvent("wheel", { detail: { deltaY: 1 } })
    );
    window.requestAnimationFrame(cb);
  };
  window.requestAnimationFrame(cb);
};

您还需要修改事件监听器以使用detail,因为deltaY将未定义

const delta = e.deltaY != null ? e.deltaY : (e.detail as any).deltaY;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接