|
|
@@ -3,159 +3,155 @@ import { injectable, Service } from './service'
|
|
|
/** vue 自定义指令 */
|
|
|
@injectable
|
|
|
export default class directiveService extends Service {
|
|
|
- /** 长按 */
|
|
|
- longpress() {
|
|
|
- return {
|
|
|
- beforeMount(el: { $duration: number | undefined; addEventListener: (arg0: string, arg1: { (e: { type: string; button: number; preventDefault: () => void; }): void; (e: { type: string; button: number; preventDefault: () => void; }): void; (): void; (): void; (): void; }) => void; }, binding: { value: any; arg: number; }) {
|
|
|
- const cb = binding.value;
|
|
|
- el.$duration = binding.arg || 3000; // 获取长按时长, 默认3秒执行长按事件
|
|
|
- if (typeof cb !== 'function') return console.warn('v-longpress指令必须接收一个回调函数');
|
|
|
- let timer: string | number | NodeJS.Timeout | null | undefined = null;
|
|
|
- const add: Any = (e: { type: string; button: number; preventDefault: () => void; }) => {
|
|
|
- // 排除点击与右键情况, event.button: 0-左键 2-右键
|
|
|
- if (e.type === 'click' && e.button !== 0) return;
|
|
|
- e.preventDefault();
|
|
|
- if (timer === null) {
|
|
|
- timer = setTimeout(() => {
|
|
|
- cb('start');
|
|
|
- timer = null;
|
|
|
- }, el.$duration)
|
|
|
- }
|
|
|
- }
|
|
|
- const cancel = () => {
|
|
|
- if (timer !== null) {
|
|
|
- clearTimeout(timer);
|
|
|
- timer = null;
|
|
|
- }
|
|
|
- cb('end');
|
|
|
- }
|
|
|
+ /** 长按 */
|
|
|
+ longpress = {
|
|
|
|
|
|
- // 添加计时器
|
|
|
- el.addEventListener('mousedown', add);
|
|
|
- el.addEventListener('touchstart', add);
|
|
|
- // 取消计时器
|
|
|
- el.addEventListener('mouseout', cancel);
|
|
|
- el.addEventListener('touchend', cancel)
|
|
|
- el.addEventListener('touchcancel', cancel)
|
|
|
- },
|
|
|
- updated(el: { $duration: any; }, binding: { arg: any; }) {
|
|
|
- // 可以实时更新时长
|
|
|
- el.$duration = binding.arg;
|
|
|
- },
|
|
|
- unmounted(el: { removeEventListener: (arg0: string, arg1: { (): void; (): void; (): void; (): void; (): void; (): void; }) => void; }) {
|
|
|
- el.removeEventListener('mousedown', () => { });
|
|
|
- el.removeEventListener('touchstart', () => { });
|
|
|
- el.removeEventListener('click', () => { });
|
|
|
- el.removeEventListener('mouseout', () => { });
|
|
|
- el.removeEventListener('touchend', () => { });
|
|
|
- el.removeEventListener('touchcancel', () => { });
|
|
|
- }
|
|
|
+ beforeMount(el: any, binding: any) {
|
|
|
+ const cb = binding.value
|
|
|
+ el.$durations = binding.arg || 3000 // 获取长按时长, 默认3秒执行长按事件
|
|
|
+ if (typeof cb !== 'function') return console.warn('v-longpress指令必须接收一个回调函数')
|
|
|
+ let timer: any = null
|
|
|
+ const add = (e: { type: string; button: number; preventDefault: () => void }) => {
|
|
|
+ // 排除点击与右键情况, event.button: 0-左键 2-右键
|
|
|
+ if (e.type === 'click' && e.button !== 0) return
|
|
|
+ e.preventDefault()
|
|
|
+ if (timer === null) {
|
|
|
+ timer = setTimeout(() => {
|
|
|
+ cb('start')
|
|
|
+ timer = null
|
|
|
+ }, el.$durations)
|
|
|
}
|
|
|
+ }
|
|
|
+ const cancel = () => {
|
|
|
+ if (timer !== null) {
|
|
|
+ clearTimeout(timer)
|
|
|
+ timer = null
|
|
|
+ }
|
|
|
+ cb('end')
|
|
|
+ }
|
|
|
+
|
|
|
+ // 添加计时器
|
|
|
+ el.addEventListener('mousedown', add)
|
|
|
+ el.addEventListener('touchstart', add)
|
|
|
+ // 取消计时器
|
|
|
+ el.addEventListener('mouseout', cancel)
|
|
|
+ el.addEventListener('touchend', cancel)
|
|
|
+ el.addEventListener('touchcancel', cancel)
|
|
|
+ },
|
|
|
+ updated(el: any, binding: any) {
|
|
|
+ // 可以实时更新时长
|
|
|
+ el.$durations = binding.arg
|
|
|
+ },
|
|
|
+ unmounted(el: any) {
|
|
|
+ el.removeEventListener('mousedown', () => { })
|
|
|
+ el.removeEventListener('touchstart', () => { })
|
|
|
+ el.removeEventListener('click', () => { })
|
|
|
+ el.removeEventListener('mouseout', () => { })
|
|
|
+ el.removeEventListener('touchend', () => { })
|
|
|
+ el.removeEventListener('touchcancel', () => { })
|
|
|
}
|
|
|
|
|
|
- /** 拖拽 */
|
|
|
- drag() {
|
|
|
- return {
|
|
|
- mounted(el: HTMLElement | null) {
|
|
|
- const oDiv = el // 当前元素
|
|
|
- el!.style.pointerEvents = 'none' // 防止触发点击事件
|
|
|
- oDiv!.onmousedown = e => {
|
|
|
- // 找父级 是否是absolute来进行移动
|
|
|
- let target = oDiv
|
|
|
- while (window.getComputedStyle(target!).position !== 'absolute' && target !== document.body) {
|
|
|
- target = target!.parentElement
|
|
|
- }
|
|
|
- // 找父级 是否是relative来进行宽度计算
|
|
|
- let targetParent = target!.parentElement
|
|
|
- while (window.getComputedStyle(targetParent!).position !== 'relative' && targetParent !== document.body) {
|
|
|
- targetParent = targetParent!.parentElement
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
- document.onselectstart = () => {
|
|
|
- return false
|
|
|
- }
|
|
|
+ /** 拖拽 */
|
|
|
+ drag = {
|
|
|
|
|
|
- // 鼠标按下,计算当前元素距离可视区的距离
|
|
|
- const disX = e.clientX - target!.offsetLeft
|
|
|
- const disY = e.clientY - target!.offsetTop
|
|
|
- const cW = +window.getComputedStyle(target!).width.replace('px', '')
|
|
|
- const cH = +window.getComputedStyle(target!).height.replace('px', '')
|
|
|
- const maxW = +window.getComputedStyle(targetParent!).width.replace('px', '')
|
|
|
- const maxH = +window.getComputedStyle(targetParent!).height.replace('px', '')
|
|
|
- document.onmousemove = e => {
|
|
|
- // 通过事件委托,计算移动的距离
|
|
|
- // 因为浏览器里并不能直接取到并且使用clientX、clientY,所以使用事件委托在内部做完赋值
|
|
|
- el!.style.pointerEvents = 'none'
|
|
|
- const l = e.clientX - disX
|
|
|
- const t = e.clientY - disY
|
|
|
- const cl = maxW - cW
|
|
|
- const ct = maxH - cH
|
|
|
- // 计算移动当前元素的位置,并且给该元素样式中的left和top值赋值
|
|
|
- target!.style.left = (l < 0 ? 0 : l > cl ? cl : l) + 'px'
|
|
|
- target!.style.top = (t < 0 ? 0 : t > ct ? ct : t) + 'px'
|
|
|
- }
|
|
|
- document.onmouseup = e => {
|
|
|
- el!.style.pointerEvents = 'none'
|
|
|
- document.onmousemove = null
|
|
|
- document.onmouseup = null
|
|
|
- document.onselectstart = null
|
|
|
- }
|
|
|
- // return false不加的话可能导致黏连,拖到一个地方时div粘在鼠标上不下来,相当于onmouseup失效
|
|
|
- return false
|
|
|
- }
|
|
|
- }
|
|
|
+ mounted(el: HTMLElement | null) {
|
|
|
+ const oDiv = el // 当前元素
|
|
|
+ // el!.style.pointerEvents = null // 防止触发点击事件
|
|
|
+ oDiv!.onmousedown = (e) => {
|
|
|
+ // 找父级 是否是absolute来进行移动
|
|
|
+ let target = oDiv
|
|
|
+ while (window.getComputedStyle(target!).position !== 'absolute' && target !== document.body) {
|
|
|
+ target = target!.parentElement
|
|
|
+ }
|
|
|
+ // 找父级 是否是relative来进行宽度计算
|
|
|
+ let targetParent = target!.parentElement
|
|
|
+ while (window.getComputedStyle(targetParent!).position !== 'relative' && targetParent !== document.body) {
|
|
|
+ targetParent = targetParent!.parentElement
|
|
|
}
|
|
|
|
|
|
- }
|
|
|
+ document.onselectstart = () => false
|
|
|
|
|
|
- /** 点击其它地方消失 */
|
|
|
- clickoutside() {
|
|
|
- return {
|
|
|
- beforeMount(el: { contains: (arg0: EventTarget | null) => any; }, binding: { value: () => any; }) {
|
|
|
- document.addEventListener('click', (e) => {
|
|
|
- el.contains(e.target) && binding.value();
|
|
|
- }, false)
|
|
|
- },
|
|
|
- unmounted() {
|
|
|
- document.removeEventListener('click', () => { })
|
|
|
- }
|
|
|
+ // 鼠标按下,计算当前元素距离可视区的距离
|
|
|
+ const disX = e.clientX - target!.offsetLeft
|
|
|
+ const disY = e.clientY - target!.offsetTop
|
|
|
+ const cW = +window.getComputedStyle(target!).width.replace('px', '')
|
|
|
+ const cH = +window.getComputedStyle(target!).height.replace('px', '')
|
|
|
+ const maxW = +window.getComputedStyle(targetParent!).width.replace('px', '')
|
|
|
+ const maxH = +window.getComputedStyle(targetParent!).height.replace('px', '')
|
|
|
+ document.onmousemove = (e) => {
|
|
|
+ // 通过事件委托,计算移动的距离
|
|
|
+ // 因为浏览器里并不能直接取到并且使用clientX、clientY,所以使用事件委托在内部做完赋值
|
|
|
+ // el!.style.pointerEvents = 'none'
|
|
|
+ const l = e.clientX - disX
|
|
|
+ const t = e.clientY - disY
|
|
|
+ const cl = maxW - cW
|
|
|
+ const ct = maxH - cH
|
|
|
+ // 计算移动当前元素的位置,并且给该元素样式中的left和top值赋值
|
|
|
+ target!.style.left = `${l < 0 ? 0 : l > cl ? cl : l}px`
|
|
|
+ target!.style.top = `${t < 0 ? 0 : t > ct ? ct : t}px`
|
|
|
+ }
|
|
|
+ document.onmouseup = (e) => {
|
|
|
+ // el!.style.pointerEvents = 'none'
|
|
|
+ document.onmousemove = null
|
|
|
+ document.onmouseup = null
|
|
|
+ document.onselectstart = null
|
|
|
}
|
|
|
+ // return false不加的话可能导致黏连,拖到一个地方时div粘在鼠标上不下来,相当于onmouseup失效
|
|
|
+ return false
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- /** 复制 */
|
|
|
- copy() {
|
|
|
- return {
|
|
|
- beforeMount(el: { targetContent: string; addEventListener: (arg0: string, arg1: () => void) => void; }, binding: { arg: Any; value: Any; }) {
|
|
|
- el.targetContent = binding.value;
|
|
|
- const success = binding.arg;
|
|
|
- el.addEventListener('click', () => {
|
|
|
- if (!el.targetContent) return console.warn('没有需要复制的目标内容');
|
|
|
- // 创建textarea标签
|
|
|
- const textarea = document.createElement('textarea');
|
|
|
- // 设置相关属性
|
|
|
- textarea.readOnly = true;
|
|
|
- textarea.style.position = 'fixed';
|
|
|
- textarea.style.top = '-99999px';
|
|
|
- // 把目标内容赋值给它的value属性
|
|
|
- textarea.value = el.targetContent;
|
|
|
- // 插入到页面
|
|
|
- document.body.appendChild(textarea);
|
|
|
- // 调用onselect()方法
|
|
|
- textarea.select();
|
|
|
- // 把目标内容复制进剪贴板, 该API会返回一个Boolean
|
|
|
- const res = document.execCommand('Copy');
|
|
|
- res && success ? success(el.targetContent) : console.log('复制成功,剪贴板内容:' + el.targetContent);
|
|
|
- // 移除textarea标签
|
|
|
- document.body.removeChild(textarea);
|
|
|
- })
|
|
|
- },
|
|
|
- updated(el: { targetContent: any; }, binding: { value: any; }) {
|
|
|
- // 实时更新最新的目标内容
|
|
|
- el.targetContent = binding.value;
|
|
|
- },
|
|
|
- unmounted(el: { removeEventListener: (arg0: string, arg1: () => void) => void; }) {
|
|
|
- el.removeEventListener('click', () => { })
|
|
|
- }
|
|
|
- }
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 点击其它地方消失 */
|
|
|
+ clickoutside = {
|
|
|
+
|
|
|
+ beforeMount(el: { contains: (arg0: EventTarget | null) => any; }, binding: { value: () => any; }) {
|
|
|
+ document.addEventListener('click', (e) => {
|
|
|
+ el.contains(e.target) && binding.value()
|
|
|
+ }, false)
|
|
|
+ },
|
|
|
+ unmounted() {
|
|
|
+ document.removeEventListener('click', () => { })
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 复制 */
|
|
|
+ copy = {
|
|
|
+
|
|
|
+ beforeMount(el: { targetContent: string; addEventListener: (arg0: string, arg1: () => void) => void; }, binding: { arg: any; value: any; }) {
|
|
|
+ el.targetContent = binding.value
|
|
|
+ const success = binding.arg
|
|
|
+ el.addEventListener('click', () => {
|
|
|
+ if (!el.targetContent) return console.warn('没有需要复制的目标内容')
|
|
|
+ // 创建textarea标签
|
|
|
+ const textarea = document.createElement('textarea')
|
|
|
+ // 设置相关属性
|
|
|
+ textarea.readOnly = true
|
|
|
+ textarea.style.position = 'fixed'
|
|
|
+ textarea.style.top = '-99999px'
|
|
|
+ // 把目标内容赋值给它的value属性
|
|
|
+ textarea.value = el.targetContent
|
|
|
+ // 插入到页面
|
|
|
+ document.body.appendChild(textarea)
|
|
|
+ // 调用onselect()方法
|
|
|
+ textarea.select()
|
|
|
+ // 把目标内容复制进剪贴板, 该API会返回一个Boolean
|
|
|
+ const res = document.execCommand('Copy')
|
|
|
+ res && success ? success(el.targetContent) : console.log(`复制成功,剪贴板内容:${el.targetContent}`)
|
|
|
+ // 移除textarea标签
|
|
|
+ document.body.removeChild(textarea)
|
|
|
+ })
|
|
|
+ },
|
|
|
+ updated(el: { targetContent: any; }, binding: { value: any; }) {
|
|
|
+ // 实时更新最新的目标内容
|
|
|
+ el.targetContent = binding.value
|
|
|
+ },
|
|
|
+ unmounted(el: { removeEventListener: (arg0: string, arg1: () => void) => void; }) {
|
|
|
+ el.removeEventListener('click', () => { })
|
|
|
}
|
|
|
+ }
|
|
|
}
|