React+Taro h5 解决ios机型input无法自动聚焦的问题

1、原因

在ios12系统以上版本,苹果端考虑到用户的安全性和体验方面的因素,所以不支持input框的自动聚焦

2、方案

需要用户主动触发事件才可以使 focus生效

3、需求

首页顶部有个搜索框,点击进去搜索页,自动聚焦并弹起键盘

4、思路

首先封装一个搜索功能的组件,其次在全局app.js中引入,因为是在全局引入的,所以每个页面的顶部都会出现搜索框,这样就可以解决ios机型无法聚焦的问题。 然后我们通过EventEmitter来进行页面通信,来根据实际需求判断不同页面是否需要用搜索框,此方法不用**input.focus()**就可以解决无法聚焦的问题,下面我们来看看具体的解决方案:

(4.1)、步骤一

封装一个搜索功能组件

const SearchArea = (props) => {
    const {
        show = true,
        callback = () => {}
    } = props;

    const [curInputVal, setCurInputVal] = useState('');

    // 监听input值变化
    const handleInputValue = (val) => {
        setCurInputVal(val)
    }

    // 点击手机键盘搜索框触发的函数
    const handleFinishForm = () => {
        intoSearchResult()
    }

    // 跳往搜索结果
    const intoSearchResult = () => {
        if(!curInputVal.trim()) return;
        Taro.navigateTo({
            url: 'pages/searchResult/index' + `?searchVal=${curInputVal}`
        })
    }

    return (
        <View className='search-area' style={{display: show ? 'flex' : 'none'}}>
            <View className='header-center-search' onClick={() => { callback() }}>
                <Form action="." onFinish={handleFinishForm}> // 自动调起手机键盘,务必得有Form
                     <Input
                         type="search" 
                         value={curInputVal}
                         placeholder='请输入您想查找的商品' 
                         maxLength={100}
                         onChange={handleInputValue}
                     />
                 </Form>
            </View>
            <View 
                className='search-btn'
                onClick={() => {
                    intoSearchResult()
                }}
            >搜索</View>
        </View>
    )
}

export default SearchArea;
(4.2)、步骤二

在全局app.js中引入组件,并通过eventBus.on来接收每个页面派发的事件

constructor(props) {
    super(props)
    this.state = {
      headerInfo: {}
    }
}
componentDidMount() {
    eventBus.on('setHeaderSearchInfo', (res) => {
      this.setState({
        headerInfo: res
      });
    });
  }
render () {
    return (
      <Provider store={store}>
        <SearchArea {...this.state.headerInfo}></SearchArea>
        {this.props.children}
      </Provider>
    )
}
(4.3)、步骤三

在每个页面来通过eventBus.emit进行派发事件,来控制每个页面是否需要显示搜索框,这里的callback可以通过回调函数来告知页面,你在组件中做了什么事

// index 页面
useDidShow(() => {
    eventBus.emit('setHeaderSearchInfo', {
      show: true,
      isNoNeedVal: true,
      callback: () => {
        Taro.navigateTo({
          url: 'pages/search/index',
        })
      }
    });
})
5、温馨提示

如果在使用此方法中遇到修改不了根元素的样式,可以采用以下方法,如果有其他方法可以忽略

componentDidMount() {
    eventBus.on('setHeaderSearchInfo', (res) => {
      let id = getCurrentInstance().router.path;
      let element = document.getElementById(id);
      if(element) {
        if(res.show) {
          element.style.paddingTop = Taro.pxTransform(100)
        } else {
          element.style.paddingTop = Taro.pxTransform(0)
        }
      }
      this.setState({
        headerInfo: res
      });
    });
 }
6、售后服务

这个方法也不是唯一的,但是可以解决此问题,如果大家在运用过程中遇到什么问题,欢迎在下方评论区留言,或者私信我哦,定会帮您解答~

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值