捕获鼠标滚轮事件作为原生 HTML 属性
Capture mouse wheel event as native HTML attribute
我即将开始处理鼠标滚轮事件,但我在网上唯一能找到的是使用 addEventListener()。我想检测是原生 HTML 和 CSS。换句话说,我正在寻找类似的东西:
<span id='fooBar' onmousewheel='alert("fooBar")'></span>
我正在动态创建 span 并将它们注入 DOM,如果我不必 运行 javascript 这样做,效果会更好。我似乎可以在本机工作但不是鼠标滚轮的所有其他事件。这可能吗?
你只找到对 addEventListener()
的引用的原因是因为那是 standard 和正确的方法(看起来 onmousewheel
在 Firefox 中甚至不被支持)。
虽然可以使用您在问题中显示的代码使其工作(在支持它的浏览器中)(除了您的 span
是空的,所以您不能用它启动事件,因为元素不会有任何渲染大小),我在下面有一个例子,内联 HTML 事件处理属性的使用让人回想起我们有标准之前的时间,不应该使用。 Here's a link 我的另一个回答解释了原因。
<span id='fooBar' onmousewheel='alert("fooBar")'>Use the mousewheel while mouse is over this</span>
您可以非常轻松地动态创建带有侦听器的元素。您只需要了解 DOM 以及如何附加事件侦听器。
下面的示例创建了 10 个跨度并为每个跨度附加了一个侦听器。只需将鼠标悬停在一个跨度上并滚动鼠标滚轮。跨度的 ID 将记录到控制台。
// Create 10 spans with a scroll listener.
var count = 10;
for (var i = 0; i < count; i++) {
var span = document.createElement('SPAN');
span.id = 'foo-bar-' + i;
span.innerHTML = 'Foo #' + i;
addEventListener(span, 'mousewheel', performEvent);
document.body.appendChild(span);
}
// Event function.
function performEvent(e) {
console.log(e.target.id);
}
// IE 8+ via http://youmightnotneedjquery.com/
function addEventListener(el, eventName, handler) {
if (el.addEventListener) {
el.addEventListener(eventName, handler);
} else {
el.attachEvent('on' + eventName, function(){
handler.call(el);
});
}
}
.as-console-wrapper { max-height: 5em !important; }
span[id^="foo-bar-"] {
border: thin solid black;
margin: 0.25em;
}
尝试以下操作:
::-webkit-scrollbar {
width: 0px; /* remove scrollbar space */
background: transparent; /* optional: just make scrollbar invisible */
}
<!DOCTYPE HTML>
<html>
<body style="overflow: auto;
max-height: 100vh;" onscroll="alert('hi')">
<div style="height:2000px;width:100%"></div>
</body>
</html>
你只找到 "addEventListener" 个例子的原因是你需要处理这个跨浏览器:
var supportedWheelEvent = "onwheel" in HTMLDivElement.prototype ? "wheel" : document.onmousewheel !== undefined ? "mousewheel" : "DOMMouseScroll";
此外,最好只对一个元素执行此操作!使用委托事件侦听器来处理您需要的所有元素。
HTML 示例:
<div id="delegator">
<div class="handleWheel">handle wheel event here</div>
<div> no wheel event handled here </div>
<div class="handleWheel">handle wheel event here</div>
<div> no wheel event handled here </div>
</div>
JS:
var supportedWheelEvent = "onwheel" in HTMLDivElement.prototype ? "wheel" : document.onmousewheel !== undefined ? "mousewheel" : "DOMMouseScroll";
function handler(e){
if(e.target.classList.contains('handleWheel')){
// handle the event here
}
}
var d = document.getElementById('delegator');
d.addEventListener(supportedWheelEvent, handler);
工作代码笔示例:
https://codepen.io/Mchaov/pen/zwaMmM
内联与委派
在演示中,A 方使用标准 addEventListener
并注册 wheel
事件,该事件是已弃用的 mousewheel
事件的替代品。使用 addEventListener
不仅是标准,而且如果使用 event delegation 则效率最高。
使用 onwheel
作为属性事件的支持有限,因为使用任何属性事件都是非标准的并且不鼓励使用。尽管如此,我还是包含了 B 面,它使用已弃用的非标准 onmousewheel
事件作为属性内联事件处理程序。因为它是一个笨拙的编码 <span>
,所以我在使用所有三个引号(即 '
、"
、`)的字符串上使用了 insertAdjacentHTML
。在第二层嵌套引号中使用了字符串文字,非常混乱。
请参阅此 post,了解如何在事件委托中使用事件对象属性。
详情在demo中评论
演示
// Reference the buttons
const btnA = document.getElementById('addA');
const btnB = document.getElementById('addB');
// Reference the parent nodes
const secA = document.querySelector('section:first-of-type');
const secB = document.querySelector('section:last-of-type');
// Register the click event on buttons
btnA.addEventListener('click', addNodeA, false);
btnB.addEventListener('click', addNodeB, false);
/* Register the wheel event on section A
|| which is the parent node of the wheeled
|| nodes. Event delegation involves one
|| event handler for multiple event targets.
|| This is far more efficient than multiple
|| inline event handlers.
*/
secA.addEventListener('wheel', markNode, false);
let cnt = 0;
/* Add node A to section A
|| ex. <span id="A1" class="A">A1</span>
*/
function addNodeA(e) {
cnt++;
var nodeA = document.createElement('span');
nodeA.id = 'A' + cnt;
nodeA.textContent = nodeA.id;
nodeA.className = 'A';
secA.appendChild(nodeA);
return false;
}
/* Add node B to section B
|| ex. <span id="B3" class="B" onmousewheel="this.style.outline = `5px dashed red`">B3</span>
*/
function addNodeB(e) {
cnt++;
/* This string is wrapped in single quotes,
|| double quotes for the attributes values,
|| and backticks for the property value of
|| an attribute value. Very messy, confusing,
|| and inefficient.
*/
var nodeB = '<span id="B' + cnt + '" class="B" onmousewheel="this.style.outline = `5px dashed red`">B' + cnt + '</span>';
// insertAdjacentHTML is innerHTML on steroids
secB.insertAdjacentHTML('beforeend', nodeB);
return false;
}
function markNode(e) {
/* If the wheeled node (i.e. e.target) is not the
|| registered node (i.e. e.currentTarget), then...
*/
if (e.target !== e.currentTarget) {
var node = e.target;
if (node.className === 'A') {
node.style.outline = '5px dashed blue';
} else {
return false;
}
}
}
html,
body {
width: 100%;
width: 100%
}
fieldset {
height: 10%;
}
main {
border: 3px solid lime;
height: 90%;
min-height: 250px;
display: flex;
}
section {
width: 50%;
min-height: 250px;
outline: 3px dashed gold;
padding: 10px 25px;
}
span {
height: 50px;
width: 50px;
padding: 2px;
text-align: center;
font-size: 12px;
margin: 5px;
display: inline-block;
}
.A {
background: rgba(0, 100, 200, .3);
}
.B {
background: rgba(200, 100, 0, .3);
}
#addB {
margin-left: 35%
}
<fieldset>
<legend>addNode</legend>
<button id='addA'>nodeA</button>
<button id='addB'>nodeB</button>
</fieldset>
<main>
<section></section>
<section></section>
</main>
我即将开始处理鼠标滚轮事件,但我在网上唯一能找到的是使用 addEventListener()。我想检测是原生 HTML 和 CSS。换句话说,我正在寻找类似的东西:
<span id='fooBar' onmousewheel='alert("fooBar")'></span>
我正在动态创建 span 并将它们注入 DOM,如果我不必 运行 javascript 这样做,效果会更好。我似乎可以在本机工作但不是鼠标滚轮的所有其他事件。这可能吗?
你只找到对 addEventListener()
的引用的原因是因为那是 standard 和正确的方法(看起来 onmousewheel
在 Firefox 中甚至不被支持)。
虽然可以使用您在问题中显示的代码使其工作(在支持它的浏览器中)(除了您的 span
是空的,所以您不能用它启动事件,因为元素不会有任何渲染大小),我在下面有一个例子,内联 HTML 事件处理属性的使用让人回想起我们有标准之前的时间,不应该使用。 Here's a link 我的另一个回答解释了原因。
<span id='fooBar' onmousewheel='alert("fooBar")'>Use the mousewheel while mouse is over this</span>
您可以非常轻松地动态创建带有侦听器的元素。您只需要了解 DOM 以及如何附加事件侦听器。
下面的示例创建了 10 个跨度并为每个跨度附加了一个侦听器。只需将鼠标悬停在一个跨度上并滚动鼠标滚轮。跨度的 ID 将记录到控制台。
// Create 10 spans with a scroll listener.
var count = 10;
for (var i = 0; i < count; i++) {
var span = document.createElement('SPAN');
span.id = 'foo-bar-' + i;
span.innerHTML = 'Foo #' + i;
addEventListener(span, 'mousewheel', performEvent);
document.body.appendChild(span);
}
// Event function.
function performEvent(e) {
console.log(e.target.id);
}
// IE 8+ via http://youmightnotneedjquery.com/
function addEventListener(el, eventName, handler) {
if (el.addEventListener) {
el.addEventListener(eventName, handler);
} else {
el.attachEvent('on' + eventName, function(){
handler.call(el);
});
}
}
.as-console-wrapper { max-height: 5em !important; }
span[id^="foo-bar-"] {
border: thin solid black;
margin: 0.25em;
}
尝试以下操作:
::-webkit-scrollbar {
width: 0px; /* remove scrollbar space */
background: transparent; /* optional: just make scrollbar invisible */
}
<!DOCTYPE HTML>
<html>
<body style="overflow: auto;
max-height: 100vh;" onscroll="alert('hi')">
<div style="height:2000px;width:100%"></div>
</body>
</html>
你只找到 "addEventListener" 个例子的原因是你需要处理这个跨浏览器:
var supportedWheelEvent = "onwheel" in HTMLDivElement.prototype ? "wheel" : document.onmousewheel !== undefined ? "mousewheel" : "DOMMouseScroll";
此外,最好只对一个元素执行此操作!使用委托事件侦听器来处理您需要的所有元素。
HTML 示例:
<div id="delegator">
<div class="handleWheel">handle wheel event here</div>
<div> no wheel event handled here </div>
<div class="handleWheel">handle wheel event here</div>
<div> no wheel event handled here </div>
</div>
JS:
var supportedWheelEvent = "onwheel" in HTMLDivElement.prototype ? "wheel" : document.onmousewheel !== undefined ? "mousewheel" : "DOMMouseScroll";
function handler(e){
if(e.target.classList.contains('handleWheel')){
// handle the event here
}
}
var d = document.getElementById('delegator');
d.addEventListener(supportedWheelEvent, handler);
工作代码笔示例: https://codepen.io/Mchaov/pen/zwaMmM
内联与委派
在演示中,A 方使用标准 addEventListener
并注册 wheel
事件,该事件是已弃用的 mousewheel
事件的替代品。使用 addEventListener
不仅是标准,而且如果使用 event delegation 则效率最高。
使用 onwheel
作为属性事件的支持有限,因为使用任何属性事件都是非标准的并且不鼓励使用。尽管如此,我还是包含了 B 面,它使用已弃用的非标准 onmousewheel
事件作为属性内联事件处理程序。因为它是一个笨拙的编码 <span>
,所以我在使用所有三个引号(即 '
、"
、`)的字符串上使用了 insertAdjacentHTML
。在第二层嵌套引号中使用了字符串文字,非常混乱。
请参阅此 post,了解如何在事件委托中使用事件对象属性。
详情在demo中评论
演示
// Reference the buttons
const btnA = document.getElementById('addA');
const btnB = document.getElementById('addB');
// Reference the parent nodes
const secA = document.querySelector('section:first-of-type');
const secB = document.querySelector('section:last-of-type');
// Register the click event on buttons
btnA.addEventListener('click', addNodeA, false);
btnB.addEventListener('click', addNodeB, false);
/* Register the wheel event on section A
|| which is the parent node of the wheeled
|| nodes. Event delegation involves one
|| event handler for multiple event targets.
|| This is far more efficient than multiple
|| inline event handlers.
*/
secA.addEventListener('wheel', markNode, false);
let cnt = 0;
/* Add node A to section A
|| ex. <span id="A1" class="A">A1</span>
*/
function addNodeA(e) {
cnt++;
var nodeA = document.createElement('span');
nodeA.id = 'A' + cnt;
nodeA.textContent = nodeA.id;
nodeA.className = 'A';
secA.appendChild(nodeA);
return false;
}
/* Add node B to section B
|| ex. <span id="B3" class="B" onmousewheel="this.style.outline = `5px dashed red`">B3</span>
*/
function addNodeB(e) {
cnt++;
/* This string is wrapped in single quotes,
|| double quotes for the attributes values,
|| and backticks for the property value of
|| an attribute value. Very messy, confusing,
|| and inefficient.
*/
var nodeB = '<span id="B' + cnt + '" class="B" onmousewheel="this.style.outline = `5px dashed red`">B' + cnt + '</span>';
// insertAdjacentHTML is innerHTML on steroids
secB.insertAdjacentHTML('beforeend', nodeB);
return false;
}
function markNode(e) {
/* If the wheeled node (i.e. e.target) is not the
|| registered node (i.e. e.currentTarget), then...
*/
if (e.target !== e.currentTarget) {
var node = e.target;
if (node.className === 'A') {
node.style.outline = '5px dashed blue';
} else {
return false;
}
}
}
html,
body {
width: 100%;
width: 100%
}
fieldset {
height: 10%;
}
main {
border: 3px solid lime;
height: 90%;
min-height: 250px;
display: flex;
}
section {
width: 50%;
min-height: 250px;
outline: 3px dashed gold;
padding: 10px 25px;
}
span {
height: 50px;
width: 50px;
padding: 2px;
text-align: center;
font-size: 12px;
margin: 5px;
display: inline-block;
}
.A {
background: rgba(0, 100, 200, .3);
}
.B {
background: rgba(200, 100, 0, .3);
}
#addB {
margin-left: 35%
}
<fieldset>
<legend>addNode</legend>
<button id='addA'>nodeA</button>
<button id='addB'>nodeB</button>
</fieldset>
<main>
<section></section>
<section></section>
</main>