7月6日笔记

1.单复选
代码演示:

点击查看代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>文字获得焦点 + 一键全选</title>
    <style>
        /* ----- 核心:文字获得焦点样式 ----- */
        .option-group label {
            display: inline-block;
            margin: 8px 16px 8px 0;
            padding: 6px 10px;
            border-radius: 4px;
            cursor: pointer;
            font-size: 16px;
            transition: all 0.2s;
        }

        /* 当内部的 input 获得焦点时,文字变色加粗 */
        .option-group label:focus-within {
            color: #0066ff;
            font-weight: bold;
            background-color: #f0f7ff;
        }

        /* 输入框聚焦时的辅助样式(可选) */
        .option-group input:focus {
            outline: 2px solid #0066ff;
            outline-offset: 2px;
        }

        /* ----- 页面布局 ----- */
        body {
            font-family: system-ui, sans-serif;
            padding: 40px;
            background: #f9f9f9;
        }
        .container {
            background: white;
            padding: 30px;
            border-radius: 12px;
            box-shadow: 0 2px 8px rgba(0,0,0,0.05);
            max-width: 550px;
        }
        hr {
            margin: 20px 0;
            border: 0;
            border-top: 1px solid #eee;
        }
        .hint {
            margin-top: 20px;
            color: #888;
            font-size: 14px;
        }
        kbd {
            background: #eee;
            padding: 0 6px;
            border-radius: 3px;
            font-size: 13px;
        }
        /* 全选行样式 */
        .select-all-row {
            margin-bottom: 12px;
            padding: 6px 0;
            border-bottom: 1px dashed #ddd;
        }
        .select-all-row label {
            font-weight: 600;
            color: #333;
        }
    </style>
</head>
<body>
    <div class="container">
        <h3>点击文字或按 Tab 键聚焦</h3>

        <!-- ===== 单选组 ===== -->
        <div class="option-group">
            <p><strong>单选:</strong></p>
            <label>
                <input type="radio" name="gender" value="男"> 男
            </label>
            <label>
                <input type="radio" name="gender" value="女"> 女
            </label>
        </div>

        <hr>

        <!-- ===== 复选框组(带全选) ===== -->
        <div class="option-group">
            <p><strong>复选框:</strong></p>

            <!-- 全选控制行 -->
            <div class="select-all-row">
                <label>
                    <input type="checkbox" id="selectAll"> ✅ 全选
                </label>
            </div>

            <!-- 各爱好选项 -->
            <label>
                <input type="checkbox" class="hobby" value="读书"> 读书
            </label>
            <label>
                <input type="checkbox" class="hobby" value="运动"> 运动
            </label>
            <label>
                <input type="checkbox" class="hobby" value="音乐"> 音乐
            </label>
            <label>
                <input type="checkbox" class="hobby" value="旅行"> 旅行
            </label>
        </div>

        <div class="hint">
            ✅ 点击文字或按 <kbd>Tab</kbd> 键,聚焦的文字会变蓝加粗。<br>
            ✅ 勾选“全选”可一键控制所有爱好。
        </div>
    </div>

    <script>
        (function() {
            const selectAll = document.getElementById('selectAll');
            const hobbyCheckboxes = document.querySelectorAll('.hobby');

            // 更新全选状态(根据子项同步)
            function updateSelectAll() {
                const allChecked = Array.from(hobbyCheckboxes).every(cb => cb.checked);
                selectAll.checked = allChecked;
            }

            // 全选复选框变化时,同步所有子项
            selectAll.addEventListener('change', function() {
                hobbyCheckboxes.forEach(cb => {
                    cb.checked = selectAll.checked;
                });
                // 手动触发一次更新(其实已经一致,但为了保险)
                updateSelectAll();
            });

            // 每个子项变化时,更新全选状态
            hobbyCheckboxes.forEach(cb => {
                cb.addEventListener('change', updateSelectAll);
            });

            // 初始同步一次
            updateSelectAll();
        })();
    </script>
</body>
</html>

效果图:

屏幕截图 2026-07-09 085458

2.flex弹性布局

代码演示:

点击查看代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Flex 弹性布局 · 交互式演示</title>
    <style>
        /* ----- 全局样式 ----- */
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Segoe UI', Roboto, system-ui, sans-serif;
            background: #f0f5fb;
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            padding: 2rem 1rem;
        }

        .container {
            max-width: 1100px;
            width: 100%;
            background: #ffffff;
            border-radius: 2rem;
            box-shadow: 0 25px 60px rgba(0, 0, 0, 0.07);
            padding: 2rem 2rem 2.5rem;
        }

        h1 {
            font-weight: 600;
            font-size: 1.8rem;
            color: #0b1e2e;
            margin-bottom: 0.2rem;
        }

        .sub {
            color: #647a8f;
            font-size: 0.95rem;
            margin-bottom: 1.8rem;
            border-left: 4px solid #b6ccdf;
            padding-left: 1rem;
        }

        /* ----- 演示区域 ----- */
        .demo-area {
            background: #fafdff;
            border-radius: 1.2rem;
            border: 1px solid #e4edf6;
            padding: 1.5rem;
            margin-bottom: 1.8rem;
        }

        /* Flex 容器 */
        .flex-container {
            display: flex;
            background: #eef3f9;
            border-radius: 0.8rem;
            padding: 1rem;
            min-height: 220px;
            gap: 0.6rem;
            transition: all 0.25s ease;
            border: 2px dashed #b6ccdf;
            flex-wrap: nowrap; /* 默认,由控制覆盖 */
            align-content: stretch;
        }

        .flex-item {
            background: #1f3a5f;
            color: #fff;
            font-weight: 500;
            border-radius: 0.6rem;
            padding: 0.8rem 0.5rem;
            text-align: center;
            min-width: 50px;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: all 0.25s ease;
            font-size: 0.9rem;
            flex: 0 1 auto; /* 默认由控制覆盖 */
        }

        .flex-item:nth-child(1) { background: #2a5a7a; }
        .flex-item:nth-child(2) { background: #3d7ca3; }
        .flex-item:nth-child(3) { background: #5b9abf; }
        .flex-item:nth-child(4) { background: #7fb4d4; }
        .flex-item:nth-child(5) { background: #a8cce3; color: #1a2b3e; }

        /* ----- 控制面板 ----- */
        .controls {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
            gap: 1rem 1.5rem;
            background: #f8fafc;
            padding: 1.2rem 1.5rem;
            border-radius: 1.2rem;
            border: 1px solid #e4edf6;
            margin-top: 0.5rem;
        }

        .control-group {
            display: flex;
            flex-direction: column;
            gap: 0.3rem;
        }

        .control-group label {
            font-size: 0.75rem;
            font-weight: 600;
            text-transform: uppercase;
            letter-spacing: 0.5px;
            color: #4f657c;
        }

        .control-group select,
        .control-group input[type="range"] {
            padding: 0.3rem 0.5rem;
            border-radius: 0.5rem;
            border: 1px solid #d0dce8;
            background: #fff;
            font-size: 0.85rem;
            cursor: pointer;
            outline: none;
        }

        .control-group select:focus,
        .control-group input:focus {
            border-color: #1f3a5f;
        }

        .control-group .value-indicator {
            font-size: 0.8rem;
            color: #1f3a5f;
            font-weight: 500;
            margin-top: 0.1rem;
        }

        .control-group input[type="range"] {
            width: 100%;
        }

        /* 项目单独控制 */
        .item-controls {
            margin-top: 1.2rem;
            display: flex;
            flex-wrap: wrap;
            gap: 0.8rem 1.5rem;
            background: #ffffff;
            padding: 1rem 1.2rem;
            border-radius: 0.8rem;
            border: 1px solid #e4edf6;
        }

        .item-controls .control-group {
            flex: 1 0 150px;
        }

        .item-controls .control-group select {
            background: #f9fcff;
        }

        .badge {
            display: inline-block;
            background: #dce8f2;
            padding: 0.1rem 0.6rem;
            border-radius: 20px;
            font-size: 0.7rem;
            color: #1f3a5f;
            font-weight: 600;
        }

        /* 响应式 */
        @media (max-width: 700px) {
            .container { padding: 1.2rem; }
            .controls { grid-template-columns: 1fr 1fr; }
            .item-controls { flex-direction: column; }
        }
        @media (max-width: 480px) {
            .controls { grid-template-columns: 1fr; }
        }
    </style>
</head>
<body>
<div class="container">
    <h1>🧩 Flex 弹性布局 · 交互演示</h1>
    <div class="sub">调整下方属性,实时观察 Flex 容器和项目的变化</div>

    <!-- Flex 容器展示 -->
    <div class="demo-area">
        <div class="flex-container" id="flexContainer">
            <div class="flex-item" id="item1">1</div>
            <div class="flex-item" id="item2">2</div>
            <div class="flex-item" id="item3">3</div>
            <div class="flex-item" id="item4">4</div>
            <div class="flex-item" id="item5">5</div>
        </div>
    </div>

    <!-- 容器控制面板 -->
    <div class="controls" id="containerControls">
        <div class="control-group">
            <label>flex-direction</label>
            <select id="flexDirection">
                <option value="row">row</option>
                <option value="row-reverse">row-reverse</option>
                <option value="column">column</option>
                <option value="column-reverse">column-reverse</option>
            </select>
        </div>
        <div class="control-group">
            <label>flex-wrap</label>
            <select id="flexWrap">
                <option value="nowrap">nowrap</option>
                <option value="wrap">wrap</option>
                <option value="wrap-reverse">wrap-reverse</option>
            </select>
        </div>
        <div class="control-group">
            <label>justify-content</label>
            <select id="justifyContent">
                <option value="flex-start">flex-start</option>
                <option value="flex-end">flex-end</option>
                <option value="center">center</option>
                <option value="space-between">space-between</option>
                <option value="space-around">space-around</option>
                <option value="space-evenly">space-evenly</option>
            </select>
        </div>
        <div class="control-group">
            <label>align-items</label>
            <select id="alignItems">
                <option value="stretch">stretch</option>
                <option value="flex-start">flex-start</option>
                <option value="flex-end">flex-end</option>
                <option value="center">center</option>
                <option value="baseline">baseline</option>
            </select>
        </div>
        <div class="control-group">
            <label>align-content</label>
            <select id="alignContent">
                <option value="stretch">stretch</option>
                <option value="flex-start">flex-start</option>
                <option value="flex-end">flex-end</option>
                <option value="center">center</option>
                <option value="space-between">space-between</option>
                <option value="space-around">space-around</option>
            </select>
        </div>
        <div class="control-group">
            <label>gap (间距) <span id="gapValue">0.6rem</span></label>
            <input type="range" id="gapSlider" min="0" max="2" step="0.1" value="0.6" />
        </div>
    </div>

    <!-- 项目单独控制 -->
    <div class="item-controls">
        <div class="control-group">
            <label>项目 1 flex-grow</label>
            <select id="grow1">
                <option value="0">0</option>
                <option value="1">1</option>
                <option value="2">2</option>
                <option value="3">3</option>
            </select>
        </div>
        <div class="control-group">
            <label>项目 2 flex-grow</label>
            <select id="grow2">
                <option value="0">0</option>
                <option value="1" selected>1</option>
                <option value="2">2</option>
                <option value="3">3</option>
            </select>
        </div>
        <div class="control-group">
            <label>项目 3 flex-grow</label>
            <select id="grow3">
                <option value="0">0</option>
                <option value="1">1</option>
                <option value="2" selected>2</option>
                <option value="3">3</option>
            </select>
        </div>
        <div class="control-group">
            <label>项目 4 flex-grow</label>
            <select id="grow4">
                <option value="0">0</option>
                <option value="1">1</option>
                <option value="2">2</option>
                <option value="3">3</option>
            </select>
        </div>
        <div class="control-group">
            <label>项目 5 flex-grow</label>
            <select id="grow5">
                <option value="0">0</option>
                <option value="1">1</option>
                <option value="2">2</option>
                <option value="3">3</option>
            </select>
        </div>
        <div class="control-group">
            <label><span class="badge">align-self</span> 项目 3</label>
            <select id="alignSelf3">
                <option value="auto">auto</option>
                <option value="flex-start">flex-start</option>
                <option value="flex-end">flex-end</option>
                <option value="center">center</option>
                <option value="baseline">baseline</option>
                <option value="stretch">stretch</option>
            </select>
        </div>
    </div>

    <div style="margin-top: 1.5rem; font-size: 0.85rem; color: #5c738a; text-align: center; border-top: 1px solid #e4edf6; padding-top: 1rem;">
        💡 提示:调整容器属性影响所有子项,项目 flex-grow 控制剩余空间分配,align-self 单独覆盖 align-items。
    </div>
</div>

<script>
    (function() {
        const container = document.getElementById('flexContainer');

        // ----- 容器控制元素 -----
        const flexDirection = document.getElementById('flexDirection');
        const flexWrap = document.getElementById('flexWrap');
        const justifyContent = document.getElementById('justifyContent');
        const alignItems = document.getElementById('alignItems');
        const alignContent = document.getElementById('alignContent');
        const gapSlider = document.getElementById('gapSlider');
        const gapValue = document.getElementById('gapValue');

        // ----- 项目控制元素 -----
        const grow1 = document.getElementById('grow1');
        const grow2 = document.getElementById('grow2');
        const grow3 = document.getElementById('grow3');
        const grow4 = document.getElementById('grow4');
        const grow5 = document.getElementById('grow5');
        const alignSelf3 = document.getElementById('alignSelf3');

        // 获取所有项目
        const items = [
            document.getElementById('item1'),
            document.getElementById('item2'),
            document.getElementById('item3'),
            document.getElementById('item4'),
            document.getElementById('item5')
        ];
        const growSelectors = [grow1, grow2, grow3, grow4, grow5];

        // ----- 更新容器样式 -----
        function updateContainer() {
            container.style.flexDirection = flexDirection.value;
            container.style.flexWrap = flexWrap.value;
            container.style.justifyContent = justifyContent.value;
            container.style.alignItems = alignItems.value;
            container.style.alignContent = alignContent.value;
            const gap = parseFloat(gapSlider.value);
            container.style.gap = gap + 'rem';
            gapValue.textContent = gap.toFixed(1) + 'rem';
        }

        // ----- 更新项目样式 -----
        function updateItems() {
            // 设置 flex-grow
            items.forEach((item, index) => {
                const val = parseInt(growSelectors[index].value, 10);
                item.style.flexGrow = val;
                // 保留 flex-shrink 和 flex-basis 默认
                // 为了效果,我们设置 flex-basis: auto,让 grow 起作用
                item.style.flexBasis = 'auto';
                // 重置 flex 简写,避免冲突
                item.style.flex = `${val} 1 auto`;
            });

            // 单独设置项目3的 align-self
            const selfVal = alignSelf3.value;
            items[2].style.alignSelf = selfVal;
        }

        // ----- 绑定事件 -----
        function bindControls() {
            const containerControls = [
                flexDirection, flexWrap, justifyContent,
                alignItems, alignContent, gapSlider
            ];
            containerControls.forEach(el => {
                el.addEventListener('change', updateContainer);
                el.addEventListener('input', updateContainer); // 支持滑块实时
            });

            const itemControls = [...growSelectors, alignSelf3];
            itemControls.forEach(el => {
                el.addEventListener('change', updateItems);
            });

            // 额外:容器属性变化时也要重新应用项目样式(因为可能影响布局)
            // 但项目样式独立,所以分别调用
            // 初始更新
            updateContainer();
            updateItems();

            // 当容器属性变化时,项目样式不变,但可能因为容器尺寸变化而影响,但项目样式依然独立
            // 所以不需要额外联动
        }

        bindControls();
    })();
</script>
</body>
</html>

效果图:

屏幕截图 2026-07-09 085906

posted @ 2026-07-09 08:59  createcoding  阅读(37)  评论(0)    收藏  举报