I haven’t written for a long time because I am lazy recently. Ha ha ha company has encountered some pits in taroui3 development project recently

First, enter the box enter function

The business scenario

As shown in the figure above, you need to search after entering the contents such as the tracking number

The solution

Since there is no reset button, it is necessary to use the return function of the pop-up box. Since the TARO UI framework is used, the taro-UI document has not found any return event after browsing the document, so we plan to listen for the key event of the page and judge according to the corresponding identifier after testing, there is no relevant identifier in onKeyDown Onkeyup is available so use the onkeyUp event:

componentDidMount(){...//h5: There is no carriage return event so listen keyup keydown is invalid
    window.addEventListener('keyup'.this.handleSubmit)
}
componentWillUnmount() {
    window.removeEventListener('keyup'.this.handleSubmit)
}
handleSubmit = (e) = > {
    console.log('e', e)
    if (e.code === 'Enter' && this.props.onInputConfirm) {
      this.props.onInputConfirm({ isResetList: true}}})Copy the code

Android is having problems

There is no problem on the developer tool and the real iPhone, and then the problem is found on the Android phone. After testing, the code of the Android phone is empty, so the judgment is increased

handleSubmit = (e) = > {
    console.log('e', e)
    // Apple enter which=13 finish =55/88
    if ((e.code === 'Enter' || e.key === 'Enter' || e.which === 13 || e.which===55 ||e.which===88) && this.props.onInputConfirm) {
      this.props.onInputConfirm({ isResetList: true}}})Copy the code

2. Screening date function

The business scenario

Date filtering is required as shown above

Post a method to calculate the timestamp of the last N days

// Calculate the start timestamp of different time intervals
export function calculateTimestamp(type) {
  let timeArr = []
  switch (type) {
    case 'today':
      timeArr = [getTimetampFrom(`${getDay(0)}00:00:00 `), getTimetampFrom()]
      break
    case 'yesterday':
      timeArr = [
        getTimetampFrom(`${getDay(-1)}00:00:00 `),
        getTimetampFrom(`${getDay(0)}00:00:00 `)]break
    case 'recently7':
      timeArr = [getTimetampFrom(`${getDay(-7)}00:00:00 `), getTimetampFrom()]
      break
    case 'recently30':
      timeArr = [getTimetampFrom(`${getDay(-30)}00:00:00 `), getTimetampFrom()]
      break
    default:
      timeArr = []
      break
  }
  // Return the corresponding value with the backend
  return timeArr.map((time) = > time / 1000)}function getDay(day) {
  var today = new Date(a)var targetday_milliseconds = today.getTime() + 1000 * 60 * 60 * 24 * day

  today.setTime(targetday_milliseconds) // Note that this line is critical code

  var tYear = today.getFullYear()

  var tMonth = today.getMonth()

  var tDate = today.getDate()

  tMonth = doHandleMonth(tMonth + 1)

  tDate = doHandleMonth(tDate)

  return tYear + The '-' + tMonth + The '-' + tDate
}

function doHandleMonth(month) {
  var m = month
  if (month.toString().length == 1) {
    m = '0' + month
  }

  return m
}

// Get the timestamp
function getTimetampFrom(day) { 

  if(! day) {return new Date().getTime()
  } 
 
  return new Date(day).getTime()
}
Copy the code

There is a problem in IOS

All of a sudden, a test boy said to me, “Hey boy, your screening time is not working.” I thought, “How could it be that it didn’t work before, but it worked on my Android phone? The input parameter of Date cannot be xxxx-xx-xx, which will be resolved to NaN and must be XXXX /xx/xx

// Add judgment ios
function isIos() {
  let u = navigator.userAgent
  let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1
  letisiOS = !! u.match(/\(i[^;] +; ( U;) ? CPU.+Mac OS X/) / / ios terminal
  return isiOS
}

import { isIos } from './index'

// Get the timestamp
function getTimetampFrom(day) { 

  if(! day) {return new Date().getTime()
  }

  if (isIos()) {
    //IOS is not compatible with new Date()
    day = day.replace(/\-/g.'/')}return new Date(day).getTime()
}
Copy the code

3. Picker component Scroll penetration exists in IOS

The business scenario

As shown above, express delivery is required

IOS is having problems

And the test guy said, “HEY, I found a little bug in this. You’re rolling up there and I look like this. And then I found this problem with everything using the AtFloatLayout component

1.touchmove+event.preventDefault()

But that’s what I did and it didn’t work

export function stopPropagation(event) {
  event.stopPropagation()
}

export function preventDefault(event, isStopPropagation) {
  console.log('preventDefault', event)

  /* istanbul ignore else */
  if (typeofevent.cancelable ! = ='boolean' || event.cancelable) {
    console.log('preventDefault2', event)
    event.preventDefault()
  }

  if (isStopPropagation) {
    stopPropagation(event)
  }
} 


const handleTouchMove = (event) = > {
    move(event)

    if (isVertical()) {
      console.log('isVertical()')

      moving.current = true
      preventDefault(event, true)}let rangeOffset = range(startOffset.current + deltaY, -(count() * itemHeight), itemHeight)

    setOffset(rangeOffset)

    const now = Date.now()

    if(now - touchStartTime.current > MOMENTUM_LIMIT_TIME) { touchStartTime.current = now momentumOffset.current = rangeOffset }}Copy the code

2. Set body overflow to Hidden

Turns out, it worked perfectly

useEffect(() = > {
    if (visible) {
      window.document.body.style.overflow = 'hidden'
    } else {
      window.document.body.style.overflow = 'auto'= > {} ()window.document.body.style.overflow = 'auto'
    }
}, [visible])
Copy the code

4, the bottom absolute position is on the top

The business scenario

As shown in the figure above, the mobile phone number needs to be bound

Android is having problems

This problem does not exist because the test driver is IOS system. The product told me that the treasure collapsed. My heart was trembling and I said that the logo was on the top

To envision

First of all, the height of the page is set to absolute and the height of the view is set to absolute bottom at 40px. Is this because Android considers the height to be the part in the middle that is not covered by the keyboard when the keyboard is up

The solution

The logo will be hidden when the keyboard is up and then displayed when the logo is blur


handleFocus = () = > {
    console.log('handleFocus')
    this.setState({
      showLogo: false
    })
}

handleBlur = () = > {
    console.log('handleBlur')
    this.setState({
      showLogo: true
    })
}

{showLogo && (
          <View className='auth-ft'>
            <Image className='logo' mode='widthFix' src={LOGO} />
          </View>
 )}
Copy the code

Hope for a better solution

Although this method can be regarded as a solution to the problem, it is not very good. For me, I cannot pass the threshold in my mind. However, when the product says OK, I think it is OK hahaha

5, mobile phone camera function

The business scenario

You need to take a picture and upload your profile picture

IOS is having problems

Why does IOS not respond when uploading photos? Then I tested it on IOS and sure enough, it worked

Continuously debug

After my constant debugging (console.log), I found the probable cause of the qiniu-js library and reported such an error

English gray often good I saw the error reason “FileSizeLimit” this is not the file size is too large? I thought to myself, is the quality of the images on ios just too good? However, I have tried to upload 100 MB pictures perfectly on the computer. I have opened github of Qiniu-js and set a parameter retryCount=10, which indicates the retry times of uploading failures. But it still didn’t work, so I tried the pre-upload compression code on the official website to see if it worked

 qiNiuInit(tokenRes) {
    this.client.upload = (flie, key) = > { 
      const config = {
        retryCount: 10
      } 
      const options = {
        quality: 0.1.noCompressIfLarger: true
      }
      return new Promise((resolve, reject) = > {
        QiNiu.compressImage(flie, options).then((data) = > {
          console.log('data', data)
          const observable = QiNiu.upload(data.dist, key, tokenRes.token, {}, config)
          // const subscription = Observable. subscribe(observer) // Upload begins
          observable.subscribe({
            next: (res) = > {
              console.log('next', res, res? .uploadInfo, res? .chunks, res? .total) },error: (err) = > reject(err),
            complete: (res) = > resolve(res)
          })
        })
      }) 
    }
  }
Copy the code