将Javascript拖动事件与滚动事件配对

Pairing a Javascript drag event with a scroll event

本文关键字:事件 滚动 拖动 Javascript      更新时间:2023-09-26

我正在尝试为演讲构建一个Javascript UI,模仿Sublime文本编辑器的右视图。在将一些文本加载到主div中后,我将该文本克隆到右侧更窄的div中,并将font-sizeline-height设置为非常小的值。

下面是jsFiddle使用旧的国情咨文地址的工作演示:http://jsfiddle.net/chriswilsondc/NYSSa/

黄色div动态调整大小,以表示左侧视图中文本的可见部分,正如您所期望的那样。然后,我将一个拖动事件附加到这个黄色框上,以模仿左侧窗格中滚动条的行为。我需要左边滚动条的原生功能绑定到右边框的拖动行为。我使用YUI drag模块,虽然我的问题更一般(我认为)。

现在,这是一个简单(如果草率)的问题,手动移动一侧时,另一侧被激活。

//right-hand side
dd.on("drag:drag", function(e) {
    console.log("dragged", e);
    var percentScrolled = Y.one("#pane").get('offsetTop') / ht_aer;
    //scroll the left side
    Y.one("#text").set("scrollTop", percentScrolled * ht_text_comp);
    //parallax scrolling of small-text version
    Y.one(".aerial .complete").setStyle("top", -ht_aer_comp * percentScrolled);
});

//left-hand side
Y.one("#text").on("scroll", function(e) {
    console.log("scrolled", e);
    var percentScrolled = e.currentTarget.get('scrollTop') / ht_text_comp;
    //parallax scrolling of small-text version
    Y.one(".aerial .complete").setStyle("top", -ht_aer_comp * percentScrolled);
    //manual drag 
    Y.one("#pane").setStyle('top', ht_aer * percentScrolled);
});
但是,如果您观察控制台日志,就会看到一个反向事件:通过拖动div以编程方式更改滚动条会触发"scroll"事件,从而尝试以编程方式触发我们最初用鼠标调用的拖动事件。我有点惊讶它没有无限发射。这似乎不明智。

是否有一种方法只触发一个事件,如果它是由手动操作调用?或者有更好的方法将这两个完全不同的事件联系起来?我不介意解决方案是否使用YUI——它只是我习惯的框架。谢谢。

在滚动事件处理程序中,不触发拖动事件。你只需要设置div的位置,它不会触发拖动事件。因此,没有机会循环事件处理程序。

当用户拖动div时,拖动处理程序为编辑器设置scrollTop值。注意,这个动作只在scrollTop值确实改变时才触发滚动事件。如果scrollTop的整数值与之前完全相同,则不会触发滚动事件。即使你在滚动事件发生时触发了拖动事件也不会有循环。

这种行为没有害处。这是自然的。

@Riateche解释了为什么它不会创建事件的无限循环。但是,您可能仍然希望滚动事件在拖动过程中不要触发,以避免潜在的视觉故障。所以基本上我们的想法是当你开始拖动时停止监听滚动事件并在拖动完成后继续监听。

在YUI中,您可以使用drag:startdrag:end事件。像这样:
function scrollHandler() {
  // ...
}
var scrollNode = Y.one('#foo');
scrollNode.on('scroll', scrollHandler);
dd.on('drag:start', function () {
  scrollNode.detach('scroll', scrollHandler);
});
dd.on('drag:end', function () {
  scrollNode.on('scroll', scrollHandler);
});