Skip to content

程序思维训练

星星评分

思路:

  • 准备对应的dom,图片分为激活和未激活的部分
  • 事件:
    • 鼠标移动:将当前元素之前的元素激活,之后的元素未激活
    • 鼠标移出:恢复所有元素未激活
    • 鼠标点击:记录当前点击的数,设置激活。

使用while循环来循环激活目标元素前的所有dom

html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .left {
            float: left;
            margin-left: 10px;
            line-height: 30px;
        }
    </style>
</head>

<body>
    <div id="divstars" class="left">
        <img src="images/empty.png" alt="">
        <img src="images/empty.png" alt="">
        <img src="images/empty.png" alt="">
        <img src="images/empty.png" alt="">
        <img src="images/empty.png" alt="">
    </div>
    <div id="divword" class="left">

    </div>

    <script>
        var words = ["满意", "一般满意", "还不错", "很满意", "非常满意"];
        var divstars = document.getElementById("divstars");
        var divword = document.getElementById("divword");
        var star = -1; //记录评分,点击的是第几个星星
        divstars.onmouseover = function(e) {
            if (e.target.tagName === "IMG") {
                e.target.src = "images/shining.png";
                //处理之前的
                var prev = e.target.previousElementSibling;
                while (prev) {
                    prev.src = "images/shining.png";
                    prev = prev.previousElementSibling;
                }
                //处理之后的
                var next = e.target.nextElementSibling;
                while (next) {
                    next.src = "images/empty.png";
                    next = next.nextElementSibling;
                }
                //处理文字
                var index = Array.from(divstars.children).indexOf(e.target)
                divword.innerHTML = words[index];
            }
        }

        divstars.onclick = function(e) {
            if (e.target.tagName === "IMG") {
                star = Array.from(divstars.children).indexOf(e.target);
            }
        }

        divstars.onmouseleave = function() {
            divword.innerHTML = words[star] || "";
            for (var i = 0; i < divstars.children.length; i++) {
                if (i <= star) {
                    divstars.children[i].src = "images/shining.png";
                } else {
                    divstars.children[i].src = "images/empty.png";
                }
            }
        }
    </script>
</body>

</html>

放大镜

思路:

准备两张图,一个正常,一个放大,通过正常计算出放大图背景的位置即可

  • 创建两个区域,正常区域和放大区域
  • 移动元素:通过比例计算出移动元素的宽高
  • 鼠标移动时,移动元素跟随鼠标且处于鼠标最中心,要做边界判断
  • 大图放大的区域的距离=正常图中移动元素的left/正常图的宽度 * 放大区域的宽度(通过比例计算
  • 设置放大图片的background-position即可。
html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .small{
            width: 350px;
            height: 350px;
            border: 1px solid #ccc;
            float: left;
            background-clip: padding-box;
            position: relative;
        }
        .big{
            width: 540px;
            height: 540px;
            border:1px solid #ccc;
            float: left;
            margin-left: 10px;
            background-clip: padding-box;
            display: none;
        }

        .small .move{
            position: absolute;
            background: rgba(200,200,50,0.5);
            border: 1px solid #999;
            box-sizing: border-box;
            cursor: move;
            display: none;
        }
    </style>
</head>
<body>
    <div class="small">
        <div class="move"></div>
    </div>
    <div class="big"></div>

    <script src="index.js"></script>
</body>
</html>
js


/**
 * 初始化
 */
(function () {
    //配置
    var config = {
        smallBg: "images/mouse.jpg", // 小图背景路径
        bigBg: "images/mouseBigSize.jpg", //大图背景路径
        divBig: document.querySelector(".big"), //大图div dom元素
        divSmall: document.querySelector(".small"), //小图div dom元素
        divMove: document.querySelector(".small .move"), //可移动的div
        smallImgSize: { //小图尺寸
            width: 350,
            height: 350
        },
        divBigSize: { //大的div的尺寸
            width: 540,
            height: 540
        },
        bigImgSize: { //大图尺寸
            width: 800,
            height: 800
        }
    };
    //计算可移动的div的宽高
    config.moveSize = {
        width: config.divBigSize.width / config.bigImgSize.width * config.smallImgSize.width,
        height: config.divBigSize.height / config.bigImgSize.height * config.smallImgSize.height,
    };

    initDivBg();
    initMoveDiv();
    initDivSmallEvent();

    /**
     * 初始化div背景
     */
    function initDivBg() {
        config.divSmall.style.background = `url("${config.smallBg}") no-repeat left top/100% 100%`;
        config.divBig.style.background = `url("${config.bigBg}") no-repeat`;
    }

    /**
     * 初始化可移动的div
     */
    function initMoveDiv() {
        config.divMove.style.width = config.moveSize.width + "px";
        config.divMove.style.height = config.moveSize.height + "px";
    }

    /**
     * 初始化小图div的鼠标事件
     */
    function initDivSmallEvent() {
        config.divSmall.onmouseenter = function () {
            config.divMove.style.display = "block";
            config.divBig.style.display = "block";
        }
        config.divSmall.onmouseleave = function () {
            config.divMove.style.display = "none";
            config.divBig.style.display = "none";
        }

        config.divSmall.onmousemove = function (e) {
            var offset = getOffset(e);
            setPosition(offset);
            setBigBgPosition();
        }

        /**
         * 设置大图背景图位置
         */
        function setBigBgPosition() {
            var style = getComputedStyle(config.divMove);
            var left = parseFloat(style.left);
            var top = parseFloat(style.top);

            var bgLeft = left / config.smallImgSize.width * config.bigImgSize.width;
            var bgTop = top / config.smallImgSize.height * config.bigImgSize.height;
            config.divBig.style.backgroundPosition = `-${bgLeft}px -${bgTop}px`;
        }

        /**
         * 根据鼠标坐标,设置divMove的坐标
         * @param {*} offset 
         */
        function setPosition(offset) {
            var left = offset.x - config.moveSize.width / 2;
            var top = offset.y - config.moveSize.height / 2;
            if (left < 0) {
                left = 0;
            }
            if (top < 0) {
                top = 0;
            }
            if (left > config.smallImgSize.width - config.moveSize.width) {
                left = config.smallImgSize.width - config.moveSize.width;
            }
            if (top > config.smallImgSize.height - config.moveSize.height) {
                top = config.smallImgSize.height - config.moveSize.height;
            }
            config.divMove.style.left = left + "px";
            config.divMove.style.top = top + "px";
        }

        /**
         * 根据鼠标事件参数,得到鼠标在divsmall中的坐标
         * @param {MouseEvent} e 
         */
        function getOffset(e) {
            if (e.target === config.divSmall) {
                return {
                    x: e.offsetX,
                    y: e.offsetY
                }
            }
            else {
                //事件源是divMove
                var style = getComputedStyle(config.divMove);
                var left = parseFloat(style.left);
                var top = parseFloat(style.top);
                return {
                    x: e.offsetX + left + 1, //加1是因为边框
                    y: e.offsetY + top + 1
                }
            }
        }
    }
}())

MIT License