Browse Source

fix IE+SVG no classList available error. Based on #537 by @tyage

Evan You 11 years ago
parent
commit
68b1a00ab3
4 changed files with 44 additions and 50 deletions
  1. 2 29
      src/directives/class.js
  2. 11 11
      src/transition/css.js
  3. 18 10
      src/util/dom.js
  4. 13 0
      test/unit/specs/util/dom_spec.js

+ 2 - 29
src/directives/class.js

@@ -1,33 +1,6 @@
 var _ = require('../util')
-var hasClassList =
-  typeof document !== 'undefined' &&
-  'classList' in document.documentElement
-
-/**
- * add class for IE9
- *
- * @param {Element} el
- * @param {Strong} cls
- */
-
-var addClass = hasClassList
-  ? function (el, cls) {
-      el.classList.add(cls)
-    }
-  : _.addClass
-
-/**
- * remove class for IE9
- *
- * @param {Element} el
- * @param {Strong} cls
- */
-
-var removeClass = hasClassList
-  ? function (el, cls) {
-      el.classList.remove(cls)
-    }
-  : _.removeClass
+var addClass = _.addClass
+var removeClass = _.removeClass
 
 module.exports = function (value) {
   if (this.arg) {

+ 11 - 11
src/transition/css.js

@@ -1,4 +1,6 @@
 var _ = require('../util')
+var addClass = _.addClass
+var removeClass = _.removeClass
 var transDurationProp = _.transitionProp + 'Duration'
 var animDurationProp = _.animationProp + 'Duration'
 
@@ -53,7 +55,6 @@ function flush () {
 function run (job) {
 
   var el = job.el
-  var classList = el.classList
   var data = el.__v_trans
   var cls = job.cls
   var cb = job.cb
@@ -63,7 +64,7 @@ function run (job) {
   if (job.dir > 0) { // ENTER
     if (transitionType === 1) {
       // trigger transition by removing enter class
-      classList.remove(cls)
+      removeClass(el, cls)
       // only need to listen for transitionend if there's
       // a user callback
       if (cb) setupTransitionCb(_.transitionEndEvent)
@@ -71,11 +72,11 @@ function run (job) {
       // animations are triggered when class is added
       // so we just listen for animationend to remove it.
       setupTransitionCb(_.animationEndEvent, function () {
-        classList.remove(cls)
+        removeClass(el, cls)
       })
     } else {
       // no transition applicable
-      classList.remove(cls)
+      removeClass(el, cls)
       if (cb) cb()
     }
   } else { // LEAVE
@@ -87,11 +88,11 @@ function run (job) {
         : _.animationEndEvent
       setupTransitionCb(event, function () {
         op()
-        classList.remove(cls)
+        removeClass(el, cls)
       })
     } else {
       op()
-      classList.remove(cls)
+      removeClass(el, cls)
       if (cb) cb()
     }
   }
@@ -167,23 +168,22 @@ function getTransitionType (el, data, className) {
  */
 
 module.exports = function (el, direction, op, data, cb) {
-  var classList = el.classList
   var prefix = data.id || 'v'
   var enterClass = prefix + '-enter'
   var leaveClass = prefix + '-leave'
   // clean up potential previous unfinished transition
   if (data.callback) {
     _.off(el, data.event, data.callback)
-    classList.remove(enterClass)
-    classList.remove(leaveClass)
+    removeClass(el, enterClass)
+    removeClass(el, leaveClass)
     data.event = data.callback = null
   }
   if (direction > 0) { // enter
-    classList.add(enterClass)
+    addClass(el, enterClass)
     op()
     push(el, direction, null, enterClass, cb)
   } else { // leave
-    classList.add(leaveClass)
+    addClass(el, leaveClass)
     push(el, direction, op, leaveClass, cb)
   }
 }

+ 18 - 10
src/util/dom.js

@@ -138,31 +138,39 @@ exports.off = function (el, event, cb) {
 }
 
 /**
- * Compatibility add class for IE9
+ * Add class with compatibility for IE & SVG
  *
  * @param {Element} el
  * @param {Strong} cls
  */
 
 exports.addClass = function (el, cls) {
-  var cur = ' ' + el.className + ' '
-  if (cur.indexOf(' ' + cls + ' ') < 0) {
-    el.className = (cur + cls).trim()
+  if (el.classList) {
+    el.classList.add(cls)
+  } else {
+    var cur = ' ' + (el.getAttribute('class') || '') + ' '
+    if (cur.indexOf(' ' + cls + ' ') < 0) {
+      el.setAttribute('class', (cur + cls).trim())
+    }
   }
 }
 
 /**
- * Compatibility remove class for IE9
+ * Remove class with compatibility for IE & SVG
  *
  * @param {Element} el
  * @param {Strong} cls
  */
 
 exports.removeClass = function (el, cls) {
-  var cur = ' ' + el.className + ' '
-  var tar = ' ' + cls + ' '
-  while (cur.indexOf(tar) >= 0) {
-    cur = cur.replace(tar, ' ')
+  if (el.classList) {
+    el.classList.remove(cls)
+  } else {
+    var cur = ' ' + (el.getAttribute('class') || '') + ' '
+    var tar = ' ' + cls + ' '
+    while (cur.indexOf(tar) >= 0) {
+      cur = cur.replace(tar, ' ')
+    }
+    el.setAttribute('class', cur.trim())
   }
-  el.className = cur.trim()
 }

+ 13 - 0
test/unit/specs/util/dom_spec.js

@@ -114,5 +114,18 @@ if (_.inBrowser) {
       _.addClass(el, 'bb')
       expect(el.className).toBe('cc bb')
     })
+
+    it('addClass/removeClass for SVG/IE9', function () {
+      var el = document.createElementNS('http://www.w3.org/2000/svg', 'circle')
+      el.setAttribute('class', 'aa bb cc')
+      _.removeClass(el, 'bb')
+      expect(el.getAttribute('class')).toBe('aa cc')
+      _.removeClass(el, 'aa')
+      expect(el.getAttribute('class')).toBe('cc')
+      _.addClass(el, 'bb')
+      expect(el.getAttribute('class')).toBe('cc bb')
+      _.addClass(el, 'bb')
+      expect(el.getAttribute('class')).toBe('cc bb')
+    })
   })
 }