【发布时间】:2018-01-04 14:40:17
【问题描述】:
我有一个可以通过网络界面控制的 DSP 应用程序。为了允许用户设置某些数值,例如增益、灵敏度、音量、滤波器的频率限制等,我使用了 Anthony Therrien 中的 JQuery Knob 元素。
JQuery Knob 元素可以通过将光标放在旋钮上并启动滚轮来启动。但是,问题是,当您这样做时,不仅旋钮的值会发生变化,而且文档本身也会滚动,因此当您尝试使用滚轮(或触控板,或触摸屏,...)。
为了确保问题不是特定于我的应用程序并为我的问题提供代码示例,我实现了一个小型测试站点来演示该问题。
这是网站的 (X)HTML(5) 代码。
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>
Test page
</title>
<script src="js/include/jquery-3.2.1.js" type="text/javascript"></script>
<script src="js/include/jquery.knob.js" type="text/javascript"></script>
<script src="js/test.js" type="text/javascript"></script>
</head>
<body>
<div id="content">
<div>
Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod
tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquid
ex ea commodi consequat. Quis aute iure reprehenderit in voluptate
velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
obcaecat cupiditat non proident, sunt in culpa qui officia deserunt
mollit anim id est laborum.
</div>
</div>
<div>
<div class="param" style="display: inline-block">
<input class="knob" value="50" data-min="0" data-max="100"
data-step="1" data-width="150" data-height="150"
data-angleoffset="-135" data-anglearc="270"
data-rotation="clockwise" data-cursor="false"
data-thickness=".3" data-displayprevious="true"
data-bgcolor="#181818" data-fgcolor="#ff8800"
type="text"/>
</div>
</div>
</body>
</html>
这些是网站引用的js/test.js文件的内容。
/*
* This is called after the DOM initialized.
*/
function init() {
var contentDiv = $('#content').get(0);
var loremDiv = contentDiv.firstChild.nextSibling;
/*
* Replicate the lorem ipsum a couple of times to have
* content on the site for scrolling.
*/
for (var i = 0; i < 16; i++) {
var newNode = loremDiv.cloneNode(true);
contentDiv.appendChild(newNode);
}
/*
* Turn the input element into a JQuery knob.
*/
$('.knob').knob();
}
$(init);
JavaScript 代码用大量盲文填充网站,并将输入元素转换为 JQuery Knob。在浏览器中加载站点(我使用 Firefox 对其进行了测试,尽管我不怀疑问题是特定于浏览器的),向下滚动到旋钮,将光标放在旋钮上并启动滚动车轮。您将看到滚轮事件改变了两个旋钮的值和滚动文档。
为了防止当用户在光标放在旋钮上时启动滚轮时滚动文档,我尝试在 JQuery Knob 周围的 DIV 元素上注册一个事件处理程序,它捕获onwheel 事件。为此,我刚刚将以下代码插入到 init() 函数的主体中。
var paramDiv = $('.param').get(0);
/*
* Prevent site from scrolling when knob is actuated.
*/
paramDiv.onwheel = function(event) {
event.preventDefault();
}
(我刚刚意识到 StackOverflow 的语法突出显示将 event 突出显示为 JavaScript 关键字。但是,参数是否在行为上似乎没有区别被命名为 event 或 e 或其他。)
当光标放在旋钮上(或者更确切地说,包含它的 DIV)上时,当鼠标滚轮被启动时,这确实可以防止文档滚动。但是,它也阻止了鼠标滚轮驱动旋钮本身,从而破坏了整个目的。
我不明白为什么在周围的 DIV 捕获事件会阻止使用滚轮启动旋钮。据我了解,事件“向上传播 DOM 树”,从子节点传播到父节点。因此,旋钮(或它所包含的 DOM 元素)应该首先获得鼠标滚轮事件,从而使旋钮被滚轮驱动。然后,我希望事件在 DOM 树中“向上”传播(朝向父节点),以便最终被周围 DIV 上的事件处理程序捕获,从而防止文档被滚动。
但是,事实并非如此。当我在周围的 DIV 上捕获鼠标滚轮事件时,当光标放在旋钮上时,这确实可以防止网站滚动。但是,它也防止使用鼠标滚轮启动旋钮。任何人都知道,为什么会发生这种情况以及如何正确处理这个问题?
我想要实现的行为如下:
- 当光标放在旋钮上时启动滚轮仅会启动相应的旋钮,但不会不滚动文档。
- 在光标未放在旋钮上时启动滚轮可滚动文档。
我有一个 JQuery Knob 的修改版本,我在我的特定应用程序中使用它并且修复了几个问题。 (JQuery Knob 的代码目前未维护。存储库中的最后一次提交是在 2015 年 12 月。)但是,原始版本也会出现问题,因此当知道修复/解决方法时哪个有效对于最初的 JQuery Knob 实现,它很可能也适用于我的自定义版本。
感谢任何帮助。
【问题讨论】:
标签: javascript jquery scroll