Javascript 安格拉斯的德拉戈弗和德拉格里夫

Javascript 安格拉斯的德拉戈弗和德拉格里夫,javascript,jquery,angularjs,Javascript,Jquery,Angularjs,我试图创建一个元素,用户可以在拖动元素时按住鼠标慢慢向下滚动页面。这是支持拖放编辑器所必需的 我正在检测用户是否悬停在锚上并正在拖动,如果是这样,我将启动一个$interval,在那里启动慢速滚动。如果鼠标离开锚点,或者用户停止拖动,则应取消慢速滚动,但不会取消。下面是我的代码 elem.on('dragover', mouseOver); elem.on('dragleave', mouseLeave); elem.on('dragend', mouseLeave); var scroll

我试图创建一个元素,用户可以在拖动元素时按住鼠标慢慢向下滚动页面。这是支持拖放编辑器所必需的

我正在检测用户是否悬停在锚上并正在拖动,如果是这样,我将启动一个
$interval
,在那里启动慢速滚动。如果鼠标离开锚点,或者用户停止拖动,则应取消慢速滚动,但不会取消。下面是我的代码

elem.on('dragover', mouseOver);

elem.on('dragleave', mouseLeave);
elem.on('dragend', mouseLeave);

var scroller = null;

function mouseOver(ev) {
    ev.preventDefault();

    console.log('over');

    scroller = $interval(function () {
        if (!scrolledToBottom()) {
            $(window).scrollTop($(window).scrollTop() + 1);
        }
    }, 10);

}

function mouseLeave(ev) {
    ev.preventDefault();

    console.log('left');

    $interval.cancel(scroller);
    scroller = null;
}

function scrolledToBottom() {
    return ($(window).scrollTop() + $(window).height()) == 
    $(document).height();
}
即使
console.log
启动得很好,滚动条也不会停止滚动。我认为这是因为Angular无法在事件触发时看到事件内部,并且无法将更改应用到滚动条。然而,Angular没有ngDragOver,我只能想到JQuery实现


有什么建议吗?

您的代码的问题是您注册了以下事件
elem.on('dragover',mouseOver)
elem.on('dragleave',mouseLeave)
elem.on('dragend',mouseLeave)
在操作过程中,会触发多个事件类型,并且可能会多次触发某些事件类型(例如drag和dragover事件类型)。

例如,您的
dragover
事件处理程序如下所示:

function mouseOver(ev) {
    ev.preventDefault();

    console.log('over');

    scroller = $interval(function () {
        if (!scrolledToBottom()) {
            $(window).scrollTop($(window).scrollTop() + 1);
        }
    }, 10);

}
因此,上面的事件处理程序将多次触发注册
$interval
,并将失去对旧承诺的引用

通过使用以下检查来修复此问题:

var scroller  = null;
function mouseOver(ev) {
    ev.preventDefault();

    console.log('over');

    if (scroller === null) {  // <-- This check will prevent multiple $interval registration.
        scroller = $interval(function () {
            if (!scrolledToBottom()) {
                $(window).scrollTop($(window).scrollTop() + 1);
            }
        }, 10);
    }

}
下面是一个要尝试的工作示例:

angular.module('myApp',[])
.directive('drag',函数($interval){
返回{
限制:“A”,
链接:函数(范围、元素、属性、ctrl){
元素on('dragover',鼠标盖);
元素on('dragend',mouseLeave);
var scroller=null;
功能鼠标盖(ev){
ev.preventDefault();
如果(滚动条===null){
滚动器=$interval(函数(){
如果(!scrolledToBottom()){
$(窗口).scrollTop($(窗口).scrollTop()+1);
}
}, 10);
}
}
移动鼠标功能(ev){
ev.preventDefault();
如果(滚动条!==null){
$interval.cancel(滚动条);
scroller=null;
}
}
函数scrolledToBottom(){
返回($(窗口).scrollTop()+$(窗口).height())==
$(文档).height();
}
}
}
});
.container{
填充:0;
保证金:0;
背景:蓝色;
高度:800px;
}
.容器.拖动{
高度:300px;
}
.容器。拖动{
颜色:白色;
}


代码的问题是您注册了以下事件
elem.on('dragover',mouseOver)
elem.on('dragleave',mouseLeave)
elem.on('dragend',mouseLeave)
在操作过程中,会触发多个事件类型,并且可能会多次触发某些事件类型(例如drag和dragover事件类型)。

例如,您的
dragover
事件处理程序如下所示:

function mouseOver(ev) {
    ev.preventDefault();

    console.log('over');

    scroller = $interval(function () {
        if (!scrolledToBottom()) {
            $(window).scrollTop($(window).scrollTop() + 1);
        }
    }, 10);

}
因此,上面的事件处理程序将多次触发注册
$interval
,并将失去对旧承诺的引用

通过使用以下检查来修复此问题:

var scroller  = null;
function mouseOver(ev) {
    ev.preventDefault();

    console.log('over');

    if (scroller === null) {  // <-- This check will prevent multiple $interval registration.
        scroller = $interval(function () {
            if (!scrolledToBottom()) {
                $(window).scrollTop($(window).scrollTop() + 1);
            }
        }, 10);
    }

}
下面是一个要尝试的工作示例:

angular.module('myApp',[])
.directive('drag',函数($interval){
返回{
限制:“A”,
链接:函数(范围、元素、属性、ctrl){
元素on('dragover',鼠标盖);
元素on('dragend',mouseLeave);
var scroller=null;
功能鼠标盖(ev){
ev.preventDefault();
如果(滚动条===null){
滚动器=$interval(函数(){
如果(!scrolledToBottom()){
$(窗口).scrollTop($(窗口).scrollTop()+1);
}
}, 10);
}
}
移动鼠标功能(ev){
ev.preventDefault();
如果(滚动条!==null){
$interval.cancel(滚动条);
scroller=null;
}
}
函数scrolledToBottom(){
返回($(窗口).scrollTop()+$(窗口).height())==
$(文档).height();
}
}
}
});
.container{
填充:0;
保证金:0;
背景:蓝色;
高度:800px;
}
.容器.拖动{
高度:300px;
}
.容器。拖动{
颜色:白色;
}


为什么你甚至需要定制卷轴?如果您将一个元素拖出视口,窗口滚动将自动发生。对于熟悉计算机的人来说,这是一个合理的响应,但恐怕我的用户不会。如果站点有固定的顶栏菜单,这也不适用于滚动备份。好的,这是有道理的,但是你应该记住要注意你可能会引入的任何其他可访问性问题(如果有的话)。不管怎样,看看我发布的答案。为什么你甚至需要定制卷轴?如果您将一个元素拖出视口,窗口滚动将自动发生。对于熟悉计算机的人来说,这是一个合理的响应,但恐怕我的用户不会。如果站点有固定的顶栏菜单,这也不适用于滚动备份。好的,这是有道理的,但是你应该记住要注意你可能会引入的任何其他可访问性问题(如果有的话)。不管怎样,看看我发布的答案。太好了!这有我需要的一切:)完美!这是我需要的一切:)