在实现类似 Vim 的热键时遇到问题
Having Trouble Implementing Vim-like Hotkeys
我正在尝试为我的项目实现类似 Vim 的热键;首先,我决定实现 j 和 k 绑定,所以我写了这个 KeyboardEvent
处理程序:
window.onkeydown = function( event ) {
if (event.code === 'KeyJ')
window.scrollBy({ top: 128, behavior: 'smooth' });
else if (event.code === 'KeyK')
window.scrollBy({ top: -128, behavior: 'smooth' });
};
似乎是合法的,对吧?实际上 — 不:当我 holding j 或 k 滚动过程变得脱节和撕裂(也是似乎滚动速度减半,就像 64
将被添加到 scrollTop
而不是 128
).
我能以某种方式直接将 k 映射到 ↑ 并将 j 映射到 ↓ 使用 plain JavaScript?
我已经试过了 solution:
const ArrowUp = new KeyboardEvent( 'keydown', { code: 'ArrowUp' } );
const ArrowDown = new KeyboardEvent( 'keydown', { code: 'ArrowDown' } );
window.onkeydown = function( event ) {
if (event.code === 'KeyJ')
window.dispatchEvent( ArrowDown );
else if (event.code === 'KeyK')
window.dispatchEvent( ArrowUp );
};
但它根本不起作用,我什至没有收到任何错误。
我有两个解决方案。第一个解决方案有点......我们只能说它不是很好。
您可以强制它每隔一段时间只监听事件以防止出现故障。
var lastScrollTime = Date.now();
window.onkeydown = function( event ) {
var d = Date.now();
if(d - lastScrollTime < 64){
return;
}
lastScrollTime = d;
if (event.code === 'KeyJ')
window.scrollBy({ top: 128, behavior: 'smooth' });
else if (event.code === 'KeyK')
window.scrollBy({ top: -128, behavior: 'smooth' });
};
我的第二个解决方案稍微好一点,但仍然不是很好。您可以实现自己的平滑滚动系统。
var scrollTo = 0;
function lerpTo(){
var newPt = lerp(scrollTo, window.scrollY, 1.1);
console.log(newPt);
window.scrollBy(0, window.scrollY - newPt);
}
function lerp(v0, v1, t) {
return v0*(1-t)+v1*t
}
setInterval(lerpTo, 20);
然后,您只需按 j 或 k 更改 'scrollTo'。现在该代码使用了 lerp 函数。如果您想要更一致的运动,您可以按固定数量更换它。那个最大的缺点是你不能再正常滚动了。要重新添加正常滚动,您必须监听该事件并再次设置滚动,但我认为这是一个糟糕的解决方案。或者,要再次添加正常滚动,您可以在手动滚动时禁用 lerp 代码,然后在有人按 j 或 k 时重新启用它。
我正在尝试为我的项目实现类似 Vim 的热键;首先,我决定实现 j 和 k 绑定,所以我写了这个 KeyboardEvent
处理程序:
window.onkeydown = function( event ) {
if (event.code === 'KeyJ')
window.scrollBy({ top: 128, behavior: 'smooth' });
else if (event.code === 'KeyK')
window.scrollBy({ top: -128, behavior: 'smooth' });
};
似乎是合法的,对吧?实际上 — 不:当我 holding j 或 k 滚动过程变得脱节和撕裂(也是似乎滚动速度减半,就像 64
将被添加到 scrollTop
而不是 128
).
我能以某种方式直接将 k 映射到 ↑ 并将 j 映射到 ↓ 使用 plain JavaScript?
我已经试过了 solution:
const ArrowUp = new KeyboardEvent( 'keydown', { code: 'ArrowUp' } );
const ArrowDown = new KeyboardEvent( 'keydown', { code: 'ArrowDown' } );
window.onkeydown = function( event ) {
if (event.code === 'KeyJ')
window.dispatchEvent( ArrowDown );
else if (event.code === 'KeyK')
window.dispatchEvent( ArrowUp );
};
但它根本不起作用,我什至没有收到任何错误。
我有两个解决方案。第一个解决方案有点......我们只能说它不是很好。 您可以强制它每隔一段时间只监听事件以防止出现故障。
var lastScrollTime = Date.now();
window.onkeydown = function( event ) {
var d = Date.now();
if(d - lastScrollTime < 64){
return;
}
lastScrollTime = d;
if (event.code === 'KeyJ')
window.scrollBy({ top: 128, behavior: 'smooth' });
else if (event.code === 'KeyK')
window.scrollBy({ top: -128, behavior: 'smooth' });
};
我的第二个解决方案稍微好一点,但仍然不是很好。您可以实现自己的平滑滚动系统。
var scrollTo = 0;
function lerpTo(){
var newPt = lerp(scrollTo, window.scrollY, 1.1);
console.log(newPt);
window.scrollBy(0, window.scrollY - newPt);
}
function lerp(v0, v1, t) {
return v0*(1-t)+v1*t
}
setInterval(lerpTo, 20);
然后,您只需按 j 或 k 更改 'scrollTo'。现在该代码使用了 lerp 函数。如果您想要更一致的运动,您可以按固定数量更换它。那个最大的缺点是你不能再正常滚动了。要重新添加正常滚动,您必须监听该事件并再次设置滚动,但我认为这是一个糟糕的解决方案。或者,要再次添加正常滚动,您可以在手动滚动时禁用 lerp 代码,然后在有人按 j 或 k 时重新启用它。