【JavaScript】使用js实现滑块验证、成语拆解验证功能;浏览器打印功能

滑块验证码

效果图:

实现思路:

根据滑块的最左侧点跟最右侧点, 是否在规定的距离内【页面最左侧为原点】,来判断是否通过

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 格式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

来自湖南的阿晨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值