uni-app中使用renderjs在视图层创建摇杆,摇杆addEventListener监听滑动时,this.$ownerInstance.callMethod函数不起作用
uni-app中使用renderjs在视图层创建摇杆,摇杆addEventListener监听滑动时,this.$ownerInstance.callMethod函数不起作用
使用renderjs在视图层创建了一个摇杆,摇杆addEventListener监听滑动,在监听函数里面,使用this.$ownerInstance.callMethod函数不起作用,请问我该怎样才能调用逻辑层函数?
代码如下:
renderBtn() {
var bottom = document.getElementById(".bottom");
if (!bottom) {
bottom = document.createElement("div");
bottom.classList = ["bottom"];
document.body.appendChild(bottom);
var that = this;
window.off = function() {
plus.nativeUI.confirm("确定结束吗?", (e) => {
if (e.index == 0) {
}
});
};
bottom.innerHTML = [
"<div class='btn'><div class='back'></div></div>",
"<div class='ybtn off' onclick='off()'></div>",
].join('');
}
var zbtn = document.querySelector(".btn");
console.log('zbtn:', zbtn);
zbtn.addEventListener('touchstart', function(e) {
console.log('点击左摇杆');
this.startX = e.touches[0].clientX;
this.startY = e.touches[0].clientY;
})
zbtn.addEventListener('touchmove', function(e) {
this.endX = e.touches[0].clientX;
this.endY = e.touches[0].clientY;
var that = this;
console.log('that======:' + that);
//获取滑动距离
var distanceX = this.endX - this.startX;
var distanceY = this.endY - this.startY;
//判断滑动方向
if (Math.abs(distanceX) > Math.abs(distanceY) && distanceX > 0) {
console.log('往右滑动:' + distanceX);
that.callMethod("doOver");
} else if (Math.abs(distanceX) > Math.abs(distanceY) && distanceX < 0) {
console.log('往左滑动:' + distanceX);
} else if (Math.abs(distanceX) < Math.abs(distanceY) && distanceY < 0) {
console.log('往上滑动');
} else if (Math.abs(distanceX) < Math.abs(distanceY) && distanceY > 0) {
console.log('往下滑动');
}
})
zbtn.addEventListener('touchend', function() {
console.log('Swipe direction: ' + direction);
this.startX = 0;
this.startY = 0;
this.endX = 0;
this.endY = 0;
var back = document.querySelector(".back");
back.style.left = 40 + 'px';
back.style.top = 40 + 'px';
})
}
信息类型 | 信息 |
---|---|
开发环境 | 未提及 |
版本号 | 未提及 |
项目创建方式 | 未提及 |
1 回复
在 uni-app
中使用 renderjs
创建摇杆并监听滑动事件时,如果 this.$ownerInstance.callMethod
函数不起作用,可能是由于 renderjs
环境中对 Vue 实例的访问方式有所不同。在 renderjs
中,我们不能直接使用 Vue 实例的方法,因为 renderjs
运行在一个相对独立的环境中,用于提升性能并减少 DOM 操作对主线程的影响。
下面是一个使用 renderjs
创建摇杆并监听滑动事件的示例代码,同时展示如何在 renderjs
环境中调用页面逻辑。
页面代码 (pages/index/index.vue)
<template>
<view class="container">
<canvas canvas-id="joystickCanvas" style="width: 100px; height: 100px;"></canvas>
</view>
</template>
<script>
export default {
mounted() {
this.$nextTick(() => {
this.initJoystick();
});
},
methods: {
handleJoystickMove(data) {
console.log('Joystick moved:', data);
// 在这里处理摇杆移动的逻辑
},
initJoystick() {
const renderScript = `
const canvas = uni.createCanvasContext('joystickCanvas');
const joystick = { x: 50, y: 50 }; // 假设摇杆中心在画布中心
const radius = 40; // 摇杆半径
canvas.setStrokeStyle('#000');
canvas.setLineWidth(2);
canvas.drawCircle(50, 50, radius, false);
function onTouchMove(e) {
const touch = e.touches[0];
const rect = uni.getNodeInfo(canvas).boundingClientRect;
joystick.x = touch.x - rect.left;
joystick.y = touch.y - rect.top;
// 限制摇杆在画布内移动
if (joystick.x < 0) joystick.x = 0;
if (joystick.y < 0) joystick.y = 0;
if (joystick.x > rect.width) joystick.x = rect.width;
if (joystick.y > rect.height) joystick.y = rect.height;
// 更新画布
canvas.clearRect(0, 0, rect.width, rect.height);
canvas.drawCircle(50, 50, radius, false);
canvas.beginPath();
canvas.moveTo(50, 50);
canvas.lineTo(joystick.x, joystick.y);
canvas.setStrokeStyle('#FF0000');
canvas.stroke();
canvas.draw(true);
// 调用页面方法
const data = { x: joystick.x, y: joystick.y };
postMessage(data);
}
canvas.canvas.addEventListener('touchmove', onTouchMove);
`;
uni.createSelectorQuery().select('#joystickCanvas').fields({ node: true, size: true }).exec((res) => {
const context = res[0].node.getContext('renderjs', renderScript);
});
}
},
onUnload() {
// 页面卸载时移除事件监听器(示例中未直接实现,但应考虑)
}
};
</script>
解释
- Canvas 初始化:在
mounted
生命周期钩子中初始化摇杆。 - RenderJS 脚本:在
renderScript
中定义了摇杆的逻辑,包括绘制和触摸移动事件处理。 - 事件监听:使用
canvas.canvas.addEventListener('touchmove', onTouchMove)
监听触摸移动事件。 - 数据传递:通过
postMessage(data)
将摇杆位置数据发送回页面逻辑。
注意:在真实项目中,你可能需要更复杂的逻辑来处理摇杆边界、灵敏度等,并且需要确保在组件卸载时移除事件监听器以避免内存泄漏。