Javascript 支持画布上的滚动和拖动操作
我有一个程序,你可以通过拖动门来编辑电路。有时电路变得非常大,因此绘制它的画布元素超出了浏览器的视口,因此需要滚动 当使用触摸屏的用户在屏幕上滑动手指时,我希望从电路元件开始的幻灯片被解释为拖动。但是在空白处开始的幻灯片(由我的自定义逻辑决定画布上显示的内容)应该被解释为滚动 如何使拖动和滚动行为和谐共存?如何在不模拟浏览器通常的滚动行为的情况下执行?用户不喜欢滚动是不稳定的,这是本机的行为 (好处:在不改变通常的滚动行为的情况下,如何做到这一点,但仍然防止滚动触发导航操作[例如,在Android上,当已经在页面顶部时,向下拉将重新加载它]?)Javascript 支持画布上的滚动和拖动操作,javascript,scroll,drag-and-drop,cross-browser,touch,Javascript,Scroll,Drag And Drop,Cross Browser,Touch,我有一个程序,你可以通过拖动门来编辑电路。有时电路变得非常大,因此绘制它的画布元素超出了浏览器的视口,因此需要滚动 当使用触摸屏的用户在屏幕上滑动手指时,我希望从电路元件开始的幻灯片被解释为拖动。但是在空白处开始的幻灯片(由我的自定义逻辑决定画布上显示的内容)应该被解释为滚动 如何使拖动和滚动行为和谐共存?如何在不模拟浏览器通常的滚动行为的情况下执行?用户不喜欢滚动是不稳定的,这是本机的行为 (好处:在不改变通常的滚动行为的情况下,如何做到这一点,但仍然防止滚动触发导航操作[例如,在Androi
我试着只在希望画布控制并显示拖动时调用。当滚动条出现时(浏览器发送触摸,但随后立即取消触摸),该功能就会停止工作。CSS属性可能也很有用,但我没有对它进行过太多的实验。我最终使用的解决方法是blocker divs 对于画布中的每个可拖动元素,我在该元素的位置上添加了一个div,其中包含
touch action:none
、opacity:0
、和position:absolute
。当用户触碰其中一个拦截器div时,滚动将被阻止,而不会干扰拖动事件
setBlockers(blockers, overrideCursorStyle) {
// ensure enough blocker divs exist
while (this._blockerDivs.length < blockers.length) {
let blockerDiv = document.createElement('div');
blockerDiv.style.touchAction = 'none';
blockerDiv.style.position = 'absolute';
blockerDiv.style.opacity = 0;
this._parentElement.appendChild(blockerDiv);
this._blockerDivs.push(blockerDiv);
}
// reposition blocker divs
for (let i = 0; i < blockers.length; i++) {
let s = this._blockerDivs[i].style;
let {x, y, w, h, cursor} = blockers[i];
[s.left, s.top, s.width, s.height] = [x, y, w, h].map(e => e + "px");
s.cursor = overrideCursorStyle || cursor || 'auto';
s.display = 'inline';
}
// hide unused blocker divs
for (let i = blockers.length; i < this._blockerDivs.length; i++) {
this._blockerDivs[i].style.display = 'none';
}
}
backbockers(拦截器、覆盖器或样式){
//确保存在足够的拦截器div
while(此._blockerDivs.lengthe+“px”);
s、 cursor=overrideCursorStyle | | cursor | | | auto |;
s、 显示='内联';
}
//隐藏未使用的拦截器div
for(设i=blockers.length;i
这适用于Chrome和iOS上的Safari,但不适用于Firefox(不支持触摸操作:无)。我最后使用的解决方法是blocker divs 对于画布中的每个可拖动元素,我在该元素的位置上添加了一个div,其中包含
touch action:none
、opacity:0
、和position:absolute
。当用户触碰其中一个拦截器div时,滚动将被阻止,而不会干扰拖动事件
setBlockers(blockers, overrideCursorStyle) {
// ensure enough blocker divs exist
while (this._blockerDivs.length < blockers.length) {
let blockerDiv = document.createElement('div');
blockerDiv.style.touchAction = 'none';
blockerDiv.style.position = 'absolute';
blockerDiv.style.opacity = 0;
this._parentElement.appendChild(blockerDiv);
this._blockerDivs.push(blockerDiv);
}
// reposition blocker divs
for (let i = 0; i < blockers.length; i++) {
let s = this._blockerDivs[i].style;
let {x, y, w, h, cursor} = blockers[i];
[s.left, s.top, s.width, s.height] = [x, y, w, h].map(e => e + "px");
s.cursor = overrideCursorStyle || cursor || 'auto';
s.display = 'inline';
}
// hide unused blocker divs
for (let i = blockers.length; i < this._blockerDivs.length; i++) {
this._blockerDivs[i].style.display = 'none';
}
}
backbockers(拦截器、覆盖器或样式){
//确保存在足够的拦截器div
while(此._blockerDivs.lengthe+“px”);
s、 cursor=overrideCursorStyle | | cursor | | | auto |;
s、 显示='内联';
}
//隐藏未使用的拦截器div
for(设i=blockers.length;i
这适用于Chrome和iOS上的Safari,但不适用于Firefox(不支持触摸操作:无)