当前位置 : 主页 > 网页制作 > React >

在反应本机webview中为触摸事件创建一个漏洞

来源:互联网 收集:自由互联 发布时间:2021-06-15
我们正在尝试重复与此插件相同的事情: https://github.com/mapsplugin/cordova-plugin-googlemaps/blob/master/README.md(此插件如何工作)但使用react-native mapbox gl(native). 这个想法很简单:webview和mapview是“
我们正在尝试重复与此插件相同的事情: https://github.com/mapsplugin/cordova-plugin-googlemaps/blob/master/README.md(此插件如何工作)但使用react-native mapbox gl(native).

这个想法很简单:webview和mapview是“兄弟姐妹”,webview在mapview之上,webview的一部分是透明的,mapview在它下面显示.我们希望在此透明区域中发生的任何触摸事件都不会被webview和bubble /捕获到mapview,因此您可以触摸/拖动/缩放地图.

简单地说:我们希望webview的部分(不是全部)不捕获事件,而是允许底层视图捕获它们.

看起来反应原生中有一些方法允许这样做(有条件地控制事件捕获)(https://facebook.github.io/react-native/docs/view.html#onstartshouldsetrespondercapture)但是我们找不到任何工作示例来测试它,我们无法完全理解提供的文档(我们可以如果为父视图或子视图指定了这个回调,我甚至不会理解.

所以基本上我们只需要一些反应原生的仪器来有条件地捕获触摸事件.

任何人都可以帮助我们吗? map / webview的示例可能过于复杂,在两个视图中对事件的任何条件捕获都应该有很大帮助.

我不确定这是否是完美的解决方案,但您可以做的是创建一个EvenEmitter并让Webview捕获所有点击.应该由Map处理的那些,我可以发送到地图本身.

我在屏幕上使用它们,可能会创建多个组件,但它们可以发送到父屏幕.它主要用于处理模态屏幕.

import EventEmitter from 'react-native/Libraries/vendor/emitter/EventEmitter';

this._eventEmitter = new EventEmitter();

        this._eventEmitter.addListener('modal', (data) => {
            this.setState({
                visibleModal: true,
                modalData: data
            });
        });

然后你可以使用它们像emitter.emit(“模态”,数据)

编辑:

这是另一种方法,它还向您展示了如何使用您在问题中提出的方法.

class Class extends Component {

    onStartShouldSetResponder = () => true;
    onEvent = (e) => {
        let object = {};
        object.locationX = e.nativeEvent.locationX;
        object.locationY = e.nativeEvent.locationY;
        object.pageY = e.nativeEvent.pageY;
        object.pageX = e.nativeEvent.pageX;
        object.target = e.nativeEvent.target;
        //object.touches = e.nativeEvent.touches; //These will trigger a cyclic error while parsing but you can access them
        //object.changedTouches = e.nativeEvent.changedTouches;
        object.identifier = e.nativeEvent.identifier;
        alert(JSON.stringify(object));

        if (object.pageX > this.state.x && object.pageX < (this.state.x + this.state.width) && object.pageY > this.state.y && object.pageY < (this.state.y + this.state.height))
            alert("inside") //Here you can trigger whatever function you need from the underlying view
    }

    onLayout = (event) => {
        this.setState({
            x: event.nativeEvent.layout.x,
            y: event.nativeEvent.layout.y,
            width: event.nativeEvent.layout.width,
            height: event.nativeEvent.layout.height,
        });
    }

    render(){

        return(    

            <ScrollView>

            <View ref={"target"} style={{
                position: 'absolute',
                height: 200,
                width: 200,
                left: 100,
                top: 100,
                backgroundColor: 'rgba(0,0,0,0.5)'
            }}
            onLayout={this.onLayout}
            />

            <View 
            onl
            onStartShouldSetResponder={this.onStartShouldSetResponder} 
            onResponderMove={this.onEvent}
            style={{
                backgroundColor: 'rgba(255,0,0,0.3)',
                width: '100%',
                height: 150
            }}/>

            <TouchableWithoutFeedback 
            onPress={this.onEvent}
            onLongPress={this.onEvent}
            style={{
                backgroundColor: 'rgba(0,255,0,0.3)',
                width: '100%',
                height: 150
            }}> 
            <View style={{height: 150, backgroundColor: 'rgba(0,255,0,0.3)'}}/>
            </TouchableWithoutFeedback>

            <View 
            onTouchStart={this.onEvent}
            onTouchEnd={this.onEvent}
            style={{
                backgroundColor: 'rgba(0,0,255,0.3)',
                width: '100%',
                height: 150
            }}> 
            </View>

            </ScrollView>

        );
    }

}

也许这会帮助您将事件传递给其他视图

网友评论