前言
1、版本一的樣式比較齊全;
2、版本二的JS邏輯和功能效果比較完善,且是別人的代碼,后續(xù)會(huì)對(duì)樣式進(jìn)行完善。[Gitee | 嗶哩嗶哩];
3、兩個(gè)版本各有千秋,主要學(xué)習(xí)里面的一些技巧,這里主要介紹版本一的樣式技巧;
4、行為驗(yàn)證碼一般是后端實(shí)現(xiàn),而且大概率是使用第三方插件,因?yàn)樯婕暗降倪壿嫼蛢?nèi)容比較多,前后端實(shí)現(xiàn)起來(lái)都比較麻煩。
版本一(html+JS+css)
案例公共樣式
body {
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
案例一(clip-path裁剪的應(yīng)用)
<style>
.clip_path {
width: 300px;
height: 300px;
background-color: #ff0000;
}
.clip_path:first-child {
float: left;
background-color: #0000ff;
clip-path: inset(50px 20px 30px 40px round 10px);
}
</style>
<div>
<div class="clip_path"></div>
<div class="clip_path"></div>
</div>
案例一解析
代碼塊中包含兩個(gè)<div>元素,每個(gè)元素都有類(lèi)名為clip_path。此外,還有一些CSS樣式被應(yīng)用于這些元素。
CSS樣式部分
1、clip_path類(lèi)指定了一個(gè)固定的寬度(300像素)、高度(300像素)和背景顏色(紅色)的區(qū)域。
2、clip_path:first-child選擇器用于選擇第一個(gè)具有類(lèi)名clip_path的元素,并對(duì)其應(yīng)用特定樣式。
2.1、float: left;
將第一個(gè)元素左浮動(dòng),使其在其右側(cè)的元素之前顯示。
2.2、background-color: #0000ff;
將第一個(gè)元素的背景顏色更改為藍(lán)色。
2.3、clip-path: inset(50px 20px 30px 40px round 10px);
將剪切路徑應(yīng)用于第一個(gè)元素,剪切路徑的形狀是一個(gè)矩形,內(nèi)邊距為50px 20px 30px 40px,并且角是圓形的,半徑為10px。
HTML部分
兩個(gè)<div>元素被包含在一個(gè)外部<div>中。
每個(gè)<div>元素都有類(lèi)名為clip_path,因此它們都受到了相同的CSS樣式的影響。
綜上所述,代碼將顯示兩個(gè)相同大小的紅色方塊,但第一個(gè)方塊的背景顏色為藍(lán)色,并具有一種剪切路徑,使其內(nèi)部形成一個(gè)圓角矩形區(qū)域。
案例一效果圖
案例二(clamp最大值最小值的應(yīng)用)
<style>
.clamp {
width: clamp(300px, 50vw, 600px);
height: 300px;
background-color: #ff0000;
}
</style>
<div class="clamp"></div>
案例二解析
一段簡(jiǎn)單的HTML和CSS代碼段,用于創(chuàng)建一個(gè)具有限制寬度的元素。
1、<style>標(biāo)簽用于在HTML文檔中定義CSS樣式。
2、.clamp是一個(gè)CSS類(lèi)選擇器,它用于選擇具有類(lèi)名為"clamp"的HTML元素。
3、width: clamp(300px, 50vw, 600px);
是一個(gè)CSS屬性,它使用clamp()函數(shù)來(lái)設(shè)置元素的寬度。clamp()函數(shù)接受三個(gè)參數(shù),分別是最小寬度、首選寬度和最大寬度。在這個(gè)例子中,元素的寬度將被限制在300像素、視窗寬度的50%和600像素之間,以保證在不同設(shè)備和屏幕尺寸下有不同的大小。
4、height: 300px;
設(shè)置元素的高度為300像素。
5、background-color: #ff0000;
設(shè)置元素的背景顏色為紅色。
<div class=“clamp”></div>是一個(gè)HTML<div>元素,它具有一個(gè)類(lèi)名為"clamp",因此應(yīng)用了上述定義的CSS樣式。這個(gè)<div>元素將具有限制寬度的特性,寬度將根據(jù)視窗寬度和定義的最小和最大寬度進(jìn)行調(diào)整,以便在不同設(shè)備和屏幕尺寸下呈現(xiàn)出不同的大小。
案例二效果圖
功能效果圖
html
<div id="captcha">
<div id="handle">
<span onmousedown="onmousedownFn()" mousemove="mousemoveFn()"></span>
</div>
</div>
JavaScript
const captcha = document.querySelector('#captcha');
const handle = document.querySelector('#handle');
const button = document.querySelector('#handle span');
const oLeft = handle.getBoundingClientRect().left;
const buttonWidth = button.getBoundingClientRect().width;
let flag = false;
function onmousedownFn() {
flag = true;
}
window.addEventListener('mousemove', ({ clientX }) => {
if (flag) {
captcha.style.setProperty('--moved', `${clientX - oLeft - buttonWidth / 2}px`);
}
});
window.addEventListener('mouseup', ({ clientX }) => {
if (flag) {
const dis = clientX - oLeft;
if (dis >= 430 && dis <= 450) {
captcha.classList.add('passed');
alert('驗(yàn)證通過(guò)!');
} else {
captcha.style.setProperty('--moved', '0px');
}
flag = false;
}
});
style
* {
margin: 0;
padding: 0;
}
body {
--width: 400px;
--height: 260px;
--puzzle-width: 80px;
--puzzle-height: 80px;
--moved: 0px;
background-color: #008b8b;
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
#captcha {
width: var(--width);
height: var(--height);
background-image: url('https://cn.bing.com/th?id=OHR.AlmondBloom_ZH-CN9441550492_1920x1080.jpg');
background-size: cover;
background-position: center;
position: relative;
border-radius: 4px;
box-shadow: 0px 2px 4px rgba(0, 0, 0, .3);
}
#captcha::before,
#captcha::after {
display: flex;
position: absolute;
content: '';
width: inherit;
height: inherit;
background-image: inherit;
background-size: inherit;
background-position: inherit;
clip-path: inset( calc((var(--height) - var(--puzzle-height)) / 2) var(--puzzle-width) calc((var(--height) - var(--puzzle-height)) / 2) calc(var(--width) - var(--puzzle-width) * 2));
}
#captcha::after {
transform: translateX(clamp( calc(var(--width) * -1), calc(var(--width) * -1 + var(--moved)), var(--puzzle-width)));
transition: .25s all ease-in-out;
cursor: pointer;
}
#captcha:active::after {
transition: none;
}
#captcha::before {
background-color: rgba(0, 0, 0, .6);
background-blend-mode: multiply;
}
#handle {
height: 30px;
width: calc(var(--width) + var(--puzzle-width) * 2);
border-radius: 18px;
background-color: #eeeeee;
box-shadow: inset 0 0 12px rgba(0, 0, 0, .2);
border: 3px solid #eeeeee;
position: absolute;
bottom: -50px;
left: calc(var(--puzzle-width) * 2 * -1);
}
#handle span {
width: var(--puzzle-width);
height: inherit;
display: block;
border-radius: inherit;
background-color: #fff;
box-shadow: 0 0 6px rgba(0, 0, 0, .25), 0 2px 4px rgba(0, 0, 0, .3);
cursor: move;
transform: translateX( clamp( 0px, var(--moved), calc(var(--width) + var(--puzzle-width))));
cursor: pointer;
transition: .25s all ease-in-out;
}
#captcha:active #handle span {
transition: none;
}
#captcha.passed::before,
#captcha.passed::after,
#captcha.passed #handle {
opacity: 0;
}
版本二(html+JS+css+canvas)
效果圖
html
<div class="container">
<div id="captcha" style="position: relative;"></div>
<div id="msg"></div>
</div>
<script src="./indexV2.js"></script>
<script>
captcha.init(document.getElementById('captcha'), function() {
document.getElementById('msg').innerHTML = '驗(yàn)證成功';
setTimeout(() => {
document.getElementById('msg').innerHTML = '';
}, 2000);
}, function() {
document.getElementById('msg').innerHTML = '驗(yàn)證失敗';
setTimeout(() => {
document.getElementById('msg').innerHTML = '';
}, 1000);
})
</script>
JavaScript文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-854317.html
(function(win) {
// 滑塊邊長(zhǎng)
let l = 42,
// 滑塊半徑
r = 10,
// canvas寬度
w = 310,
//canvas高度
h = 155,
PI = Math.PI;
// 滑塊的實(shí)際邊長(zhǎng)
const ll = l + r * 2;
// 獲取指定區(qū)間內(nèi)的隨機(jī)數(shù)
function getRandomNumberByRange(start, end) {
return Math.round(Math.random() * (end - start) + start);
}
// 創(chuàng)建元素
function createElement(tagName) {
return document.createElement(tagName);
}
// 創(chuàng)建畫(huà)布
function createCanvas(width, height) {
const canvas = createElement('canvas');
canvas.width = width;
canvas.height = height;
return canvas;
}
// 獲取隨機(jī)圖片
function getRandomImg() {
// 這個(gè)網(wǎng)站可以生成隨機(jī)圖片
return 'https://picsum.photos/300/150/?image=' + getRandomNumberByRange(0, 100);
}
// 創(chuàng)建圖片
function createImg(onload) {
const img = createElement('img');
img.crossOrigin = 'Anonymous';
img.onload = onload;
img.onerror = () => {
img.src = getRandomImg();
}
img.src = getRandomImg();
return img;
}
// 添加樣式
function addClass(tag, className) {
tag.classList.add(className);
}
// 移除樣式
function removeClass(tag, className) {
tag.classList.remove(className);
}
// 繪制
function draw(ctx, operation, x, y) {
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x + l / 2, y);
ctx.arc(x + l / 2, y - r + 2, r, 0, 2 * PI);
ctx.lineTo(x + l / 2, y);
ctx.lineTo(x + l, y);
ctx.lineTo(x + l, y + l / 2);
ctx.arc(x + l + r - 2, y + l / 2, r, 0, 2 * PI);
ctx.lineTo(x + l, y + l / 2);
ctx.lineTo(x + l, y + l);
ctx.lineTo(x, y + l);
ctx.lineTo(x, y);
ctx.fillStyle = '#fff';
ctx[operation]();
ctx.beginPath();
ctx.arc(x, y + l / 2, r, 1.5 * PI, 0.5 * PI);
ctx.globalCompositeOperation = 'xor';
ctx.fill();
}
// 求和
function sum(x, y) {
return x + y;
}
// 求平方
function square(x) {
return x * x;
}
// 驗(yàn)證碼類(lèi)
class captcha {
// 構(gòu)造器
constructor(el, success, fail) {
this.el = el;
this.success = success;
this.fail = fail;
}
// 初始化
init() {
this.initDOM();
this.initImg();
this.draw();
this.bindEvents();
}
// 初始化DOM
initDOM() {
const canvas = createCanvas(w, h),
block = canvas.cloneNode(true),
sliderContainer = createElement('div'),
sliderMask = createElement('div'),
slider = createElement('div'),
refreshIcon = createElement('div'),
sliderIcon = createElement('span'),
text = createElement('span');
block.className = 'block';
sliderContainer.className = 'slider-container';
sliderMask.className = 'slider-mask';
slider.className = 'slider';
refreshIcon.className = 'refresh-icon';
sliderIcon.className = 'slider-icon';
text.className = 'slider-text';
text.innerHTML = '向右滑動(dòng)滑塊填充拼圖';
const el = this.el;
el.appendChild(canvas);
el.appendChild(refreshIcon);
el.appendChild(block);
slider.appendChild(sliderIcon);
sliderMask.appendChild(slider);
sliderContainer.appendChild(sliderMask);
sliderContainer.appendChild(text);
el.appendChild(sliderContainer);
Object.assign(this, {
canvas,
block,
sliderContainer,
refreshIcon,
slider,
sliderMask,
sliderIcon,
text,
canvasCtx: canvas.getContext('2d'),
blockCtx: block.getContext('2d')
});
}
// 初始化圖像
initImg() {
const img = createImg(() => {
this.canvasCtx.drawImage(img, 0, 0, w, h);
this.blockCtx.drawImage(img, 0, 0, w, h);
const y = this.y - r * 2 + 2;
const imageData = this.blockCtx.getImageData(this.x, y, ll, ll);
this.block.width = ll;
this.blockCtx.putImageData(imageData, 0, y);
});
this.img = img;
}
// 繪畫(huà)
draw() {
this.x = getRandomNumberByRange(ll + 10, w - (ll + 10));
this.y = getRandomNumberByRange(10 + r * 2, h - (ll + 10));
draw(this.canvasCtx, 'fill', this.x, this.y);
draw(this.blockCtx, 'clip', this.x, this.y);
}
// 清除
clean() {
this.canvasCtx.clearRect(0, 0, w, h);
this.blockCtx.clearRect(0, 0, w, h);
this.block.width = w;
}
// 綁定事件
bindEvents() {
this.el.onselectstart = () => false;
this.refreshIcon.onclick = () => {
this.reset();
}
let originX, originY, trail = [],
isMouseDown = false;
this.slider.addEventListener('mousedown', function(e) {
originX = e.x;
originY = e.y;
isMouseDown = true;
});
document.addEventListener('mousemove', (e) => {
if (!isMouseDown) return false;
const moveX = e.x - originX;
const moveY = e.y - originY;
if (moveX < 0 || moveX + 38 >= w) return false;
this.slider.style.left = moveX + 'px';
var blockLeft = (w - 40 - 20) / (w - 40) * moveX;
this.block.style.left = blockLeft + 'px';
addClass(this.sliderContainer, 'slider-container-active');
this.sliderMask.style.width = moveX + 'px';
trail.push(moveY);
});
document.addEventListener('mouseup', (e) => {
if (!isMouseDown) return false;
isMouseDown = false;
if (e.x == originX) return false;
removeClass(this.sliderContainer, 'slider-container-active');
this.trail = trail;
const spliced = this.verify();
if (spliced) {
addClass(this.sliderContainer, 'slider-container-success');
this.success && this.success();
} else {
addClass(this.sliderContainer, 'slider-container-fail');
this.fail && this.fail();
setTimeout(() => {
this.reset();
}, 1000);
}
});
}
// 重置
reset() {
this.sliderContainer.className = 'slider-container';
this.slider.style.left = 0;
this.block.style.left = 0;
this.sliderMask.style.width = 0;
this.clean();
this.img.src = getRandomImg();
this.draw();
}
// 驗(yàn)證
verify() {
const left = parseInt(this.block.style.left);
//10表示容錯(cuò)率,值越小,需要拼得越精確
return Math.abs(left - this.x) < 10;
}
}
win.captcha = {
init: function(element, success, fail) {
new captcha(element, success, fail).init();
}
}
}(window));
style文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-854317.html
* {
margin: 0;
padding: 0;
background-color: #333333;
}
body {
/* 方便演示,滿(mǎn)屏居中 */
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
/* 小拼圖 */
.block {
position: absolute;
left: 0;
top: 0;
}
/* 滑動(dòng)條 */
.slider-container {
position: relative;
text-align: center;
width: 310px;
height: 40px;
line-height: 40px;
margin-top: 15px;
background-color: #f7f9fa;
color: #45454c;
border: 1px solid #e4e7eb;
}
.slider-mask {
position: absolute;
left: 0;
top: 0;
height: 40px;
border: 0px solid #1991fa;
background-color: #d1e9fe;
}
.slider {
position: absolute;
left: 0;
top: 0;
width: 40px;
height: 40px;
background: #fff;
box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);
cursor: pointer;
transition: background 0.2s linear;
}
.slider-icon {
position: absolute;
left: 13px;
top: 15px;
width: 14px;
height: 10px;
background: url(/images/icon_light.png) 0 -26px;
background-size: 34px 471px;
}
/* 滑動(dòng)條活動(dòng)態(tài) */
.slider-container-active .slider {
height: 38px;
top: -1px;
border: 1px solid #1991fa;
}
.slider-container-active .slider-mask {
height: 38px;
border-width: 1px;
}
/* 滑動(dòng)條成功態(tài) */
.slider-container-success .slider {
height: 38px;
top: -1px;
border: 1px solid #52ccba;
background-color: #52ccba !important;
}
.slider-container-success .slider-mask {
height: 38px;
border: 1px solid #52ccba;
background-color: #d2f4ef;
}
/* 成功圖標(biāo) */
.slider-container-success .slider-icon {
background-position: 0 0 !important;
}
/* 滑動(dòng)條失敗態(tài) */
.slider-container-fail .slider {
height: 38px;
top: -1px;
border: 1px solid #f57a7a;
background-color: #f57a7a !important;
}
.slider-container-fail .slider-mask {
height: 38px;
border: 1px solid #f57a7a;
background-color: #fce1e1;
}
/* 失敗圖標(biāo) */
.slider-container-fail .slider-icon {
background-position: 0 -83px !important;
}
.slider-container-active .slider-text,
.slider-container-success .slider-text,
.slider-container-fail .slider-text {
display: none;
}
.slider:hover {
background: #1991fa;
}
.slider:hover .slider-icon {
background-position: 0 -13px;
}
.refresh-icon {
position: absolute;
right: 0;
top: 0;
width: 34px;
height: 34px;
background: url(/images/icon_light.png) 0 -437px;
background-size: 34px 471px;
cursor: pointer;
}
#msg {
height: 20px;
line-height: 20px;
text-align: center;
margin-top: 15px;
}
到了這里,關(guān)于web前端之行為驗(yàn)證碼、不同設(shè)備和屏幕尺寸呈現(xiàn)不同大小、元素寬度根據(jù)視口寬度進(jìn)行調(diào)整、元素或圖片裁剪、圖片驗(yàn)證碼的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!