Răsfoiți Sursa

fix: block unnecessary input event on textarea placeholder in IE

close #7138
Evan You 8 ani în urmă
părinte
comite
0f7c443dca

+ 18 - 2
src/platforms/web/runtime/modules/attrs.js

@@ -1,6 +1,6 @@
 /* @flow */
 
-import { isIE9, isEdge } from 'core/util/env'
+import { isIE, isIE9, isEdge } from 'core/util/env'
 
 import {
   extend,
@@ -44,7 +44,7 @@ function updateAttrs (oldVnode: VNodeWithData, vnode: VNodeWithData) {
   // #4391: in IE9, setting type can reset value for input[type=radio]
   // #6666: IE/Edge forces progress value down to 1 before setting a max
   /* istanbul ignore if */
-  if ((isIE9 || isEdge) && attrs.value !== oldAttrs.value) {
+  if ((isIE || isEdge) && attrs.value !== oldAttrs.value) {
     setAttr(elm, 'value', attrs.value)
   }
   for (key in oldAttrs) {
@@ -84,6 +84,22 @@ function setAttr (el: Element, key: string, value: any) {
     if (isFalsyAttrValue(value)) {
       el.removeAttribute(key)
     } else {
+      // #7138: IE10 & 11 fires input event when setting placeholder on
+      // <textarea>... block the first input event and remove the blocker
+      // immediately.
+      /* istanbul ignore if */
+      if (
+        isIE && !isIE9 &&
+        el.tagName === 'TEXTAREA' &&
+        key === 'placeholder' && !el.__ieph
+      ) {
+        const blocker = e => {
+          e.stopImmediatePropagation()
+          el.removeEventListener('input', blocker)
+        }
+        el.addEventListener('input', blocker)
+        el.__ieph = true /* IE placeholder patched */
+      }
       el.setAttribute(key, value)
     }
   }

+ 18 - 1
test/unit/features/directives/model-text.spec.js

@@ -1,5 +1,5 @@
 import Vue from 'vue'
-import { isIE9, isAndroid } from 'core/util/env'
+import { isIE9, isIE, isAndroid } from 'core/util/env'
 
 describe('Directive v-model text', () => {
   it('should update value both ways', done => {
@@ -412,4 +412,21 @@ describe('Directive v-model text', () => {
       }).then(done)
     })
   }
+
+  // #7138
+  if (isIE && !isIE9) {
+    it('should not fire input on initial render of textarea with placeholder in IE10/11', done => {
+      const el = document.createElement('div')
+      document.body.appendChild(el)
+      const vm = new Vue({
+        el,
+        data: { foo: null },
+        template: `<textarea v-model="foo" placeholder="bar"></textarea>`
+      })
+      setTimeout(() => {
+        expect(vm.foo).toBe(null)
+        done()
+      }, 17)
+    })
+  }
 })