2018-08-04 16:26:50 +08:00
|
|
|
|
//将所有远程加载的模板,以字符串形式存放到这里
|
|
|
|
|
var templatePool = (Anot.templateCache = {})
|
|
|
|
|
|
|
|
|
|
function getTemplateContainer(binding, id, text) {
|
|
|
|
|
var div = binding.templateCache && binding.templateCache[id]
|
|
|
|
|
if (div) {
|
|
|
|
|
var dom = DOC.createDocumentFragment(),
|
|
|
|
|
firstChild
|
|
|
|
|
while ((firstChild = div.firstChild)) {
|
|
|
|
|
dom.appendChild(firstChild)
|
|
|
|
|
}
|
|
|
|
|
return dom
|
|
|
|
|
}
|
|
|
|
|
return Anot.parseHTML(text)
|
|
|
|
|
}
|
|
|
|
|
function nodesToFrag(nodes) {
|
|
|
|
|
var frag = DOC.createDocumentFragment()
|
|
|
|
|
for (var i = 0, len = nodes.length; i < len; i++) {
|
|
|
|
|
frag.appendChild(nodes[i])
|
|
|
|
|
}
|
|
|
|
|
return frag
|
|
|
|
|
}
|
2019-09-09 20:18:17 +08:00
|
|
|
|
|
|
|
|
|
function _fetch(url) {
|
|
|
|
|
var xhr = new XMLHttpRequest()
|
|
|
|
|
var defer = Promise.defer()
|
|
|
|
|
xhr.open('GET', url, true)
|
|
|
|
|
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest')
|
|
|
|
|
xhr.responseType = 'text'
|
|
|
|
|
xhr.onreadystatechange = function() {
|
|
|
|
|
if (this.readyState === 4) {
|
|
|
|
|
if (this.status >= 200 && this.status < 400) {
|
|
|
|
|
defer.resolve(this.response)
|
|
|
|
|
} else {
|
|
|
|
|
defer.reject(this)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
xhr.send(null)
|
|
|
|
|
return defer.promise
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-04 16:26:50 +08:00
|
|
|
|
Anot.directive('include', {
|
|
|
|
|
init: directives.attr.init,
|
|
|
|
|
update: function(val) {
|
2019-07-16 11:45:23 +08:00
|
|
|
|
if (!val) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-04 16:26:50 +08:00
|
|
|
|
var binding = this
|
|
|
|
|
var elem = this.element
|
|
|
|
|
var vmodels = binding.vmodels
|
2019-07-16 11:45:23 +08:00
|
|
|
|
var loaded = binding.includeLoaded // 加载完的回调
|
|
|
|
|
var rendered = binding.includeRendered // 渲染完的回调
|
2018-08-04 16:26:50 +08:00
|
|
|
|
var effectClass = binding.effectName && binding.effectClass // 是否开启动画
|
2019-07-16 11:45:23 +08:00
|
|
|
|
var templateCache = binding.templateCache // 是否开启 缓存
|
|
|
|
|
var outer = binding.includeReplace // 是否替换容器
|
2018-08-04 16:26:50 +08:00
|
|
|
|
var target = outer ? elem.parentNode : elem
|
2019-07-16 11:45:23 +08:00
|
|
|
|
var _ele = binding._element // replace binding.element === binding.end
|
2018-08-04 16:26:50 +08:00
|
|
|
|
|
|
|
|
|
binding.recoverNodes = binding.recoverNodes || Anot.noop
|
|
|
|
|
|
|
|
|
|
var scanTemplate = function(text) {
|
2019-07-16 11:45:23 +08:00
|
|
|
|
var _stamp = (binding._stamp = Date.now()) // 过滤掉频繁操作
|
2018-08-04 16:26:50 +08:00
|
|
|
|
if (loaded) {
|
|
|
|
|
var newText = loaded.apply(target, [text].concat(vmodels))
|
2019-07-16 11:45:23 +08:00
|
|
|
|
if (typeof newText === 'string') {
|
|
|
|
|
text = newText
|
|
|
|
|
}
|
2018-08-04 16:26:50 +08:00
|
|
|
|
}
|
|
|
|
|
if (rendered) {
|
|
|
|
|
checkScan(
|
|
|
|
|
target,
|
|
|
|
|
function() {
|
|
|
|
|
rendered.call(target)
|
|
|
|
|
},
|
|
|
|
|
NaN
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
var lastID = binding.includeLastID || '_default' // 默认
|
|
|
|
|
|
|
|
|
|
binding.includeLastID = val
|
|
|
|
|
var leaveEl =
|
|
|
|
|
(templateCache && templateCache[lastID]) ||
|
|
|
|
|
DOC.createElement(elem.tagName || binding._element.tagName) // 创建一个离场元素
|
|
|
|
|
|
|
|
|
|
if (effectClass) {
|
|
|
|
|
leaveEl.className = effectClass
|
|
|
|
|
target.insertBefore(leaveEl, binding.start) // 插入到start之前,防止被错误的移动
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// cache or animate,移动节点
|
|
|
|
|
;(templateCache || {})[lastID] = leaveEl
|
|
|
|
|
var fragOnDom = binding.recoverNodes() // 恢复动画中的节点
|
|
|
|
|
if (fragOnDom) {
|
|
|
|
|
target.insertBefore(fragOnDom, binding.end)
|
|
|
|
|
}
|
|
|
|
|
while (true) {
|
|
|
|
|
var node = binding.start.nextSibling
|
|
|
|
|
if (node && node !== leaveEl && node !== binding.end) {
|
|
|
|
|
leaveEl.appendChild(node)
|
|
|
|
|
} else {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 元素退场
|
|
|
|
|
Anot.effect.remove(
|
|
|
|
|
leaveEl,
|
|
|
|
|
target,
|
|
|
|
|
function() {
|
|
|
|
|
if (templateCache) {
|
|
|
|
|
// write cache
|
|
|
|
|
if (_stamp === binding._stamp) ifGroup.appendChild(leaveEl)
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
binding
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var enterEl = target,
|
|
|
|
|
before = Anot.noop,
|
|
|
|
|
after = Anot.noop
|
|
|
|
|
|
|
|
|
|
var fragment = getTemplateContainer(binding, val, text)
|
|
|
|
|
var nodes = Anot.slice(fragment.childNodes)
|
|
|
|
|
|
|
|
|
|
if (outer && effectClass) {
|
|
|
|
|
enterEl = _ele
|
|
|
|
|
enterEl.innerHTML = '' // 清空
|
2019-07-16 11:45:23 +08:00
|
|
|
|
enterEl.setAttribute('skip', '')
|
2018-08-04 16:26:50 +08:00
|
|
|
|
target.insertBefore(enterEl, binding.end.nextSibling) // 插入到bingding.end之后避免被错误的移动
|
|
|
|
|
before = function() {
|
|
|
|
|
enterEl.insertBefore(fragment, null) // 插入节点
|
|
|
|
|
}
|
|
|
|
|
after = function() {
|
|
|
|
|
binding.recoverNodes = Anot.noop
|
|
|
|
|
if (_stamp === binding._stamp) {
|
|
|
|
|
fragment = nodesToFrag(nodes)
|
|
|
|
|
target.insertBefore(fragment, binding.end) // 插入真实element
|
|
|
|
|
scanNodeArray(nodes, vmodels)
|
|
|
|
|
}
|
|
|
|
|
if (enterEl.parentNode === target) target.removeChild(enterEl) // 移除入场动画元素
|
|
|
|
|
}
|
|
|
|
|
binding.recoverNodes = function() {
|
|
|
|
|
binding.recoverNodes = Anot.noop
|
|
|
|
|
return nodesToFrag(nodes)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
before = function() {
|
|
|
|
|
//新添加元素的动画
|
|
|
|
|
target.insertBefore(fragment, binding.end)
|
|
|
|
|
scanNodeArray(nodes, vmodels)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Anot.effect.apply(enterEl, 'enter', before, after)
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-16 11:45:23 +08:00
|
|
|
|
if (templatePool[val]) {
|
|
|
|
|
Anot.nextTick(function() {
|
|
|
|
|
scanTemplate(templatePool[val])
|
|
|
|
|
})
|
2018-08-04 16:26:50 +08:00
|
|
|
|
} else {
|
2019-09-09 20:18:17 +08:00
|
|
|
|
_fetch(val)
|
2019-07-16 11:45:23 +08:00
|
|
|
|
.then(text => {
|
|
|
|
|
templatePool[val] = text
|
|
|
|
|
scanTemplate(text)
|
|
|
|
|
})
|
|
|
|
|
.catch(err => {
|
2019-09-09 20:18:17 +08:00
|
|
|
|
log(
|
|
|
|
|
':include load [' + val + '] error\n%c%s',
|
|
|
|
|
'color:#f30',
|
|
|
|
|
`获取网络资源出错, ${err.status} (${err.statusText})`
|
|
|
|
|
)
|
2019-07-16 11:45:23 +08:00
|
|
|
|
})
|
2018-08-04 16:26:50 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})
|