Last active
March 24, 2020 06:02
-
-
Save jiyuujin/3576ba4159e81c2d7f1c5ad263e78b29 to your computer and use it in GitHub Desktop.
[doubleSubmit対策] Enterによる連打、ダブルクリックによるリクエストを禁止する
This file contains hidden or 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 { FormControl } from './FormControl'; | |
import { LinkControl } from './LinkControl'; | |
[...document.getElementsByClassName('js-double_submit')].forEach((form) => { | |
if (form.dataset.type === 'default') { | |
const formControl = new FormControl(form); | |
formControl.initNoStrict(); | |
} else { | |
const formControl = new FormControl(form); | |
formControl.init(); | |
} | |
}); | |
const linkSelector = [ | |
'.js-double_click_link:not([target="_blank"])', | |
'.breadcrumb-section a', | |
'.pagenation-init a', | |
'a[href*="sort:"]', | |
]; | |
[...document.querySelectorAll(linkSelector.join(', '))].forEach((link) => { | |
const linkControl = new LinkControl(link); | |
linkControl.initNoStrict(); | |
}); |
This file contains hidden or 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
export class FormControl { | |
constructor(form) { | |
this.form = form; | |
this.hiddenInput = null; | |
this.shouldSubmit = true; | |
} | |
/** | |
*緩めの2重クリック対策 | |
*/ | |
initNoStrict() { | |
this.attachNoStrictSubmitEvent(); | |
} | |
attachNoStrictSubmitEvent() { | |
this.form.addEventListener('submit', (e) => { | |
if (e.currentTarget.dataset.submitted) { | |
e.preventDefault(); | |
e.stopPropagation(); | |
if (process.env.NODE_ENV !== 'production') { | |
console.log('緩めの2重クリック対策が有効です'); | |
} | |
return; | |
} | |
e.currentTarget.dataset.submitted = 'true'; | |
}); | |
} | |
/** | |
* 強固な2重クリック対策 | |
*/ | |
init() { | |
this.attachClickSubmitEvent(); | |
this.attachSubmitEvent(); | |
} | |
querySubmitInput() { | |
return [...this.form.querySelectorAll('[type="submit"]')]; | |
} | |
saveSubmitInput(submitInput) { | |
const hiddenInput = document.createElement('input'); | |
hiddenInput.type = 'hidden'; | |
hiddenInput.name = submitInput.name; | |
hiddenInput.value = submitInput.value; | |
this.hiddenInput = hiddenInput; | |
} | |
generateSubmitInput() { | |
this.form.appendChild(this.hiddenInput); | |
} | |
attachClickSubmitEvent() { | |
this.querySubmitInput().forEach((input) => { | |
input.addEventListener('click', (e) => { | |
this.clickSubmitHandler(e); | |
}); | |
}); | |
} | |
clickSubmitHandler(e) { | |
const inputSubmit = e.currentTarget; | |
this.saveSubmitInput(inputSubmit); | |
} | |
attachSubmitEvent() { | |
this.form.addEventListener('submit', (e) => { | |
this.submitHandler(e); | |
}); | |
} | |
submitHandler(e) { | |
e.preventDefault(); | |
e.stopPropagation(); | |
if (this.shouldSubmit) { | |
const submitInputs = this.querySubmitInput(); | |
if (this.hiddenInput === null && submitInputs.length !== 0) { | |
this.saveSubmitInput(submitInputs[0]); | |
} | |
this.generateSubmitInput(); | |
this.form.submit(); | |
} else if (process.env.NODE_ENV !== 'production') { | |
console.log('強固な2重クリック対策が有効です'); | |
} | |
this.shouldSubmit = false; | |
} | |
} |
This file contains hidden or 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
export class LinkControl { | |
constructor(link) { | |
this.link = link; | |
} | |
/** | |
*緩めの2重クリック対策 | |
*/ | |
initNoStrict() { | |
this.attachSubmitEvent(); | |
} | |
notDoubleClick() { | |
this.link.prop('disabled', false); | |
this.link.on('click', () => { | |
setTimeout(() => { | |
this.link.prop('disabled', true); | |
}, 0); | |
}); | |
} | |
attachSubmitEvent() { | |
this.link.addEventListener('click', (e) => { | |
if (e.currentTarget.dataset.clicked) { | |
e.preventDefault(); | |
e.stopPropagation(); | |
if (process.env.NODE_ENV !== 'production') { | |
console.log('2重クリック対策が有効です'); | |
} | |
return; | |
} | |
e.currentTarget.dataset.clicked = 'true'; | |
}); | |
this.link.addEventListener('beforeunload', (e) => {}); | |
this.link.addEventListener('unload', (e) => {}); | |
if (typeof window.onpageshow !== 'undefined') { | |
this.link.onpageshow = function() { | |
this.notDoubleClick(); | |
}; | |
} else { | |
this.link.onload = function() { | |
this.notDoubleClick(); | |
}; | |
window.onunload = function() {}; | |
} | |
this.link.addEventListener('pagehide', (e) => { | |
if (e.currentTarget.dataset.clicked) { | |
setTimeout(() => { | |
e.currentTarget.dataset.clicked = 'false'; | |
}, 0); | |
} | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment