滑块验证码
效果图:
实现思路:
根据滑块的最左侧点跟最右侧点, 是否在规定的距离内【页面最左侧为原点】,来判断是否通过
html代码:
<!DOCTYPE html>
<html>
<head>
<title>滑动图片验证码</title>
<style>
.captcha-container {
position: relative;
width: 300px;
height: 300px;
overflow: hidden;
}
#captcha-image {
position: absolute;
width: 100%;
height: 100%;
background-color: #f2f2f2;
background-image: url('./img/text.png');
background-size: cover;
}
#slider {
position: absolute;
top: 48%;
left: 0;
transform: translateY(-50%);
width: 80px;
height: 80px;
background-color: #007bff;
border-radius: 50%;
cursor: pointer;
z-index: 999;
}
</style>
</head>
<body>
<div class="captcha-container">
<div id="captcha-image"></div>
<div id="slider"></div>
</div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="./js/captcha.js"></script>
</body>
</html>
js代码:
$(document).ready(function() {
var isDragging = false; // 判断是否正在拖动滑块
var slider = $("#slider");
var captchaContainer = $(".captcha-container");
var captchaWidth = captchaContainer.width();
var maxOffset = captchaWidth - slider.width(); // 滑块最大可移动距离
// 鼠标按下触发
slider.mousedown(function(e) {
isDragging = true;
});
// 鼠标移动触发
$(document).mousemove(function(e) {
// 判断是否可以拖动
if (isDragging) {
// e.pageX 是鼠标当前所在位置相对于整个文档(document)左侧的水平位置
// captchaContainer.offset().left 是容器左侧边界相对于文档左侧的水平位置。
var leftOffset = e.pageX - captchaContainer.offset().left;
// console.log(e.pageX,captchaContainer.offset().left)
if (leftOffset >= 0 && leftOffset <= maxOffset) {
slider.css("left", leftOffset);
}
}
});
// 鼠标释放触发
$(document).mouseup(function(e) {
if (isDragging) {
var captchaPassed = false; // 是否通过验证的标志
var leftOffset = e.pageX - captchaContainer.offset().left; // 滑块距离容器左侧距离
if (leftOffset >= 195 && leftOffset <= 280) { //滑块要到达的目标位置
captchaPassed = true;
}
if (captchaPassed) {
// 验证通过,执行你的相关操作
console.log("验证码验证通过!");
} else {
// 验证失败,重置滑块位置
console.log("验证码验证失败!");
slider.animate({ left: 0 }, 200);
}
isDragging = false;
}
});
});
注解:图片需要自己放一张,然后滑块验证的距离通过下面代码规定:
if (leftOffset >= 195 && leftOffset <= 280) { //滑块要到达的目标位置
xxxxxxx
}
补充:
添加一个跟随下拉条移动球体
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.slider-container {
position: relative;
width: 80%;
margin: 50px auto;
}
.slider {
width: 100%;
}
.ball {
width: 20px;
height: 20px;
background-color: red;
border-radius: 50%;
position: absolute;
top: 50px;
/* 设置初始纵向位置 */
left: 0;
/* 初始横向位置,可以根据需要设置 */
}
</style>
</head>
<body>
<div class="slider-container">
<input type="range" min="0" max="100" value="0" class="slider" id="myRange">
<div class="ball"></div>
</div>
<script>
var slider = document.getElementById("myRange");
var ball = document.querySelector('.ball');
slider.oninput = function () {
var value = (slider.value - slider.min) / (slider.max - slider.min);
var position = value * 100;
ball.style.left = position + '%';
};
</script>
</body>
</html>
成语拆解验证
效果图:
实现思路:
第一步:给定一个四字成语,然后拆分,随机绘制到canvas中
第二部:给canvas添加点击事件,并获取点击出的位置,如果跟绘制字的位置差不多,就可以下一步
第三步:判断当前位置的是否已经点击,如何已经点击不做处理,没有点击绘制一个数字序号,并进行存储
第四步:对比用户点击存储的四字与目标四字是否相等即可
html代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>成语验证</title>
<style>
canvas {
border: 1px solid #000;
margin-bottom: 10px;
}
</style>
</head>
<body>
<canvas id="idiomCanvas" width="400" height="100"></canvas>
<button id="checkButton">验证</button>
<button id="resetButton">重置</button>
</body>
</html>
js代码:
<script>
// 获取canvas元素并创建上下文
var canvas = document.getElementById('idiomCanvas');
var ctx = canvas.getContext('2d');
// 设置成语和字符数组
var idiom = '一马当先';
var characters = idiom.split('');
// 随机打乱成语的顺序
shuffleArray(characters);
// 设置每个字符的位置
var characterPositions = [
{ x: 50, y: getRandomInt(30, 60) },
{ x: 130, y: getRandomInt(30, 60) },
{ x: 210, y: getRandomInt(30, 60) },
{ x: 290, y: getRandomInt(30, 60) }
];
// 生成指定范围内随机整数的函数
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// 遍历字符数组,绘制在canvas上
characters.forEach(function (character, index) {
ctx.font = '20px Arial';
ctx.fillText(character, characterPositions[index].x, characterPositions[index].y);
});
// 存储用户点击选择的字的数组
var selectedCharacters = [];
// 下一个要显示的数字序号
var nextNumber = 1;
// 添加点击事件监听器
canvas.addEventListener('click', function (event) {
// 获取点击位置的坐标
var rect = canvas.getBoundingClientRect();
var x = event.clientX - rect.left;
var y = event.clientY - rect.top;
// 判断用户点击的字符,并记录序号
characterPositions.forEach(function (position, index) {
if (x > position.x && x < position.x + 20 && y > position.y - 20 && y < position.y) {
var selectedCharacter = characters[index];
// 查用户是否已经点击过相同的字符 不存在再往下走
if (!selectedCharacters.find(char => char === selectedCharacter)) {
selectedCharacters.push(selectedCharacter);
ctx.font = '16px Arial';
ctx.fillText(nextNumber, position.x, position.y - 5);
nextNumber++;
}
}
});
});
// 点击验证按钮时进行验证
document.getElementById('checkButton').addEventListener('click', function () {
var selectedIdiom = selectedCharacters.join('');
if (selectedIdiom === idiom) {
alert('验证成功!');
} else {
alert('请按顺序点击成语!');
}
});
// 点击重置按钮时重新开始
document.getElementById('resetButton').addEventListener('click', function () {
// 清空画布
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 重新随机打乱成语的顺序
shuffleArray(characters);
// 重新绘制成语
characterPositions.forEach(function (position, index) {
ctx.font = '20px Arial';
ctx.fillText(characters[index], position.x, position.y);
});
// 重置选中的字数组和数字序号
selectedCharacters = [];
nextNumber = 1;
});
// 打乱数组顺序的函数
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
}
</script>
浏览器打印
一开始编写的代码如下:
<!DOCTYPE html>
<html>
<head>
<title>打印页面</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<button id="printButton">打印</button>
<!-- 页面内容 -->
<h1>欢迎打印该页面</h1>
<p>这是要打印的页面内容。</p>
<script>
$(document).ready(function () {
// 点击按钮触发打印事件
$("#printButton").click(function () {
window.print(); // 调用window.print()方法打印页面
});
});
</script>
</body>
</html>
发现这样会打印整个页面的内容,不符合需求:
后来进行改进,打印指定的div下的内容:
新建一个临时页面,然后将指定内容赋值到临时页面进行打印,打印之后再关闭临时页面,这样就不会打印无关的内容了
<!DOCTYPE html>
<html>
<head>
<title>打印页面</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<button id="printButton">打印</button>
<!-- 指定内容 -->
<div id="customDiv">
<h1 style="color: red;">欢迎打印该页面</h1>
<p style="background-color: aqua; font-size: 88px;">这是要打印的页面内容。</p>
</div>
<script>
$(document).ready(function () {
// 点击按钮触发打印事件
$("#printButton").click(function () {
var printContents = $("#customDiv").html(); // 获取要打印的内容
var printWindow = window.open("", "_blank"); // 打开一个新窗口
printWindow.document.write('<html><head>');
printWindow.document.write('<title>打印</title>');
printWindow.document.write('</head><body>');
printWindow.document.write(printContents); // 将要打印的内容写入新窗口
printWindow.document.write('</body></html>');
printWindow.document.close();
printWindow.print(); // 在新窗口中调用 print() 方法打印内容
printWindow.close(); // 关闭新窗口
});
});
</script>
</body>
</html>
但是这样打印,一些样式就无法进行打印了
注解:printWindow.document.close()
是用于关闭在新窗口中打开的文档流
printWindow.document.write()
方法向新窗口的文档流中写入了 HTML 内容。然而,在将内容添加到文档流后,我们需要调用 printWindow.document.close()
来关闭文档流
于是又进行修改,想着能不能对指定内容进行一个截屏,然后将截屏的图片进行打印,这样就可以保留跟打印内容一样的样式了:
<!DOCTYPE html>
<html>
<head>
<title>截屏并打印</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.0/html2canvas.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<div id="customDiv" style="background-color: #f1f1f1; padding: 10px;">
<h2 style="color: red;">要截屏和打印的内容</h2>
<p style="background-color: chocolate;">这是示例文本</p>
</div>
<button id="printButton">截屏并打印</button>
<script>
$(document).ready(function () {
// 点击按钮触发截屏和打印事件
$("#printButton").click(function () {
var targetDiv = document.getElementById("customDiv");
var printWindow = window.open("", "_blank"); // 打开一个新窗口
html2canvas(targetDiv).then(function (canvas) {
var imageData = canvas.toDataURL(); // 获取截图数据
var imageElement = new Image();
imageElement.src = imageData;
printWindow.document.write('<html><head>');
printWindow.document.write('<title>打印</title>');
printWindow.document.write('</head><body>');
printWindow.document.write(imageElement.outerHTML); // 将截图添加到新窗口
printWindow.document.write('</body></html>');
printWindow.document.close();
setTimeout(function () {
printWindow.print(); // 在新窗口中调用 print() 方法打印内容
printWindow.close(); // 关闭新窗口
}, 1000); // 延迟 1 秒等待图像加载完成(可根据需要调整延迟时间)
});
});
});
</script>
</body>
</html>
效果如下:
注解:
引入了 html2canvas
库,它可以将指定元素(这里是 <div>
)转换为 <canvas>
,从而实现截屏功能
当我们点击按钮时,使用 html2canvas
函数将指定 <div>
(在代码中被称为 targetDiv
)转换为 <canvas>
。然后,我们使用 toDataURL()
将 <canvas>
中的图像数据转换为 URL 格式