From 4fe95a387f40ddba5366059b4e96e704fb57553d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E5=A4=A9?= Date: Mon, 2 Sep 2019 18:27:37 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=8D=A2layer=E7=9A=84=E5=AE=9E?= =?UTF-8?q?=E4=BE=8B=E5=8C=96=E6=96=B9=E5=BC=8F;drag=E6=89=8B=E5=8A=BF?= =?UTF-8?q?=E6=A0=B7=E5=BC=8F=E7=A7=BB=E9=99=A4=E8=80=81=E5=85=BC=E5=AE=B9?= =?UTF-8?q?=E6=96=B9=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/drag/core.js | 8 +- src/layer/next.wc | 498 ++++++++++++++++++++++++---------------------- 2 files changed, 264 insertions(+), 242 deletions(-) diff --git a/src/drag/core.js b/src/drag/core.js index f3bb26a..f37e970 100644 --- a/src/drag/core.js +++ b/src/drag/core.js @@ -39,13 +39,7 @@ export default class Drag { } // 鼠标状态图标 - var ico = document.documentMode ? 'move' : 'grab' - if (window.sidebar) { - ico = '-moz-' + ico - } else { - ico = '-webkit-' + ico - } - node.style.cursor = ico + node.style.cursor = 'move' this._handleResize = bind(window, 'resize', this._init.bind(this)) diff --git a/src/layer/next.wc b/src/layer/next.wc index 949d62b..880ea2b 100644 --- a/src/layer/next.wc +++ b/src/layer/next.wc @@ -25,11 +25,11 @@ } .layer { + overflow: hidden; flex: 0 auto; - position: absolute; + position: fixed; z-index: 65535; - // padding: 15px 10px; - border-radius: 3px; + border-radius: 4px; color: #666; font-size: 14px; box-shadow: 0 5px 20px rgba(0, 0, 0, 0.3); @@ -197,17 +197,7 @@ const lang = let unique = null // 储存当前打开的alert/confirm/prompt类型的弹窗 let defconf = { - type: 1, // 弹窗类型 - background: '#fff', - mask: true, // 遮罩 - maskClose: false, // 遮罩点击关闭弹窗 - maskColor: null, // 遮罩背景色 - radius: '0px', // 弹窗圆角半径 area: ['auto', 'auto'], - title: lang.TITLE, // 弹窗主标题(在工具栏上的) - menubar: true, // 是否显示菜单栏 - content: '', // 弹窗的内容 - fixed: false, // 是否固定不可拖拽 shift: {}, // 弹窗出来的初始位置,用于出场动画 offset: {} // 弹窗出来后的坐标, 为数组,可有4个值,依次是 上右下左 } @@ -228,6 +218,227 @@ const fixOffset = function(offset) { return offset } +function renderBtns(list) { + var html = '' + list.forEach((t, i) => { + html += `` + }) + + return html +} + +class Layer { + props = { + btns: [], + type: 'msg', + title: '', + fixed: false //是否固定位置 + } + + __init__() { + /* render */ + + this.__TITLE__ = this.root.children[1].firstElementChild + this.__BODY__ = this.root.children[1].children[1] + this.__CTRL__ = this.root.children[1].lastElementChild + + this.promise = new Promise((resolve, reject) => { + this.resolve = resolve + this.reject = reject + }) + } + + set title(val) { + if (val) { + this.__TITLE__.textContent = val + this.__TITLE__.style.display = '' + } else { + this.__TITLE__.style.display = 'none' + } + } + + set type(val) { + var { btns } = this.props + + switch (val) { + case 'alert': + while (btns.length > 1) { + btns.splice(0, 1) + } + break + case 'confirm': + case 'prompt': + while (btns.length > 2) { + btns.splice(0, 1) + } + break + case 'toast': + case 'frame': + btns = [] + break + default: + val = 'common' + break + } + this.props.type = val + if (btns.length) { + this.__CTRL__.innerHTML = renderBtns(btns) + this.__CTRL__.style.display = '' + } else { + this.__CTRL__.style.display = 'none' + } + + this.setAttribute('type', val) + } + + set fixed(val) { + this.props.fixed = !!val + + this._updateFixedStat() + } + + _updateFixedStat() { + // 这3类弹层不允许拖拽 + if (UNIQUE_TYPES.includes(this.props.type)) { + return + } + + if (this.props.fixed) { + if (this._dragIns) { + this._dragIns.destroy() + this._dragIns = null + } + } else { + this._dragIns = new Drag(this.root.children[1]).by(this.__TITLE__, { + overflow: this.props.hasOwnProperty('overflow') + ? this.props.overflow + : false + }) + this.removeAttribute('fixed') + } + } + + // 拦截 "确定"按钮的事件 + _intercept(input) { + if (this.props.intercept) { + this.props.intercept(input, _ => { + delete this.props.intercept + this.resolve(input) + this.close() + }) + } else { + this.resolve(input) + this.close() + } + } + + close() { + if (this._dragIns) { + this._dragIns.destroy() + } + if (UNIQUE_TYPES.includes(this.props.type)) { + unique = null + } + delete this.promise + unbind(this.__CTRL__, 'click', this._handleBtnClick) + this.parentNode.removeChild(this) + } + + mounted() { + this._handleBtnClick = bind(this.__CTRL__, 'click', ev => { + if (ev.target.tagName === 'BUTTON') { + var idx = +ev.target.dataset.idx + var { type } = this.props + + switch (type) { + case 'alert': + this.resolve() + this.close() + break + case 'confirm': + case 'prompt': + if (idx === 0) { + this.reject() + this.close() + } else { + let inputValue = type === 'prompt' ? this.__INPUT__.value : null + this._intercept(inputValue) + } + break + + default: + // 其他类型, 如有按钮, 直接交给拦截器处理 + this._intercept(idx) + break + } + } + }) + + if (this.props.type === 'prompt') { + this.__INPUT__ = this.__BODY__.firstElementChild.assignedNodes().pop() + this._handleSubmit = bind(this.__INPUT__, 'submit', ev => { + this._intercept(ev.detail) + }) + } + + this._updateFixedStat() + + if (this.props.mask) { + this._handlMask = clickOutside(this.root.children[1], ev => { + if (this.props.maskClose) { + this.reject(null) + this.close() + } else { + if (UNIQUE_TYPES.includes(this.props.type)) { + this.root.children[1].classList.toggle('scale', true) + setTimeout(_ => { + this.root.children[1].classList.remove('scale') + }, 100) + } + } + }) + + if (this.props.maskColor) { + this.style.backgroundColor = this.props.maskColor + } + } + + if (this.props.blur) { + this.root.children[1].classList.toggle('blur', true) + } + + let _style = '' + + if (this.props.background) { + _style += `background: ${this.props.background};` + } + if (this.props.radius) { + _style += `border-radius: ${this.props.radius};` + } + + if (_style) { + log(_style) + this.root.children[1].style.cssText += _style + } + } + + unmount() { + unbind(document, 'mousedown', this._handlMask) + } + + watch() { + switch (name) { + case 'title': + case 'type': + this[name] = val + break + case 'fixed': + this.fixed = true + break + } + } +} + function createLayer(opt) { var layDom = document.createElement('wc-layer') if (opt.mask) { @@ -235,7 +446,9 @@ function createLayer(opt) { } layDom.title = opt.title - if (opt.btns && opt.btns.length) { + if (opt.btns === false) { + layDom.props.btns = [] + } else if (opt.btns && opt.btns.length) { layDom.props.btns = opt.btns } else { layDom.props.btns = lang.BTNS.concat() @@ -245,10 +458,15 @@ function createLayer(opt) { layDom.props.intercept = opt.intercept } + layDom.props.radius = opt.radius layDom.props.background = opt.background layDom.props.mask = opt.mask layDom.props.maskClose = opt.maskClose layDom.props.maskColor = opt.maskColor + layDom.props.blur = opt.blur + if (opt.hasOwnProperty('overflow')) { + layDom.props.overflow = opt.overflow + } layDom.type = opt.type layDom.innerHTML = opt.content @@ -264,7 +482,36 @@ function createLayer(opt) { return layDom.promise } -const _layer = { +const _layer = function(opt) { + if (typeof opt === 'string') { + opt = 'layerwrap-' + opt + if (!layerObj[opt]) { + throw new Error(lang.ERROR) + } else { + //只能显示一个实例 + if (layerObj[opt].show) { + return opt + } + layerObj[opt].show = true + + layerObj[opt].parentElem.appendChild(layerDom[opt][0]) + layerDom[opt][0] + .querySelector('.layer-content') + .appendChild(layerObj[opt].wrap) + layerObj[opt].wrap.style.display = '' + + if (!Anot.vmodels[opt]) { + Anot(layerObj[opt].obj.init) + } + layerObj[opt].obj.show() + return opt + } + } else { + return createLayer(opt) + } +} + +Object.assign(_layer, { alert(content, title = lang.TITLE) { return createLayer({ type: 'alert', @@ -342,37 +589,8 @@ const _layer = { } return _layer.open(opt) - }, - - open(opt) { - if (typeof opt === 'string') { - opt = 'layerwrap-' + opt - if (!layerObj[opt]) { - throw new Error(lang.ERROR) - } else { - //只能显示一个实例 - if (layerObj[opt].show) { - return opt - } - layerObj[opt].show = true - - layerObj[opt].parentElem.appendChild(layerDom[opt][0]) - layerDom[opt][0] - .querySelector('.layer-content') - .appendChild(layerObj[opt].wrap) - layerObj[opt].wrap.style.display = '' - - if (!Anot.vmodels[opt]) { - Anot(layerObj[opt].obj.init) - } - layerObj[opt].obj.show() - return opt - } - } else { - return new __layer__(opt).init.$id - } } -} +}) /* Anot.directive('layer', { priority: 8090, @@ -508,196 +726,6 @@ const _layer = { } }) */ -function renderBtns(list) { - var html = '' - list.forEach((t, i) => { - html += `` - }) - - return html -} - -class Layer { - props = { - btns: [], - type: 'msg', - title: '', - fixed: false //是否固定位置 - } - - __init__() { - /* render */ - - this.__TITLE__ = this.root.children[1].firstElementChild - this.__BODY__ = this.root.children[1].children[1] - this.__CTRL__ = this.root.children[1].lastElementChild - - this.promise = new Promise((resolve, reject) => { - this.resolve = resolve - this.reject = reject - }) - } - - set title(val) { - if (val) { - this.__TITLE__.textContent = val - this.__TITLE__.style.display = '' - } else { - this.__TITLE__.style.display = 'none' - } - } - - set type(val) { - var { btns } = this.props - - switch (val) { - case 'alert': - while (btns.length > 1) { - btns.splice(0, 1) - } - break - case 'confirm': - case 'prompt': - while (btns.length > 2) { - btns.splice(0, 1) - } - break - case 'toast': - case 'frame': - btns = [] - break - default: - val = 'common' - break - } - this.props.type = val - if (btns.length) { - this.__CTRL__.innerHTML = renderBtns(btns) - this.__CTRL__.style.display = '' - } else { - this.__CTRL__.style.display = 'none' - } - - this.setAttribute('type', val) - } - - set fixed(val) { - this.props.fixed = !!val - - // 这3类弹层不允许拖拽 - if (UNIQUE_TYPES.includes(this.props.type)) { - return - } - - if (this.props.fixed) { - if (this._dragIns) { - this._dragIns.destroy() - this._dragIns = null - } - } else { - this._dragIns = new Drag(this.root.children[1]).by(this.__TITLE__, { - overflow: false - }) - this.removeAttribute('fixed') - } - } - - // 拦截 "确定"按钮的事件 - _intercept(input) { - if (this.props.intercept) { - this.props.intercept(input, _ => { - delete this.props.intercept - this.resolve(input) - this.close() - }) - } else { - this.resolve(input) - this.close() - } - } - - close() { - if (this._dragIns) { - this._dragIns.destroy() - } - if (UNIQUE_TYPES.includes(this.props.type)) { - unique = null - } - delete this.promise - unbind(this.__CTRL__, 'click', this._handleBtnClick) - this.parentNode.removeChild(this) - } - - mounted() { - this._handleBtnClick = bind(this.__CTRL__, 'click', ev => { - if (ev.target.tagName === 'BUTTON') { - var idx = +ev.target.dataset.idx - var { intercept, type } = this.props - - switch (type) { - case 'alert': - this.resolve() - this.close() - break - case 'confirm': - case 'prompt': - if (idx === 0) { - this.reject() - this.close() - } else { - let inputValue = type === 'prompt' ? this.__INPUT__.value : null - this._intercept(inputValue) - } - break - - default: - // 其他类型, 如有按钮, 直接返回按钮的索引, 不作任何拦截 - this.resolve(idx) - this.close() - } - } - }) - - if (this.props.type === 'prompt') { - this.__INPUT__ = this.__BODY__.firstElementChild.assignedNodes().pop() - this._handleSubmit = bind(this.__INPUT__, 'submit', ev => { - this._intercept(ev.detail) - }) - } - - if (this.props.mask) { - this._handlMask = clickOutside(this.root.children[1], ev => { - if (this.props.maskClose) { - this.close() - } else { - if (UNIQUE_TYPES.includes(this.props.type)) { - this.root.children[1].classList.toggle('scale', true) - setTimeout(_ => { - this.root.children[1].classList.remove('scale') - }, 100) - } - } - }) - } - } - - unmount() { - unbind(document, 'mousedown', this._handlMask) - } - - watch() { - switch (name) { - case 'title': - case 'type': - this[name] = val - break - case 'fixed': - this.fixed = true - break - } - } -} - window.layer = _layer export default _layer