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

时间:2013-05-30 18:43:04

标签: javascript events yui drag

我正在尝试为模仿Sublime文本编辑器的right-hand miniview的演讲构建Javascript UI。将一些文本加载到主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以编程方式更改滚动条会导致“滚动”事件触发,从而尝试以编程方式触发拖动事件我们最初用鼠标调用。我有点惊讶它没有无限激发。这似乎是不明智的。

如果事件是由手动操作调用的,是否有办法只触发事件?或者更好的方式来链接这两个不同的事件?我不介意解决方案是否使用YUI - 它只是我习惯的框架。感谢。

2 个答案:

答案 0 :(得分:1)

在滚动事件处理程序中,您不会触发拖动事件。您只需设置不会导致拖动事件触发的div位置。因此,没有机会骑自行车事件处理程序。

当用户拖动div时,拖动处理程序为编辑器设置scrollTop值。请注意,仅当scrollTop值确实更改时,此操作才会触发滚动事件。如果scrollTop的整数值与之前完全相同,则不会触发scroll事件。因此,即使您在滚动事件发生时实际触发了拖动事件,也不会出现循环。

这种行为没有害处。这很自然。

答案 1 :(得分:0)

@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);
});