dom.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. var config = require('../config')
  2. /**
  3. * Check if a node is in the document.
  4. * Note: document.documentElement.contains should work here
  5. * but always returns false for comment nodes in phantomjs,
  6. * making unit tests difficult. This is fixed byy doing the
  7. * contains() check on the node's parentNode instead of
  8. * the node itself.
  9. *
  10. * @param {Node} node
  11. * @return {Boolean}
  12. */
  13. exports.inDoc = function (node) {
  14. var doc = document.documentElement
  15. var parent = node && node.parentNode
  16. return doc === node ||
  17. doc === parent ||
  18. !!(parent && parent.nodeType === 1 && (doc.contains(parent)))
  19. }
  20. /**
  21. * Extract an attribute from a node.
  22. *
  23. * @param {Node} node
  24. * @param {String} attr
  25. */
  26. exports.attr = function (node, attr) {
  27. attr = config.prefix + attr
  28. var val = node.getAttribute(attr)
  29. if (val !== null) {
  30. node.removeAttribute(attr)
  31. }
  32. return val
  33. }
  34. /**
  35. * Insert el before target
  36. *
  37. * @param {Element} el
  38. * @param {Element} target
  39. */
  40. exports.before = function (el, target) {
  41. target.parentNode.insertBefore(el, target)
  42. }
  43. /**
  44. * Insert el after target
  45. *
  46. * @param {Element} el
  47. * @param {Element} target
  48. */
  49. exports.after = function (el, target) {
  50. if (target.nextSibling) {
  51. exports.before(el, target.nextSibling)
  52. } else {
  53. target.parentNode.appendChild(el)
  54. }
  55. }
  56. /**
  57. * Remove el from DOM
  58. *
  59. * @param {Element} el
  60. */
  61. exports.remove = function (el) {
  62. el.parentNode.removeChild(el)
  63. }
  64. /**
  65. * Prepend el to target
  66. *
  67. * @param {Element} el
  68. * @param {Element} target
  69. */
  70. exports.prepend = function (el, target) {
  71. if (target.firstChild) {
  72. exports.before(el, target.firstChild)
  73. } else {
  74. target.appendChild(el)
  75. }
  76. }
  77. /**
  78. * Replace target with el
  79. *
  80. * @param {Element} target
  81. * @param {Element} el
  82. */
  83. exports.replace = function (target, el) {
  84. var parent = target.parentNode
  85. if (parent) {
  86. parent.replaceChild(el, target)
  87. }
  88. }
  89. /**
  90. * Add event listener shorthand.
  91. *
  92. * @param {Element} el
  93. * @param {String} event
  94. * @param {Function} cb
  95. */
  96. exports.on = function (el, event, cb) {
  97. el.addEventListener(event, cb)
  98. }
  99. /**
  100. * Remove event listener shorthand.
  101. *
  102. * @param {Element} el
  103. * @param {String} event
  104. * @param {Function} cb
  105. */
  106. exports.off = function (el, event, cb) {
  107. el.removeEventListener(event, cb)
  108. }
  109. /**
  110. * Add class with compatibility for IE & SVG
  111. *
  112. * @param {Element} el
  113. * @param {Strong} cls
  114. */
  115. exports.addClass = function (el, cls) {
  116. if (el.classList) {
  117. el.classList.add(cls)
  118. } else {
  119. var cur = ' ' + (el.getAttribute('class') || '') + ' '
  120. if (cur.indexOf(' ' + cls + ' ') < 0) {
  121. el.setAttribute('class', (cur + cls).trim())
  122. }
  123. }
  124. }
  125. /**
  126. * Remove class with compatibility for IE & SVG
  127. *
  128. * @param {Element} el
  129. * @param {Strong} cls
  130. */
  131. exports.removeClass = function (el, cls) {
  132. if (el.classList) {
  133. el.classList.remove(cls)
  134. } else {
  135. var cur = ' ' + (el.getAttribute('class') || '') + ' '
  136. var tar = ' ' + cls + ' '
  137. while (cur.indexOf(tar) >= 0) {
  138. cur = cur.replace(tar, ' ')
  139. }
  140. el.setAttribute('class', cur.trim())
  141. }
  142. }
  143. /**
  144. * Extract raw content inside an element into a temporary
  145. * container div
  146. *
  147. * @param {Element} el
  148. * @param {Boolean} asFragment
  149. * @return {Element}
  150. */
  151. exports.extractContent = function (el, asFragment) {
  152. var child
  153. var rawContent
  154. /* istanbul ignore if */
  155. if (
  156. exports.isTemplate(el) &&
  157. el.content instanceof DocumentFragment
  158. ) {
  159. el = el.content
  160. }
  161. if (el.hasChildNodes()) {
  162. rawContent = asFragment
  163. ? document.createDocumentFragment()
  164. : document.createElement('div')
  165. /* jshint boss:true */
  166. while (child = el.firstChild) {
  167. rawContent.appendChild(child)
  168. }
  169. }
  170. return rawContent
  171. }
  172. /**
  173. * Check if an element is a template tag.
  174. * Note if the template appears inside an SVG its tagName
  175. * will be in lowercase.
  176. *
  177. * @param {Element} el
  178. */
  179. exports.isTemplate = function (el) {
  180. return el.tagName &&
  181. el.tagName.toLowerCase() === 'template'
  182. }