js-captcha
Version:
Simple captcha component written in pure JavaScript with no dependencies based on canvas element
415 lines (359 loc) • 15.7 kB
HTML
<html lang="en"><head><title>jCaptcha - Simple captcha component written in pure JavaScript with no dependencies</title><meta charset="utf-8"><meta name="description" content="Simple captcha module written in pure JavaScript with no dependencies..."><meta name="robots" content="index, follow"><meta name="viewport" content="width=device-width,initial-scale=1"><link href="https://fonts.googleapis.com/css?family=Yesteryear" rel="stylesheet"><link href="https://www.rvdizajn.com/jpopup/css/jPopup.css" rel="stylesheet"><script async defer="defer" src="https://buttons.github.io/buttons.js"></script></head><style>/*** DEMO only ***/
html {
font-size: 62.5%;
}
html,
body {
margin: 0;
padding: 0;
font-family: Arial, "Helvetica Neue", Helvetica, sans-serif;
color: #ddd;
background-color: #292b2b;
text-align: center;
}
header {
margin: 50px auto 10px auto;
text-align: center;
}
h1 {
font-size: 17px;
margin: 5px auto 15px;
font-weight: normal;
}
h2 {
font-size: 100px;
line-height: 1;
margin: 0 auto;
font-family: 'Yesteryear', cursive, serif;
color: #e8d639;
text-shadow: 3px 5px 2px #1f1f1f;
}
header p {
font-size: 14px;
margin: 18px 20px 0 20px;
line-height: 1.5;
color: #848484;
border-bottom: 1px solid #464646;
display: inline-block;
}
main {
position: absolute;
left: 50%;
top: 50%;
width: 470px;
height: 60px;
margin: -30px 0 0 -235px;
border-radius: 4px;
}
.form {
box-shadow: 2px 4px 2px #1f1f1f;
position: relative;
border-radius: 4px;
}
.jCaptchaCanvas {
position: absolute;
top: -25px;
left: 15px;
}
.jCaptcha {
padding: 20px 25px 20px 20px;
font-size: 15px;
width: 320px;
height: 60px;
box-sizing: border-box;
outline: none;
border-radius: 4px 0 0 4px;
border: none;
vertical-align: middle;
transition: all 150ms linear;
box-shadow: 0 0 8px #4e4706;
}
.jCaptcha:focus,
.jCaptcha:focus~.button {
box-shadow: 0 0 8px #a79816;
}
.jCaptcha.error,
.jCaptcha.error~.button {
box-shadow: 0 0 8px #c5391a;
}
.jCaptcha.error~.button {
background: #c5391a;
color: #fff;
}
.jCaptcha.success,
.jCaptcha.success~.button {
box-shadow: 0 0 8px #93a023;
}
.jCaptcha.success~.button {
background: #b1c317;
color: #fff;
}
.jCaptcha.disabled {
background-color: #eff3f6;
box-shadow: 0 0 8px #4e4706 ;
}
.jCaptcha.disabled~.button {
background: #e2e2e2;
color: #7c7c7c;
box-shadow: 0 0 8px #656565;
cursor: not-allowed;
}
.button {
padding: 21px 0;
width: 150px;
height: 60px;
vertical-align: middle;
box-sizing: border-box;
font-size: 12px;
font-weight: bold;
background: #e8d639;
cursor: pointer;
border: none;
color: #292b2b;
line-height: 1;
text-transform: uppercase;
border-radius: 0 4px 4px 0;
margin-left: -4px;
letter-spacing: 0.5px;
transition: all 150ms linear;
box-shadow: 0 0 8px #4e4706;
outline: none;
}
.button:hover,
.button:focus {
background: #e8d20b;
}
.codeBtn {
display: inline-block;
margin: 15px auto 0 auto;
color: #ddd;
font-size: 15px;
padding: 12px;
text-decoration: underline;
cursor: pointer;
}
.btnWrap {
bottom: 50px;
left: 0;
right: 0;
position: absolute;
}
.jPopup .content {
max-height: 82%;
margin: 40px 10px 0 10px;
text-align: center;
color: #292b2b;
font-family: "Courier New", Courier, "Lucida Sans Typewriter", "Lucida Typewriter", monospace;
overflow: auto;
}
.jPopup .content strong {
font-size: 30px;
display: block;
padding-bottom: 10px;
}
.jPopup .content p {
font-size: 16px;
text-align: left;
display: inline-block;
padding-bottom: 50px;
white-space: nowrap;
}
.jPopup .content span {
font-size: 16px;
text-align: left;
display: block;
padding-bottom: 5px;
color: #999;
font-style: italic;
}
@media screen and (max-width: 540px) {
h2 {
font-size: 60px;
}
header p {
padding-bottom: 7px;
}
main {
position: static;
left: auto;
top: auto;
width: 280px;
margin: 100px auto 100px auto;
height: auto;
}
.jCaptcha {
width: 180px;
height: 50px;
padding: 15px 20px 15px 15px;
}
.btnWrap {
position: static;
left: auto;
right: auto;
bottom: auto;
padding-bottom: 50px;
}
.button {
width: 100px;
height: 50px;
padding: 16px 0;
}
.jPopup .content p,
.jPopup .content span {
font-size: 13px;
}
}</style><body><header><h1>JavaScript Captcha</h1><h2>jCaptcha</h2><p>Tiny captcha component written in pure JavaScript with no dependencies based on canvas element</p></header><main><form class="form" action=""><input class="jCaptcha" type="text" placeholder="Type in result please"> <button class="button" type="submit">Submit</button></form><a class="codeBtn" role="button">View demo source code</a></main><footer class="btnWrap"><a class="github-button" href="https://github.com/robiveli/js-captcha" data-size="large" aria-label="View on GitHub">View on GitHub</a> <a class="github-button" href="https://github.com/robiveli/js-captcha/archive/master.zip" data-icon="octicon-cloud-download" data-size="large" egaaria-label="Download robiveli/jCaptcha on GitHub">Download</a></footer><script src="js/index.min.js"></script><script src="https://www.rvdizajn.com/jpopup/js/jPopup.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/classlist/1.1.20170427/classList.min.js"></script><script>// optionally, set maximum number of captcha validation on event:
const maxNumberOfTries = 5;
// captcha initial setup
var myCaptcha = new jCaptcha({
el: '.jCaptcha',
canvasClass: 'jCaptchaCanvas',
canvasStyle: {
// properties for captcha stylings
width: 100,
height: 15,
textBaseline: 'top',
font: '15px Arial',
textAlign: 'left',
fillStyle: '#ddd'
},
// set callback function
callback: function (response, $captchaInputElement, numberOfTries) {
if (maxNumberOfTries === numberOfTries) {
// maximum attempts reached, so do something
// e.g. disable the form:
document.querySelector('form').removeEventListener('submit', formSubmit);
$captchaInputElement.classList.add('disabled');
$captchaInputElement.placeholder = 'Maximum attempts reached!';
$captchaInputElement.setAttribute('disabled', 'true');
document.querySelector('button').setAttribute('disabled', 'true');
return;
}
if (response == 'success') {
$captchaInputElement.classList.remove('error');
$captchaInputElement.classList.add('success');
$captchaInputElement.placeholder = 'Submit successful!';
// now continue with form submit
}
if (response == 'error') {
$captchaInputElement.classList.remove('success');
$captchaInputElement.classList.add('error');
$captchaInputElement.placeholder = 'Please try again!';
}
}
});
function formSubmit(e) {
e.preventDefault();
// myCaptcha validate
myCaptcha.validate();
};
// validate captcha on form submit event
document.querySelector('form').addEventListener('submit', formSubmit);
// popup setup
document.querySelector('.codeBtn').addEventListener('click', function () {
var jPopupDemo = new jPopup({
content: '<strong>HTML</strong>\
<p>\
<form class="form" action="">\
<br>\
<input class="jCaptcha" type="text" placeholder="Type in result please">\
<br>\
<button type="submit">Submit</button>\
<br>\
</form>\
</p>\
<strong>JavaScript</strong>\
<p>\
<span>// optionally, set maximum number of captcha validation on event:</span>\
const maxNumberOfTries = 5;\
<br>\ <br>\
<span>// captcha initial setup</span>\
var myCaptcha = new jCaptcha({\
<br><br>\
el: ".jCaptcha",\
<br>\
canvas: {\
<br>\
class: "jCaptchaCanvas",\
<br>\
style: {\
<br>\
<span> // properties for captcha stylings:</span>\
width: 100,\
<br>\
height: 15,\
<br>\
textBaseline: "top",\
<br>\
font: "15px Arial",\
<br>\
textAlign: "left",\
<br>\
fillStyle: "#ddd"\
<br>\
}\
<br>\
},\
<br>\
<span> // set callback function</span>\
callback: function(response, $captchaInputElement, numberOfTries) {\
<br><br>\
if (maxNumberOfTries === numberOfTries) {\
<br><br>\
<span> // maximum attempts reached, so do something</span>\
<span> // e.g. disable the form:</span>\
document.querySelector("form").removeEventListener("submit", formSubmit);\
<br>\
$captchaInputElement.classList.add("disabled");\
<br>\
$captchaInputElement.placeholder = "Maximum attempts reached!"";\
<br>\
$captchaInputElement.setAttribute("disabled", "true");\
<br>\
document.querySelector("button").setAttribute("disabled", "true");\
<br><br>\
return;\
<br>\
}\
<br><br>\
if (response == \'success\') {\
<br><br>\
$captchaInputElement[0].classList.remove(\'error\');\
<br>\
$captchaInputElement[0].classList.add(\'success\');\
<br>\
$captchaInputElement[0].placeholder = \'Submit successful!\';\
<br><br>\
<span> // continue with form submit</span>\
<br>\
}\
<br><br>\
if (response == \'error\') {\
<br><br>\
$captchaInputElement[0].classList.remove(\'success\');\
<br>\
$captchaInputElement[0].classList.add(\'error\');\
<br>\
$captchaInputElement[0].placeholder = \'Please try again!\';\
<br>\
}\
<br>\
}\
<br><br>\
});\
<br><br>\
<span>// validate captcha on form submit event</span>\
function formSubmit(e) {\
<br>\
e.preventDefault();\
<br><br>\
<span> // myCaptcha validate</span>\
myCaptcha.validate();\
<br>\
};\
<br>\<br>\
document.querySelector("form").addEventListener("submit", formSubmit);\
<br><br>\
</p>'
});
});</script></body></html>