This repository has been archived on 2023-08-29. You can view files and clone it, but cannot push or open issues/pull-requests.
yutent
/
anot.js
Archived
1
0
Fork 0
anot.js/src/04-dom.patch.js

157 lines
4.4 KiB
JavaScript
Raw Normal View History

2018-08-04 16:26:50 +08:00
/*********************************************************************
* DOM 底层补丁 *
**********************************************************************/
//safari5+是把contains方法放在Element.prototype上而不是Node.prototype
if (!DOC.contains) {
Node.prototype.contains = function(arg) {
return !!(this.compareDocumentPosition(arg) & 16)
}
}
Anot.contains = function(root, el) {
try {
while ((el = el.parentNode)) if (el === root) return true
return false
} catch (e) {
return false
}
}
if (window.SVGElement) {
var svgns = 'http://www.w3.org/2000/svg'
var svg = DOC.createElementNS(svgns, 'svg')
svg.innerHTML = '<circle cx="50" cy="50" r="40" fill="red" />'
if (!rsvg.test(svg.firstChild)) {
// #409
/* jshint ignore:start */
function enumerateNode(node, targetNode) {
if (node && node.childNodes) {
var nodes = node.childNodes
for (var i = 0, el; (el = nodes[i++]); ) {
if (el.tagName) {
var svg = DOC.createElementNS(svgns, el.tagName.toLowerCase())
// copy attrs
ap.forEach.call(el.attributes, function(attr) {
svg.setAttribute(attr.name, attr.value)
})
// 递归处理子节点
enumerateNode(el, svg)
targetNode.appendChild(svg)
}
}
}
}
/* jshint ignore:end */
Object.defineProperties(SVGElement.prototype, {
outerHTML: {
//IE9-11,firefox不支持SVG元素的innerHTML,outerHTML属性
enumerable: true,
configurable: true,
get: function() {
return new XMLSerializer().serializeToString(this)
},
set: function(html) {
var tagName = this.tagName.toLowerCase(),
par = this.parentNode,
frag = Anot.parseHTML(html)
// 操作的svg直接插入
if (tagName === 'svg') {
par.insertBefore(frag, this)
// svg节点的子节点类似
} else {
var newFrag = DOC.createDocumentFragment()
enumerateNode(frag, newFrag)
par.insertBefore(newFrag, this)
}
par.removeChild(this)
}
},
innerHTML: {
enumerable: true,
configurable: true,
get: function() {
var s = this.outerHTML
var ropen = new RegExp(
'<' + this.nodeName + '\\b(?:(["\'])[^"]*?(\\1)|[^>])*>',
'i'
)
var rclose = new RegExp('</' + this.nodeName + '>$', 'i')
return s.replace(ropen, '').replace(rclose, '')
},
set: function(html) {
if (Anot.clearHTML) {
Anot.clearHTML(this)
var frag = Anot.parseHTML(html)
enumerateNode(frag, this)
}
}
}
})
}
}
//========================= event binding ====================
var eventHooks = Anot.eventHooks
//针对firefox, chrome修正mouseenter, mouseleave(chrome30+)
if (!('onmouseenter' in root)) {
Anot.each(
{
mouseenter: 'mouseover',
mouseleave: 'mouseout'
},
function(origType, fixType) {
eventHooks[origType] = {
type: fixType,
fix: function(elem, fn) {
return function(e) {
var t = e.relatedTarget
if (!t || (t !== elem && !(elem.compareDocumentPosition(t) & 16))) {
delete e.type
e.type = origType
return fn.call(elem, e)
}
}
}
}
}
)
}
//针对IE9+, w3c修正animationend
Anot.each(
{
AnimationEvent: 'animationend',
WebKitAnimationEvent: 'webkitAnimationEnd'
},
function(construct, fixType) {
if (window[construct] && !eventHooks.animationend) {
eventHooks.animationend = {
type: fixType
}
}
}
)
if (DOC.onmousewheel === void 0) {
/* IE6-11 chrome mousewheel wheelDetla -120 120
firefox DOMMouseScroll detail 下3 -3
firefox wheel detlaY 下3 -3
IE9-11 wheel deltaY 下40 -40
chrome wheel deltaY 下100 -100 */
eventHooks.mousewheel = {
type: 'wheel',
fix: function(elem, fn) {
return function(e) {
e.wheelDeltaY = e.wheelDelta = e.deltaY > 0 ? -120 : 120
e.wheelDeltaX = 0
Object.defineProperty(e, 'type', {
value: 'mousewheel'
})
fn.call(elem, e)
}
}
}
}