Last active
January 10, 2018 08:16
-
-
Save s875515/3a5a2f911a2db00c75dc993335f4b4f3 to your computer and use it in GitHub Desktop.
react-ga event tracking function common component solution. If have any better solution that comment below. thanks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as React from 'react'; | |
import * as gaModel from '~/model/gaModel'; | |
import gaUtil from '~/util/gaUtil'; | |
/** | |
* 為了省略不必要的div層去觸發ga event | |
* 會分成兩種做法 | |
* | |
* 一、 | |
* GaBox拿來包的是 自定義component 的話: | |
* 一樣還是會去在最外層包一層div,去觸發event(有更好的做法請聯絡 | |
* 所以會有破版可能,若有影響請自行寫style調整 | |
* | |
* 二、 | |
* GaBox拿來包的是 一般jsx 的話: | |
* 就會直接利用react.flagment去省略掉div層 | |
* 用cloneElement將onClick事件再包裝 | |
* 若原本下層就有click事件的話,也會將其包裝進來 | |
* 不會影響到原本onclick運作 | |
* | |
*/ | |
interface props { | |
// className | |
className?: string; | |
// style | |
style?: any; | |
// child element | |
children: any; | |
/** | |
* 頁面 | |
* e.q. (依據路由) | |
* 小遊戲:game | |
*/ | |
page: string; | |
/** | |
* 位置 | |
* e.q. (底線區隔、小寫) | |
* 熱門遊戲列表: hot_list | |
*/ | |
position: string; | |
/** | |
* 事件 | |
* click | view | hover | |
* 預設會為click | |
* 依據需要的event丟陣列進來 | |
*/ | |
event?: [gaModel.gaEvent]; | |
/** | |
* 標籤 | |
* e.q. (底線區隔、小寫) | |
* 小遊戲:bbin_糖果派對 | |
*/ | |
label?: string; | |
} | |
class GaBox extends React.PureComponent<props> { | |
static defaultProps: props = { | |
page: '', | |
position: '', | |
event: [gaModel.gaEvent.click], | |
children: '', | |
}; | |
componentDidMount(): void { | |
this.handleEvent(gaModel.gaEvent.view)(); | |
} | |
handleEvent = (eventFlag: gaModel.gaEvent): any => (): void => { | |
const { page, position, event, label }: props = this.props; | |
if (event && event.indexOf(eventFlag) > -1) { | |
const action: string = `${page}.${position}.${eventFlag}`; | |
gaUtil.logEvent(action, label); | |
} | |
} | |
render(): JSX.Element { | |
// 包裝 自定義 component | |
if (!isJsx(this.props.children.type)) { | |
return ( | |
<div | |
className={this.props.className} | |
style={this.props.style} | |
onClick={this.handleEvent(gaModel.gaEvent.click)} | |
onMouseOver={this.handleEvent(gaModel.gaEvent.hover)} | |
> | |
{this.props.children} | |
</div> | |
); | |
} | |
// 包裝 一般JSX element | |
const child: JSX.Element = React.cloneElement(this.props.children, { | |
onClick: (): void => { | |
const handleClickFunc: any = this.props.children.props.onClick; | |
this.handleEvent(gaModel.gaEvent.click)(); | |
// 觸發原本click事件 | |
handleClickFunc && handleClickFunc(); | |
}, | |
onMouseOver: (): void => { | |
const handleMouseOverFunc: any = this.props.children.props.onMouseOver; | |
this.handleEvent(gaModel.gaEvent.hover)(); | |
// 觸發原本onMouseOver事件 | |
handleMouseOverFunc && handleMouseOverFunc(); | |
}, | |
}); | |
return ( | |
<React.Fragment> | |
{child} | |
</React.Fragment> | |
); | |
} | |
} | |
const isJsx: any = (type: string): boolean => { | |
const all_html: any[] = [ | |
'span', | |
'address', | |
'applet', | |
'area', | |
'article', | |
'aside', | |
'base', | |
'basefont', | |
'bgsound', | |
'blockquote', | |
'body', | |
'br', | |
'button', | |
'caption', | |
'center', | |
'col', | |
'colgroup', | |
'dd', | |
'details', | |
'dir', | |
'div', | |
'dl', | |
'dt', | |
'embed', | |
'fieldset', | |
'figcaption', | |
'figure', | |
'footer', | |
'form', | |
'frame', | |
'frameset', | |
'h1', | |
'h2', | |
'h3', | |
'h4', | |
'h5', | |
'h6', | |
'head', | |
'header', | |
'hgroup', | |
'hr', | |
'html', | |
'iframe', | |
'img', | |
'input', | |
'isindex', | |
'li', | |
'link', | |
'listing', | |
'main', | |
'marquee', | |
'menu', | |
'menuitem', | |
'meta', | |
'nav', | |
'noembed', | |
'noframes', | |
'noscript', | |
'object', | |
'ol', | |
'p', | |
'param', | |
'plaintext', | |
'pre', | |
'script', | |
'section', | |
'select', | |
'source', | |
'style', | |
'summary', | |
'table', | |
'tbody', | |
'td', | |
'template', | |
'textarea', | |
'tfoot', | |
'th', | |
'thead', | |
'title', | |
'tr', | |
'track', | |
'ul', | |
'wbr', | |
'xmp', | |
'applet', | |
'caption', | |
'html', | |
'table', | |
'td', | |
'th', | |
'marquee', | |
'object', | |
'template', | |
'foreignObject', | |
'desc', | |
'title', | |
'dd', | |
'dt', | |
'li', | |
'option', | |
'optgroup', | |
'p', | |
'rp', | |
'rt', | |
]; | |
return all_html.indexOf(type) > -1; | |
}; | |
export default GaBox; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment