field.js 2.9 KB
Newer Older
1 2 3 4 5 6 7
import {
  debounce,
  throttle
} from 'uni-shared'
import emitter from './emitter'
import keyboard from './keyboard'

8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
UniViewJSBridge.subscribe('getSelectedTextRange', function ({ pageId, callbackId }) {
  const activeElement = document.activeElement
  const tagName = activeElement.tagName.toLowerCase()
  const tagNames = ['input', 'textarea']
  const data = {}
  if (tagNames.includes(tagName)) {
    data.errMsg = 'getSelectedTextRange:ok'
    data.start = activeElement.selectionStart
    data.end = activeElement.selectionEnd
  } else {
    data.errMsg = 'getSelectedTextRange:fail:no focused'
  }
  UniViewJSBridge.publishHandler('onGetSelectedTextRange', {
    callbackId,
    data
  }, pageId)
})

26 27 28 29
// App 延迟获取焦点
const FOCUS_DELAY = 200
let startTime

30
export default {
Q
qiang 已提交
31
  name: 'Field',
32 33 34 35 36 37 38 39 40
  mixins: [emitter, keyboard],
  model: {
    prop: 'value',
    event: 'update:value'
  },
  props: {
    value: {
      type: [String, Number],
      default: ''
41 42 43 44 45 46 47 48 49 50 51
    },
    /**
     * 已废弃属性,用于历史兼容
     */
    autoFocus: {
      type: [Boolean, String],
      default: false
    },
    focus: {
      type: [Boolean, String],
      default: false
52 53 54 55 56 57 58
    }
  },
  data () {
    return {
      valueSync: this._getValueString(this.value)
    }
  },
59 60 61 62 63 64 65 66 67 68 69 70 71 72
  watch: {
    focus (val) {
      if (val) {
        this._focus()
      } else {
        this._blur()
      }
    }
  },
  computed: {
    needFocus () {
      return this.autoFocus || this.focus
    }
  },
73
  created () {
74
    const valueChange = this.__valueChange = debounce((val) => {
75 76 77 78
      this.valueSync = this._getValueString(val)
    }, 100)
    this.$watch('value', valueChange)
    this.__triggerInput = throttle(($event, detail) => {
79
      this.$emit('update:value', detail.value)
80 81 82 83 84 85 86 87 88 89 90 91 92 93
      this.$trigger('input', $event, detail)
    }, 100)
    this.$triggerInput = ($event, detail) => {
      this.__valueChange.cancel()
      this.__triggerInput($event, detail)
    }
  },
  beforeDestroy () {
    this.__valueChange.cancel()
    this.__triggerInput.cancel()
  },
  methods: {
    _getValueString (value) {
      return value === null ? '' : String(value)
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
    },
    _initField (ref) {
      this._fieldRef = ref
      startTime = startTime || Date.now()
      if (this.needFocus) {
        this._focus()
      }
    },
    _focus () {
      if (!this.needFocus) {
        return
      }
      const field = this.$refs[this._fieldRef]
      if (!field || (__PLATFORM__ === 'app-plus' && !window.plus)) {
        setTimeout(this._focus.bind(this), 100)
        return
      }
      if (__PLATFORM__ === 'h5') {
        field.focus()
      } else {
        const timeout = FOCUS_DELAY - (Date.now() - startTime)
        if (timeout > 0) {
          setTimeout(this._focus.bind(this), timeout)
          return
        }
        field.focus()
        plus.key.showSoftKeybord()
      }
    },
    _blur () {
      const field = this.$refs[this._fieldRef]
      field && field.blur()
126 127 128
    }
  }
}