Skip to content

Commit

Permalink
feat: 增加"preventDefaultExclude"参数, 用来排除不需要阻止默认事件的元素
Browse files Browse the repository at this point in the history
  • Loading branch information
any86 committed Oct 22, 2019
1 parent 74b901e commit 1b025b8
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 22 deletions.
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ at.on('roatemove', ev=>{});
```

```javascript
cosnt at = new AnyTouch()
const at = new AnyTouch()
{
onload(){
at.on('pinch', ev=>{
Expand Down Expand Up @@ -156,6 +156,18 @@ export default {

[做一个drawer(抽屉)插件](https://codepen.io/russell2015/pen/jJRbgp?editors=0010)


## 参数说明
|名称|类型|默认值|简要说明|
|---|---|---|---|
|touchAction|`String`|`'compute'`|对应css的touch-action属性|
|hasDomEvents|`Boolean`|`true`|是否派发手势名对应的原生事件|
|isPreventDefault|`Boolean`|`true`|是否阻止默认事件|
|preventDefaultExclude|`RegExp | ((ev: SupportEvent) => boolean)`|`/^(INPUT|TEXTAREA|BUTTON|SELECT)$/`|符合条件可不阻止默认事件的触发|
|preventDefaultExclude|`RegExp | ((ev: SupportEvent) => boolean)`|`/^(INPUT|TEXTAREA|BUTTON|SELECT)$/`|符合条件可不阻止默认事件的触发|
syncToAttr|`Boolean`|`true`|是否在元素上的`at-gesture`属性赋值当前手势名|
cssPrevent|`Object`|`{selectText: true,drag: true, tapHighlight: true, callout: true}`|是否开启上述禁止浏览器默认事件的css属性|

## 不要用alert调试

:heavy_exclamation_mark::heavy_exclamation_mark::heavy_exclamation_mark: 在安卓手机的真机上, 如果`touchstart``touchmove`阶段触发了`alert`, 会出现后续的`touchmove/touchend`不触发的 bug. 所以请大家务必避免在手势的事件回调中使用`alert`.
Expand Down
24 changes: 24 additions & 0 deletions __tests__/preventDefaultExclude.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// import TouchSimulator from './utils/TouchSimulator';
// import sleep from './utils/sleep';
import AnyTouch from '../src/main'
const el = document.createElement('div');
// const childEl = document.createElement('input');
// childEl.type = 'checkbox';
// // input
// el.appendChild(childEl);

// 暂时没想到如何触发元素的默认行为, 所以没法完美还原实际情况
test('preventDefaultExclude通过函数指定排除', async (done) => {
const at = new AnyTouch(el, {
preventDefaultExclude(ev) {
return 'div' === (<any>ev).target.tagName;
}
});
const canPreventDefault = at.canPreventDefault((<any>{ target: { tagName: 'div' } }));
expect(canPreventDefault).toBeTruthy();
done();
});




4 changes: 2 additions & 2 deletions example/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ main table tr td:nth-child(3) {
box-sizing: content-box;
width: 150px;
height: 150px;
border-radius: 10%;
background: rgba(255, 255, 255, 0.2);
border-radius: 5%;
background: rgba(255, 255, 255, 0.8);
position: fixed;
line-height: 150px;
text-align: center;
Expand Down
14 changes: 11 additions & 3 deletions example/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

<head>
<meta charset="UTF-8">
<meta data-n-head="true" name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width" />
<meta data-n-head="true" name="viewport"
content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width" />
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>🖐 AnyTouch</title>
<link rel="stylesheet" href="index.css">
Expand Down Expand Up @@ -48,7 +49,7 @@ <h1>返回数据说明</h1>
<td>{{message.pointLength}}</td>
<td>触点数</td>
</tr>

<tr>
<td>maxPointLength</td>
<td>{{message.maxPointLength}}</td>
Expand Down Expand Up @@ -206,13 +207,20 @@ <h1>返回数据说明</h1>
left:`${x}px`,
transform: `scale(${scale}) rotate(${angle}deg)`
}">{{message.type||activeType}}</div>
}">{{message.type||activeType}}<span id="inner" style="background:#f10;padding:15px;">1231313</span></div>
<span>xsadsadasd</span>

<!-- <p class="text">scale: {{scale}}</p>
<p class="text">angle: {{angle}}</p> -->
<!-- <div class="circle2" id="circle2" ref="circle2">123</div> -->
</main>
<script src="./index.js"></script>
<script>
let inner = document.getElementById('inner');
inner.addEventListener('click', ev => {
console.log(ev);
});

// let circle = document.getElementById('circle');
// circle.addEventListener('pan', ev => {
// console.log(ev);
Expand Down
7 changes: 4 additions & 3 deletions example/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ new Vue({
// 初始化
const anyTouch = new AnyTouch(el, {
touchAction: 'auto',
// isPreventDefault:false,
syncToAttr: true
});

Expand Down Expand Up @@ -127,7 +128,7 @@ new Vue({
// e.nativeEvent.preventDefault();
// anyTouch.set({touchAction:'auto',isPreventDefault:false});
this.message = e;
console.warn(e.type);
// console.warn(e.type);

});

Expand All @@ -140,7 +141,7 @@ new Vue({


anyTouch.on('panup', e => {
console.warn(e.type);
// console.warn(e.type);
});

anyTouch.on('pancancel', e => {
Expand All @@ -150,7 +151,7 @@ new Vue({
});

anyTouch.on('panend', e => {
console.warn('panend', e.direction);
// console.warn('panend', e.direction);
this.message = e;
log(e.type);
});
Expand Down
37 changes: 24 additions & 13 deletions src/AnyTouch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { TOUCH, MOUSE, SUPPORT_TOUCH, NONE, AUTO, TOUCH_START, TOUCH_MOVE, TOUCH
import InputManage from './InputManage';
import computeTouchAction from './utils/computeTouchAction';
import Store from './Store';
import { isRegExp, isFunction } from './utils/is';

// 识别器
import Recognizer from './recognitions/Base';
Expand All @@ -36,6 +37,8 @@ interface Options {
touchAction?: 'compute' | 'auto' | 'manipulation' | 'pan-x' | 'pan-y' | 'none';
hasDomEvents?: boolean;
isPreventDefault?: boolean;
// 不阻止默认行为的白名单
preventDefaultExclude?: RegExp | ((ev: SupportEvent) => boolean);
syncToAttr?: boolean;
cssPrevent?: {
// 阻止触发选择文字
Expand All @@ -48,7 +51,7 @@ interface Options {
callout?: boolean;
}
};
export default class {
export default class {
// 识别器
static Tap = Tap;
static Press = Press;
Expand Down Expand Up @@ -95,6 +98,7 @@ export default class {
touchAction: COMPUTE,
hasDomEvents: true,
isPreventDefault: true,
preventDefaultExclude: /^(INPUT|TEXTAREA|BUTTON|SELECT)$/,
syncToAttr: false,
cssPrevent: {
// 阻止触发选择文字
Expand Down Expand Up @@ -222,7 +226,7 @@ export default class {
* @param {Element} 待绑定手势元素
*/
private _bindEL(el: Element) {
const boundInputListener = <EventListener>this.inputListener.bind(this);
const boundInputListener = <EventListener>this.catchEvent.bind(this);

// Touch
if (TOUCH === this.touchDevice) {
Expand Down Expand Up @@ -253,15 +257,6 @@ export default class {
}
};

/**
* 为微信设计的功能
* 接收touch事件的event对象
* @param {SupportEvent} 事件对象
*/
catchEvent(event: SupportEvent) {
this.inputListener(event);
};

/**
* 添加识别器
* @param recognizer 识别器
Expand Down Expand Up @@ -315,12 +310,28 @@ export default class {
}
};

canPreventDefault(event: SupportEvent): boolean {
let isPreventDefault = true;
if (null !== event.target) {
const { preventDefaultExclude } = this.options;
if (isRegExp(preventDefaultExclude)) {
const { tagName } = (<HTMLElement>event.target);
if (undefined !== tagName) {
isPreventDefault = preventDefaultExclude.test(tagName);
}
} else if (isFunction(preventDefaultExclude)) {
isPreventDefault = preventDefaultExclude(event)
}
}
return isPreventDefault;
};

/**
* 监听input变化
* @param {Event}
*/
inputListener(event: SupportEvent): void {
if (this.options.isPreventDefault) {
catchEvent(event: SupportEvent): void {
if (this.options.isPreventDefault && this.canPreventDefault(event)) {
event.preventDefault();
}

Expand Down
9 changes: 9 additions & 0 deletions src/utils/is.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const ObjectToString = Object.prototype.toString;

export function isRegExp(input: any): input is RegExp {
return '[object RegExp]' === ObjectToString.call(input);
}

export function isFunction(input: any): input is Function {
return '[object Function]' === ObjectToString.call(input);
}

0 comments on commit 1b025b8

Please sign in to comment.