事件机制(事件流、事件委托、事件类型)

news2024/11/25 1:04:24

HTML DOM 允许 JavaScript 对 HTML 事件作出反应。JavaScript 能够在事件发生时执行,比如当用户点击某个 HTML 元素时。 JavaScript与HTML之间的交互是通过事件实现的。事件就是文档或浏览器窗口中发生的一些特定的交互瞬间。

目录

事件是由三部分组成

执行事件的步骤

常用事件:

事件流

事件冒泡(IE事件流)

阻止事件冒泡        event.stopPropagation()

事件捕获(Netscape事件流)

DOM事件流

Dom0级事件和2级事件

阻止事件默认行为        preventDefault()

事件委托

事件类型

用户界面事件--UIEvent

焦点事件--FocusEvent

鼠标事件--MouseEvent

键盘事件--KeyboardEvent

页面跳转        

 对话框


事件是由三部分组成

事件源、事件类型、事件处理程序,我们也称为事件三要素。

1.事件源:事件被触发的对象 -->按钮对象

2.事件类型:如何触发?触发什么事件?例如鼠标点击,键盘按下等…

3.事件处理程序:通过一个函数赋值的方式

执行事件的步骤

1.获取事件源

2.注册事件(绑定事件)

3.采用函数赋值形式添加事件处理程序

常用事件:

  • 当用户点击鼠标时

  • 当网页加载后

  • 当图像加载后

  • 当鼠标移至元素上时

  • 当输入字段被改变时

  • 当 HTML 表单被提交时

  • 当用户敲击按键时

  • ....................

事件流

事件冒泡(IE事件流)

IE 事件流被称为事件冒泡,这是因为事件被定义为从最具体的元素(文档树中最深的节点)开始触发,然后向上传播至没有那么具体的元素(文档)。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .outer{
            width: 300px;
            height: 300px;
            background-color: red;
            margin: 0 auto;
            padding: 50px;
            box-sizing: border-box;
        }
        .center{
            width: 200px;
            height: 200px;
            background-color: pink;
            padding: 50px;
            box-sizing: border-box;
        }
        .inner{
            width: 100px;
            height: 100px;
            background-image: linear-gradient(to right,red,pink,blue);
        }
    </style>
    <script>
        window.onload = function(){
            var outer = document.querySelector('.outer');
            var center = document.querySelector('.center');
            var inner = document.querySelector('.inner');
            outer.onclick = function(){
                console.log('我是outer');
                // alert('我是outer');
                console.log(event.target,'触发事件的目标源');
                console.log(event.currentTarget,'当前正在执行事件的dom元素');
            }
            center.onclick = function(){
                console.log('我是center');
                // alert('我是center');
                // event.stopPropagation();
                console.log(event.target,'触发事件的目标源');
                console.log(event.currentTarget,'当前正在执行事件的dom元素');
            }
            inner.onclick = function(){
                console.log('我是inner');
                // alert('我是inner');
                // 阻止事件冒泡 event表示当前的事件对象
                // console.log(event,'事件对象');
                // event.stopPropagation()
                console.log(event.target,'触发事件的目标源');
                console.log(event.currentTarget,'当前正在执行事件的dom元素');
            }
        }
    </script>
</head>
<body>
    <!-- 事件三要素   1.事件源   2.事件类型  3.事件处理程序 -->
    <!-- 事件流 描述的是页面接受事件的顺序 事件冒泡:事件由内向外触发 事件捕获:事件由外向内触发 事件流机制:事件捕获 --到达目标 --事件冒泡 -->
    <div class="outer">
        <div class="center">
            <div class="inner"></div>
        </div>
    </div>
</body>
</html>

 在点击页面中的id为inner的div元素,click事件会以如下顺序发生

div#inner-----div#center-----div#outer-----body-----html-----document

也就是说,div#inner元素,即被点击的元素,最先触发 click 事件。然后,click 事件沿DOM 树一路向上,在经过的每个节点上依次触发,直至到达 document 对象。

阻止事件冒泡        event.stopPropagation()

事件捕获(Netscape事件流)

Netscape Communicator 团队提出了另一种名为事件捕获的事件流。事件捕获的意思是最不具体的节点应该最先收到事件,而最具体的节点应该最后收到事件。事件捕获实际上是为了在事件到达最终目标前拦截事件。如果前面的例子使用事件捕获,则点击div元素会以下列顺序触发 click 事件:document-----html ----- body ----- div

在事件捕获中,click 事件首先由 document 元素捕获,然后沿 DOM 树依次向下传播,直至到达实际的目标元素div。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .outer{
            width: 300px;
            height: 300px;
            background-image: radial-gradient(red,pink,blue);
            margin: 0 auto;
            padding: 50px;
            box-sizing: border-box;
        }
        .center{
            width: 200px;
            height: 200px;
            background-color: red;
            padding: 50px;
            box-sizing: border-box;
        }
        .inner{
            width: 100px;
            height: 100px;
            background-color: blue;
        }
    </style>
    <script>
        window.onload = function(){
            var outer = document.querySelector('.outer');
            var center = document.querySelector('.center');
            var inner = document.querySelector('.inner');
            function hander1(){
                console.log('outer');
            }
            function hander2(){
                console.log('center');
            }
            function hander3(){
                console.log('inner');
            }
            /**
             * false表示事件在冒泡阶段执行
             * true 表示事件在捕获阶段执行
            */
            outer.addEventListener('click',hander1,true);
            center.addEventListener('click',hander2,true);
            inner.addEventListener('click',hander3,true);

        }
    </script>
</head>
<body>
    <div class="outer">
        <div class="center">
            <div class="inner"></div>
        </div>
    </div>
</body>
</html>

 

DOM事件流

DOM2 Events 规范规定事件流分为 3 个阶段:事件捕获、到达目标和事件冒泡。事件捕获最先发生,为提前拦截事件提供了可能。然后,实际的目标元素接收到事件。最后一个阶段是冒泡,最迟要在这个阶段响应事件。点击div元素会以如图所示的顺序触发事件。

 

在 DOM 事件流中,实际的目标(div元素)在捕获阶段不会接收到事件。这是因为捕获阶段从document 到html再到body就结束了。下一阶段,即会在div元素上触发事件的“到达目标”阶段,通常在事件处理时被认为是冒泡阶段的一部分。然后,冒泡阶段开始,事件反向传播至文档。大多数支持 DOM 事件流的浏览器实现了一个小小的拓展。虽然 DOM2 Events 规范明确捕获阶段不命中事件目标,但现代浏览器都会在捕获阶段在事件目标上触发事件。最终结果是在事件目标上有两个机会来处理事件。

Dom0级事件和2级事件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        window.onload = function(){
            var btn = document.querySelector('button');
            // dom 0级事件绑定 on事件类型
            btn.onclick = function(){
                console.log(this);
            }
            // 追加事件
            btn.onclick = function(){
                console.log('第二次事件触发');
            }
            // 结果看出不可追加同一类型的事件
            // dom 0级事件解绑
            btn.onclick = null;
            
            // dom 2级事件绑定 addEventListener() 参数: 事件类型 事件处理程序 true捕获/false默认冒泡
            // btn.addEventListener('click',function(){
            //     console.log(this);
            // })
            // // 追加事件
            // btn.addEventListener('click',function(){
            //     console.log('第二次事件触发');
            // })
            var handler1 = function(){
                console.log(this);
            }
            var handler2 = function(){
                console.log('第二次事件触发');
            }
            btn.addEventListener('click',handler1);
            btn.addEventListener('click',handler2);
            // 结果看出可以追加同一类型的事件
            // dom 2级事件解绑 removeEventListener() 参数: 事件类型 事件处理程序
            // btn.removeEventListener('click',handler1);
        }   
    </script>
    
</head>
<body>
    <button>点击这里</button>
</body>
</html>

dom0级事件

dom2级事件

dom0级和dom2级事件的区别

            1.dom0级使用on关键字绑定和解绑事件,解绑将事件类型设置为null;

            2.dom2级使用addEventListener()绑定事件,解绑使用removeEventListener();

            3.dom0级事件不可追加同一类型事件    追加就是覆盖

            4.dom2级事件可以追加同一类型事件    追加后依次执行

阻止事件默认行为        preventDefault()

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        window.onload = function () {
            var input = document.querySelector('input');
            var a = document.querySelector('a');
            // 阻止默认行为 preventDefault()
            input.onclick = function () {
                event.preventDefault();
            }
            a.onclick = function () {
                event.preventDefault();
            }
        }
    </script>
</head>

<body>
    <form action="text.php">
        <input type="submit" value="提交">
    </form>
    <a href="https://www.baidu.com">百度</a>
</body>

</html>

事件委托

在 JavaScript 中,页面中事件处理程序的数量与页面整体性能直接相关。原因有很多。首先,每个函数都是对象,都占用内存空间,对象越多,性能越差。其次,为指定事件处理程序所需访问 DOM 的次数会先期造成整个页面交互的延迟。只要在使用事件处理程序时多注意一些方法,就可以改善页面性能。

事件委托就是当事件触发时,把要做的事委托给父元素(或父元素的父元素)来处理。也就是:利用冒泡的原理,把事件加到父级上,通过判断事件来源的子集,执行相应的操作。使用事件委托技术能让你避免对特定的每个节点添加事件监听器。

事件委托利用事件冒泡,可以只使用一个事件处理程序来管理一种类型的事件。例如,click 事件冒泡到 document。这意味着可以为整个页面指定一个 onclick 事件处理程序,而不用为每个可点击元素分别指定事件处理程序。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        window.onload = function(){
            var ul = document.querySelector('ul');
            // 在这里加的li可以变色
            // var newLi = document.createElement('li');
            // newLi.innerText = '第11个li';
            // ul.appendChild(newLi);
            // var lis = document.querySelectorAll('li');
            // for(var i=0;i<lis.length;i++){
            //     lis[i].onclick = function(){
            //         this.style.backgroundColor = 'red';
            //     }
            // }
            // 在这里加的li不可变色
            var newLi = document.createElement('li');
            newLi.innerText = '第11个li';
            ul.appendChild(newLi);

            // 事件委托,将子元素事件代理给父元素 绑定依次事件 管理一类事件
            ul.onclick = function(){
                // event 事件对象 event.target
                event.target.style.backgroundColor = 'red';
            }
        }
    </script>
</head>
<body>
    <ul>
        <li>第1个li</li>
        <li>第2个li</li>
        <li>第3个li</li>
        <li>第4个li</li>
        <li>第5个li</li>
        <li>第6个li</li>
        <li>第7个li</li>
        <li>第8个li</li>
        <li>第9个li</li>
        <li>第10个li</li>
    </ul>
</body>
</html>

 事件委托(事件代理)

            利用事件冒泡 只指定一个事件处理程序 就可以管理某一类事件

            将子元素的事件绑定给父元素

            目的:优化页面性能 减少事件的执行 减少浏览器的重排和回流 还可以给新增的元素绑定事件。

事件类型

用户界面事件--UIEvent

焦点事件--FocusEvent

鼠标事件--MouseEvent

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div{
            width: 200px;
            height: 200px;
            border: 1px solid blue;
            overflow: auto;
        }
    </style>
    <script>
        window.onload = function(){
            var input = document.querySelector('input');
            // select事件  在输入框中选择字符时触发
            input.onselect = function(){
                console.log('我被选择了');
                console.log(window.getSelection().toString());
            }

            // resize事件 窗口缩放时触发方法
            document.body.onresize = function(){
                console.log(window.outerHeight,window.outerWidth);
            }

            // scroll事件 绑定滚动事件
            var div = document.querySelector('div');
            div.onscroll = function(){
                console.log('正在滚动');
            }

            // 聚焦focus 失焦blur
            input.onfocus = function(){
                console.log('选中');
            }
            input.onblur = function(){
                console.log('取消选中');
            }

            // 双击 dblclick
            div.ondblclick = function(){
                console.log('被双击');
            }

            // 鼠标移入mouseenter 移除mouseleave 一直移动mousemove
            div.onmouseenter = function(){
                console.log('鼠标移入');
            }
            div.onmouseleave = function(){
                console.log('鼠标移出');
            }
            div.onmousemove = function(){
                console.log('鼠标一直在移动');
            }
        }
    </script>
</head>
<body>
    <div>我是一个div我是一个div我是一个div我是一个div我是一个div我是一个div我是一个div我是一个div
        我是一个div我是一个div我是一个div我是一个div我是一个div我是一个div我是一个div我是一个div我是一个div
        我是一个div我是一个div我是一个div我是一个div我是一个div我是一个div我是一个div我是一个div
    </div>
    <input type="text">
</body>
</html>

键盘事件--KeyboardEvent

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        window.onload = function(){
            var input = document.querySelector('input');
            // 键盘按下事件 keydown 按键keyCode
            input.onkeydown = function(){
                console.log(event.keyCode);
            }
            // 键盘抬起事件 keyup
            input.onkeyup = function(){
                console.log('抬起');
            }
            // 键盘持续按下事件 keyprogress
            input.onkeypress = function(){
                console.log('持续按下');
            }
            // 输入框输入事件 获取文本输入值
            input.addEventListener('textInput',function(event){
                console.log(event.data);
            })

        }
    </script>
</head>
<body>
    <input type="text">
</body>
</html>

页面跳转        

 open 打开页面 参数 url name 可配置对象 true自身打开 false 新窗口打开

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        window.onload = function(){
            var btn1 = document.querySelectorAll('button')[0];
            var btn2 = document.querySelectorAll('button')[1];
            btn1.onclick = function(){
                // open 打开页面 参数 url name 可配置对象 true自身打开 false 新窗口打开
                w = window.open('https://www.baidu.com','_blank','height = 600px,width = 600px');
                // 设置新窗口的宽高 resizeTo()
                w.resizeTo(400,400);
                // 设置新窗口的位置 moveTo()
                w.moveTo(100,100);
            }
            btn2.onclick = function(){
                // 关闭窗口
                w.close();
            }
        }
    </script>
</head>
<body>
    <button>百度页面</button>
    <button>关闭页面</button>
</body>
</html>

 对话框

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        window.onload = function(){
            // 弹框 alert()
            alert('弹框');
            // 确认框 confirm()
            var res = confirm('你确定么?')
            if(res){
                console.log('确定');
            }else{
                console.log('取消');
            }
            // 输入框 prompt()
            var res = prompt('请输入你的姓名');
            console.log(res);
        }
    </script>
</head>
<body>
    
</body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/721346.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

儿童硅胶勺子LFGB标准检测是什么?

食品级硅胶制品的德国食品接触材料测试LFGB标准检测哪些项目&#xff1f; Sensory test感官测试一味道和气味对于与食品接触的整体产品 extractable components in ethanol(Ethanol as compulsory simulant)(must perform)10%酒精萃取法(必做) Extractable component in deioni…

官网能为企业营销增长贡献哪些力量?

官网是门面&#xff0c;同时也具备营销价值&#xff0c;可以带来流量转化成销售线索&#xff0c;影响公司营收&#xff0c;B2B业务是复杂的&#xff0c;客户在选择你之前会长期的研究你的官网&#xff0c;了解你的产品及服务、成功案例、甚至是品牌的创始团队信息&#xff0c;来…

SpringCloud学习1

SpringCloud是分布式微服务架构的 一些列解决方案的集合&#xff0c;SpringBoot是一门单独的技术 ​​​​​​

小心 MybatisPlus 的一个坑与面试题

昨天测试说有个 xx 功能用不了&#xff0c;扔给我一个截图&#xff0c;说有报错&#xff1a; 报错信息就是&#xff1a;Transaction rolled back because it has been marked as rollback-only&#xff0c;很好理解&#xff1a;事务被回滚了&#xff0c;因为它已经被标记了只能…

HttpRunner自动化之请求中带有 headers 的接口和发送POST请求

headers 可通过headers 添加头部信息&#xff0c;如下图 # 发送请求头headers的接口 - config:name: 百度接口用例base_url: https://www.baidu.com- test:name: 发送百度接口的头部信息request:url: /smethod: GETheaders:Accept: text/html,application/xhtmlxml,applicati…

LNMT(linux下nignx+mysql+tomcat(中间件)应用)部署应用、及各服务介绍、部署开源站点jpress

目录 一、环境准备 二、tomcat1和tomcat2服务器&#xff0c;安装配置tomcat 1.tomcat服务器介绍 2.JDK软件介绍 3.查看JDK是否安装 4.tomcat1和tomcat2服务器&#xff0c;安装JDK1.8.0_191&#xff08;JDK必须和nginx版本相适应&#xff0c;不然一直报错&#xff09; 5.安…

【LeetCode】HOT 100(21)

题单介绍&#xff1a; 精选 100 道力扣&#xff08;LeetCode&#xff09;上最热门的题目&#xff0c;适合初识算法与数据结构的新手和想要在短时间内高效提升的人&#xff0c;熟练掌握这 100 道题&#xff0c;你就已经具备了在代码世界通行的基本能力。 目录 题单介绍&#…

源启数据资产管理平台助力金融机构加速数据资产化过程

自2000年左右&#xff0c;金融行业开始做数据管理。从数据仓库到数据治理、数据应用&#xff0c;再到后来的大数据&#xff0c;以及今天的数据管理。我们把这个时期总结成数据资产化时代&#xff0c;或者叫国产化时代。 为什么有两个名字&#xff1f;数据资产化时代是因为国家…

关于PID闭环控制中上位机与下位机通讯代码的解析分享(一)

下位机接收数据代码&#xff08;以STM32单片机为例&#xff09;与上位机发送数据C#代码分享 1、下位机代码&#xff1a; /*** brief 接收的数据处理* param void* return -1&#xff1a;没有找到一个正确的命令.*/ int8_t receiving_process(void) {uint8_t frame_data[…

虚幻引擎程序化资源生成框架PCG 之 常用撒点方法小结

PCG真好玩&#xff0c;门槛很低&#xff0c;天花板很高 文章目录 前言1. 基本撒点1.1 Landscape上撒点1.2 使用射线检测在地表面撒点1.3 使用曲线撒点1.3.1 沿曲线撒点1.3.2 在闭合曲线内部撒点 1.4 在StaticMesh表面撒点 2. 进阶撒点2.1 在闭合曲线内部放射状撒点2.2 在Mesh表…

MedCalc v22.009 医学ROC曲线统计分析软详细图文教程

简介 MedCalc是一款医学 ROC 曲线统计软件&#xff0c;用于ROC曲线分析的参考软件&#xff0c;医学工作者设计的医学计算器&#xff0c;功能齐全。它可以帮助医生快速作出普通的医学计算&#xff0c;从而对症下药。提供超过76种常用的规则和方法&#xff0c;包括&#xff1a;病…

《消失的她》豆瓣短评数据分析

《消失的她》豆瓣短评数据分析 文章目录 《消失的她》豆瓣短评数据分析一、前言二、数据加载和预处理三、探索性数据分析1、查看评论的评价分布2、查看评论点赞数的分布3、查看评论的地理分布 四、情感分析 一、前言 最近爆火的电影《消失的她》你们有没有去看过呢&#xff1f…

开源站点(jpress)部署

第三阶段基础 时 间&#xff1a;2023年7月5日 参加人&#xff1a;全班人员 内 容&#xff1a; 开源站点部署&#xff08;jpress&#xff09; 服务器设置&#xff1b;单台服务器&#xff0c;安装tomcat和mariadb 环境配置&#xff1a; 1、关闭防火墙 systemctl stop fir…

【大数据之Hive】二十、Hive之调优相关配置及Explain查看执行计划

1 Yarn资源配置 需要调整Yarn的参数与CPU、内存等资源有关 &#xff08;1&#xff09;yarn.nodemanager.resource.memory-mb   设置一个NodeManager节点分配给容器Container使用的内存&#xff0c;取决于NodeManager所在节点的总内存容量和该节点运行的其他服务的数量&#x…

搭建高性能数据库集群之二:MySQL读写分离(基于mycat2-1.22)

一、概述 读写分离是常见的一种数据库架构&#xff0c;一般是由 1 主多从构成&#xff0c;特殊场景下也会存在多主多从的架构。 无论哪一种架构&#xff0c;对于应用程序来说都是多个数据源&#xff0c;增加了代码的复杂性。如果配合 mycat&#xff0c;则可以实现屏蔽数据库复…

【C++】深入剖析vector

好久不见~让大家久等啦~ 本期让我们来揭开vector的面纱&#xff0c;看看它底层是怎么实现的~ 目录 一、STL定义vector的源码分析&#xff1a; 二、vector的模拟实现 2.1 vector框架的搭建&#xff08;一些简单功能函数的实现&#xff09; 2.2 迭代器失效问题 2.2.1 实现i…

【Spring】SpringCloud Ribbon中的7种负载均衡策略!

Yan-英杰的主页 悟已往之不谏 知来者之可追 C程序员&#xff0c;2024届电子信息研究生 负载均衡通器常有两种实现手段&#xff0c;一种是服务端负载均衡器&#xff0c;另一种是客户端负载均衡器&#xff0c;而我们今天的主角 Ribbon 就属于后者——客户端负载均衡器。 服务…

个人总结:测试用例万能公式+常见例子(公式的运用)

前言 测试工程师面试的时候&#xff0c;有时候会当场考测试用例&#xff0c;毕竟这是测试工程师的基本功。 对于我来说&#xff0c;让我写测试用例会比让我直接说测试用例更好点。 直接嘴里说出来&#xff0c;容易逻辑混乱&#xff0c;给人一种想到啥说啥的感觉。 其实个人感…

MySQL学习基础篇(九)---子查询

MySQL学习基础篇(九)—子查询 子查询指一个查询语句嵌套在另一个查询语句内部的查询&#xff0c;这个特性从MySQL 4.1开始引入。SQL 中子查询的使用大大增强了 SELECT查询的能力&#xff0c;因为很多时候查询需要从结果集中获取数据&#xff0c;或者需要从同一个表中先计算得出…

MySQL安装与部署

第一种方法&#xff1a;在线安装 配置一个安装yum源 Adding the MySQL Yum Repository 可以手动配置yum源&#xff0c;baseurl指向国内镜像源地址&#xff0c;比如清华、中科大。 Installing MySQL Starting the MySQL Server&#xff1a; 查询临时登录密码 修改数据库密码…