input输入框事件流程变化

从聚焦到失去焦点,以下事件会根据情况,先后判断是否会执行。

onfocus -> 键盘输入 -> onkeydown -> onkeypress -> onkeyup -> oninput -> 失去焦点 -> onchange -> onblur

onfocus 聚焦事件

无论是用户主动的聚焦行为还是代码的强制聚焦,只要是由失去焦点的状态变为聚焦的状态都会触发这一事件。

<template>
  <div class="hello">
   <input type="text" @focus="onfocus" ref="input1">
   <button @click="focusbtn"> foucs </button>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  methods: {
    onfocus () {
      console.log('聚焦执行')
    },
    focusbtn () {
      // 代码控制聚焦
      this.$refs.input1.focus()
    }
  }
}
</script>

如果本身就是聚焦状态,多次执行聚焦则不会执行

<template>
  <div class="hello">
   <input type="text" @focus="onfoucs" ref="input1">
   <button @click="foucsbtn"> foucs </button>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  methods: {
    onfoucs () {
      console.log('聚焦执行')
    },
    foucsbtn () {
      // 代码控制聚焦,onfoucs只会执行一次
      this.$refs.input1.focus()
      this.$refs.input1.focus()
      this.$refs.input1.focus()
    }
  }
}
</script>
<template>
  <div class="hello">
   <input type="text" @focus="onfoucs" ref="input1">
   <button @click="foucsbtn"> foucs </button>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  methods: {
    onfoucs () {
      console.log('聚焦执行')
    },
    foucsbtn () {
      // 代码控制聚焦
      this.$refs.input1.focus()
      this.$refs.input1.blur()
      // 失去焦点后再聚焦,onfoucs则会再执行一次
      this.$refs.input1.focus()
    }
  }
}
</script>

这也又一次应证了,只有从失去焦点状态变为聚焦,@focus才会执行。

onkeydown 键盘按键按下事件

每一个键的触发都有三个步骤 按下keydown,按住press,抬起keyup,如果有按键输入,keydown会率先触发

<template>
  <div class="hello">
   <input type="text" @keydown="keydown" @keypress="keypress" @keyup="keyup">
   <button @click="foucsbtn"> foucs </button>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  methods: {
    keydown () {
      console.log('按下')
    },
    keypress () {
      console.log('按住')
    },
    keyup () {
      console.log('抬起')
    }
  }
}
</script>

效果
input输入框事件流程变化_第1张图片
但是,如果一直按住按键不松手,keydown也会一直执行

效果
input输入框事件流程变化_第2张图片

onkeypress 键盘按键按住事件

每一个键的触发都有三个步骤 按下keydown,按住press,抬起keyup,如果有按键输入,keydown触发后,只要不松开按键,onkeypress 会和onkeydown一起一直触发
input输入框事件流程变化_第3张图片

onkeyup 键盘按键松开事件

每一个键的触发都有三个步骤 按下keydown,按住press,抬起keyup,如果有按键输入,松开按键的一瞬间会触发一次onkeyup事件,一般来说,keydown和keyup选择一个使用就可以了

oninput 输入值变化事件

当input输入框的值发生变化时,就会触发,一般用户输入内容,会变化很多次,如果不做防抖处理,oninput的事件会执行很多次

<template>
  <div class="hello">
   <input type="text" @input="onInput" @keydown.enter="onEnter">
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  methods: {
    onEnter () {
      console.log('按下enter')
    },
    onInput () {
      console.log('改变了')
    }
  }
}
</script>

input输入框事件流程变化_第4张图片
按下回车键这个行为不会触发oninput事件
input输入框事件流程变化_第5张图片

onchange 失去焦点后的输入值变化事件

当用户输入完成后,无论是按了一下回车键,还是点击了其它地方,或者代码控制失去焦点,都有可能触发onchange 事件。是否触发的另外一个条件就是,与上一次失去焦点的值相比,此时input框内的值是否发生变化,如果变化了,则触发onchange,没有变化则不触发

<template>
  <div class="hello">
   <input type="text" @change="onchange">
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  methods: {
    onchange () {
      console.log('改变了')
    }
  }
}
</script>

input输入框事件流程变化_第6张图片

这里涉及到开发中常用的另外一个问题,当用户敲击回车键后,onchange事件仍有可能触发。如果input框同时绑定了onchange事件,也绑定了对回车键的监听,如果在按下回车键前,input框的值发生变化,这两个事件一定都会触发。

<template>
  <div class="hello">
   <input type="text" @change="onchange" @keydown.enter="onEnter">
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  methods: {
    onEnter () {
      console.log('按下enter')
    },
    onchange () {
      console.log('改变了')
    }
  }
}
</script>

按下enter键虽然没有失去焦点,但也有可能会触发onchange事件
input输入框事件流程变化_第7张图片

如果开发希望将这两个事件同时绑定,又从功能上要求完全分开,就需要input输入框的值是否发生变化,如果没有发生变化,只会执行回车事件,如果发生了变化,则阻止回车事件,因为onChange会执行

<template>
  <div class="hello">
   <input type="text" @change="onchange" @keydown.enter="onEnter">
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  data () {
    return {
      initValue: ''
    }
  },
  methods: {
    onEnter (e) {
      const val = e.target.value
      if (val === this.initValue) {
        // 表示onChange不会执行,所以得执行
        console.log('按下enter')
      }
    },
    onchange (e) {
      this.initValue = e.target.value
      console.log('改变了')
    }
  }
}
</script>

输入后第一次按下回车,onenter虽然会触发,但我们的不想要执行的console.log并没有执行。
input输入框事件流程变化_第8张图片
再次多次点击回车,不会再执行onchange,因为值没有变化
input输入框事件流程变化_第9张图片

再次说明,失去焦点后,会先判断onchange是否执行,再执行onblur

<template>
  <div class="hello">
   <input type="text" @change="onchange" @keydown.enter="onEnter" @blur="onblur">
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  data () {
    return {
      initValue: ''
    }
  },
  methods: {
    onEnter (e) {
      const val = e.target.value
      if (val === this.initValue) {
        // 表示onChange不会执行,所以得执行
        console.log('按下enter')
      }
    },
    onchange (e) {
      this.initValue = e.target.value
      console.log('改变了')
    },
    onblur () {
      console.log('失去焦点了')
    }
  }
}
</script>

input输入框事件流程变化_第10张图片

onblur 失去焦点事件

当用户输入完成后,无论点击了其它地方,或者代码控制失去焦点,只要有聚焦到失去焦点这一变化,就一定会触发onblur,如果原本就是失去焦点状态,再次失去焦点,onblur事件不会再触发。

<template>
  <div class="hello">
   <input type="text" @change="onchange" @blur="onblur" ref="input1">
   <button @click="clickBtn">失去焦点</button>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  data () {
    return {
      initValue: ''
    }
  },
  methods: {
    clickBtn (e) {
      this.$refs.input1.blur()
      this.$refs.input1.blur()
      this.$refs.input1.blur()
    },
    onblur () {
      console.log('失去焦点了')
    }
  }
}
</script>

无论怎么点击按钮都不会触发
input输入框事件流程变化_第11张图片

<template>
  <div class="hello">
   <input type="text" @change="onchange" @blur="onblur" ref="input1">
   <button @click="clickBtn">失去焦点</button>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  data () {
    return {
      initValue: ''
    }
  },
  methods: {
    clickBtn (e) {
      this.$refs.input1.blur()
      this.$refs.input1.blur()
      // 如果聚焦后再失去焦点,则会触发一次onblur
      this.$refs.input1.focus()
      this.$refs.input1.blur()
    },
    onblur () {
      console.log('失去焦点了')
    }
  }
}
</script>

点击一次按钮
input输入框事件流程变化_第12张图片

但是,按下回车,并不会失去焦点,onblur不会触发

<template>
  <div class="hello">
   <input type="text" @change="onchange" @keydown.enter="onEnter" @blur="onblur">
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  data () {
    return {
      initValue: ''
    }
  },
  methods: {
    onEnter (e) {
        console.log('按下enter')
    },
    onblur () {
      console.log('失去焦点了')
    }
  }
}
</script>

input输入框事件流程变化_第13张图片

说明,vue的input输入框事件是从原生的input输入框封装而来的,所以对于原生html input输入框事件,与上述说明一致。

你可能感兴趣的:(vue,前端必备知识,javascript,前端,html5)