登 录
注册
Search
标签搜索
技术教程
typecho
JavaScript
成长日记
Joe主题
Typecho主题
前端学习
网站搭建
typecho函数
情感
css
帮助文档
虚拟机
服务器
typecho编辑器
插件
Linux
typecho插件
Windows
Win11
Brains - 灵感乌托邦
累计撰写
79
篇文章
累计收到
4,337
条评论
文章首页
分类栏目
技术教程
Typecho
程序代码
学习笔记
Web前端
CSS
JavaScript
其他文章
生活
独立页面
胡言乱语
生活吐槽
友情链接
网站统计
关于博主
自建图床
自建网盘
博主推荐
灵感宝物库
灵感图床库
Code-Server
在线工具箱
TypechoDoc
在线转换
灵感导航页
登录
丨
注册
JavaScript
(共
12
篇)
搜索到
12
篇与
JavaScript
的结果
『原创』『教程』为你的博客添加阅读模式(适配Joe,其他主题也可用)
> ## 前言 我又来拔flag了,最近立了好多flag,但是最近重庆太热了,不想写文章(其实就是懒了)  既然给小伙伴立了flag,还是要说到做到,不然没有小伙伴来玩了。 这个功能也是xcshare定制的功能,但是我还是分享出来吧 > ## 成果展示  > ## 教程开始 ### 一、添加后台开关 一样的,还是在 `Joe/functions.php` 里添加(也可以在 `Joe/public/custom.php` 里添加,前提是你创建并引用了这个文件) ```php // 是否启用阅读模式 $ReadBook = new Typecho_Widget_Helper_Form_Element_Select( 'ReadBook', array( 'off' => '关闭(默认)', 'on' => '开启'), 'off', '请选择是否启用阅读模式', '介绍:开启后,文章页可以进入阅读模式' ); $ReadBook->setAttribute('class', 'joe_content joe_custom'); //没有joe_custom就改成joe_other $form->addInput($ReadBook->multiMode()); ``` ### 二、添加开关按钮 在 `Joe/public/footer.php` 的 `` 内部添加以下代码 ```php ``` ### 三、添加JS 首先说明,因为我使用的Joe主题自带jQuery框架,如果你是其他主题,请自行引入jQuery或者将以下代码修改为原生js 在 `Joe/assets/js/joe.post_page.min.js` 最后一个 `});` 前加入以下代码 当然你也可以加在`Joe/assets/js/joe.post_page.js`里再使用minify进行压缩 ~~ 如果看过我之前的教程,也可以加在 Joe/assets/css/custom.js 里,再进行压缩 ~~ 隐藏内容,请前往内页查看详情 ### 四、添加按钮css 在 `Joe/assets/css/joe.post.min.css` 里加入以下代码 ~~ 如果看过我之前的教程,也可以加在 Joe/assets/css/custom.scss 里,再用scss to css转换即可 ~~ ```css .joe_action_item.read_book{visibility:hidden;transform:scale(0)}.joe_action_item.read_book.active{visibility:visible;transform:scale(1)}.joe_action_item.read_book svg{transform:scale(0);opacity:0;transition:transform .85s,opacity .85s}.joe_action_item.read_book svg.active{transform:scale(1);opacity:1} ``` > ## 结语 其实教程很简单,就是隐藏一些组件和更换页面底色 **没有固定的方法,只有固定的思维,所以一定要多思考、多变通。**
2022年08月22日
21,549 阅读
42 评论
19 点赞
2022-08-22
『笔记』JavaScript进阶学习笔记 0
> ## 数据类型 ### 1、分类 基本(值)类型 {alert type="info"} - String:任意字符串 - Number:任意的数字 - Boolean:true/false - undefined:undefined - null :null {/alert} 对象(引用)类型 {alert type="info"} - `object` :任意对象 - `function` :函数,一种特别的对象(可以执行) - `array` :数组,一种特别的对象(数值具有下标,内部数据是有序的) {/alert} ### 2、类型的判断 {alert type="success"} - `typeof` :可以判断 undefined/ 数值 / 字符串 / 布尔值Boolean / Function -不能判断 null和object object和array - `instanceof` :判断对象的具体类型 - `===` :全等,可以判断undefined,null {/alert} ```javascript // 1、基本数据类型 var a; // typeof返回数据类型的字符串表达 console.log(a, typeof a, typeof a==="undefined", a===undefined);//undefined "undefined" true true console.log(undefined === 'undefined'); //false a = 3; console.log(typeof a ==='number');//true a = 'abc'; console.log(typeof a ==='string');//true a = true; console.log(typeof a === 'boolean');//true a= null; console.log(typeof a, a===null); //obiect true console.log('--------------------') // 2、对象类型 console.log('对象类型') var b1 ={ b2:[1,'abc',console.log], b3:function(){ console.log('b3'); return function(){ return 'hello'; }; } }; // instanceof判断a(实例对象)是不是b(构造函数)类型的实例 console.log(b1 instanceof Object, b1 instanceof Array); //true false console.log(b1.b2 instanceof Array, b1.b2 instanceof Object); //true true console.log(b1.b3 instanceof Function, b1.b3 instanceof Object); //true true console.log(typeof b1.b2,'flag'); //'object' b1.b2为array(数组)类型 console.log(typeof b1.b3 === 'function'); //true console.log(b1.b2[2] instanceof Function, typeof b1.b2[2] === 'function'); //true true b1.b2[2]('你好'); //'你好' console.log(b1.b3()()); // hello b1.b3(); //可以执行 /*var obj = { name: 'tom', age:12 }; function test() { var a = 3; }; var arr = [3, "abc"]; console.log(arr[1]);*/ // 实例:实例对象 // 类型:类型对象 // 函数是一种特殊的对象(可执行) function Person(name,age){ //构造函数 类型 this.name = name; this.age = age; } var p = new Person('tom',12); //根据类型创建的实例对象 // Person('jack',12); ``` #### 1、undefined与null的区别? - `undefined` 代表定义未赋值 - `null` 代表定义并赋值了,但是值为null #### 2、什么时候给变量赋值为null? - 初始赋值:表明将要赋值为对象 - 结束前:让对象成为垃圾对象(垃圾回收) #### 3、严格区别变量类型与数据类型? (1)数据的类型 - 基本类型 - 对象类型 (2)变量的类型(变量内存值的类型) - 基本类型:保存的基本类型的数据 - 引用类型:保存的是地址值 对象类型即是引用类型 ```javascript var a; console.log(a); //undefined,未赋值 a = null; console.log(a); //null,赋值为null var b = null; //初始赋值为null,表面将要赋值为对象 // 确定对象就可以赋值 b = ['hello',12]; // 最后,为了释放对象内容 b = null; //让b指向的对象成为垃圾对象(被垃圾回收器回收:垃圾回收) // b = 2; //又重新赋值了,没有意义 // c保存的是地址值,即为引用类型 var c = function(){ }; console.log(typeof c) //'function' ``` ## 数据、变量、内存 #### 定义 1、什么是数据 - 存储在内存中代表特点信息的东西,本质上是0101....... - 数据的特点:可传递、可运算 2、什么是内存 - 内存条通电以后产生的可存储数据的空间(临时的) - 内存产生和死亡: `内存条(电路板)==>通电==>产生内存空间==>存储数据==>处理数据==>断电==>内存空间和数据都消失` - 一块小内存的2个数据 `内部存储的数据` `地址值` - 内存分类 `栈:保存全局变量/局部变量(变量名)` `堆:对象(函数、数组)` 3、什么是变量 - 可变化的量:由变量名、变量值组成 - 每个变量都对应一块小内存,变量名用来查找对应的内存,变量值就是内存中保存的数据 4、内存、数据、变量三者之间的关系 - 内存是用来存储数据的空间 - 变量是内存的标识  ```javascript var age = 18; console.log(age) var obj = {name:'tom'}; console.log(obj.name); function fn(){ var obj = {name:'tom'}; }; var a = 3; var b = a + 2; ```
2021年11月22日
6,121 阅读
0 评论
13 点赞
2021-11-22
『笔记』JavaScript基础学习笔记 6
> # DOM(文本对象模型) ###### (20)鼠标拖拽的事件 拖拽(一、二) ```html #box1{ width:100px; height:100px; background-color:red; position:absolute; } #box2{ width:100px; height:100px; background-color:yellow; position:absolute; left:200px; top:200px; } window.onload = function(){ // 拖拽box1 /* 拖拽的流程: 1.当鼠标在被拖拽元素上按下时,开始拖拽 onmousedown 2.当鼠标移动时被拖拽元素跟随鼠标移动 onmousemove 3.当鼠标松开时,被拖拽元素国定在当前位置 onmouseup */ // 获取box1 var box1 = document.getElementById("box1"); // 当鼠标在被拖拽元素上按下时,开始拖拽 box1.onmousedown = function(event){ // 设置box1捕获所有鼠标按下的事件 // setCapture()只有IE支持,Chrome不支持会报错 // 当调用一个元素的setCapture()方法后,这个元素将会把下一次所有的鼠标按下的事件捕获到自身上 /*if(box1.setCapture){ box1.setCapture(); }*/ box1.setCapture && box1.setCapture(); event = event || window.event; // div的水平偏移量:鼠标.clientX - 元素.offsetLeft // div的垂直偏移量:鼠标.clientY - 元素.offsetTop var ol = event.clientX - box1.offsetLeft; var ot = event.clientY - box1.offsetTop; // 为document绑定一个onmousemove事件 document.onmousemove = function(event){ event = event || window.event; // =当鼠标移动时被拖拽元素跟随鼠标移动 // 获取鼠标的坐标 var left = event.clientX - ol; var top = event.clientY - ot; // 修改box1的位置 box1.style.left = left+"px"; box1.style.top = top+"px"; }; // 为元素绑定一个鼠标松开事件 document.onmouseup = function(){ // 当鼠标松开时,被拖拽元素国定在当前位置 // 取消document的onmousemove事件 document.onmousemove = null; // alert("鼠标松开了"); // 取消document的onmouseup事件 document.onmouseup = null; // 当鼠标松开时,取消对事件的捕获 box1.releaseCapture && box1.releaseCapture(); }; // 当拖拽一个网页中的内容,浏览器会默认去搜索页面,会导致拖拽功能的异常,这是浏览器的默认行为 // 如果不希望这个行为发生,则可以通过return false来取消默认行为 // 但是不支持IE8及以下浏览器 return false; }; }; 我是一段文字 ``` box的偏移量=鼠标的偏移量-元素的偏移量  捕获测试 ```html window.onload = function(){ // 分别为两个按钮绑定单击响应函数 var btn01 = document.getElementById("btn01"); var btn01 = document.getElementById("btn01"); btn01.onclick = function(){ alert(1); }; btn02.onclick = function(){ alert(2); }; // 设置btn01对鼠标按下相关的事件进行捕获 // 当调用一个元素的setCapture()方法后,这个元素将会把下一次所有的鼠标按下的事件捕获到自身上 btn01.setCapture(); }; 按钮01 按钮02 ``` 拖拽(三) ```html #box1{ width:100px; height:100px; background-color:red; position:absolute; } #box2{ width:100px; height:100px; background-color:yellow; position:absolute; left:200px; top:200px; } window.onload = function(){ // 拖拽box1 /* 拖拽的流程: 1.当鼠标在被拖拽元素上按下时,开始拖拽 onmousedown 2.当鼠标移动时被拖拽元素跟随鼠标移动 onmousemove 3.当鼠标松开时,被拖拽元素国定在当前位置 onmouseup */ // 获取box1 var box1 = document.getElementById("box1"); // 获取box1 var box1 = document.getElementById("box1"); // 获取imh1 var img1 = document.getElementById("img1"); // 开启box1的拖拽 drag(box1); // 开启box2的拖拽 drag(box2); // 开启img1的拖拽 drag(img1); }; // 提取一个专门用来设置拖拽的函数 // 参数:开启拖拽的元素 function drag(obj){ // 当鼠标在被拖拽元素上按下时,开始拖拽 obj.onmousedown = function(event){ // 设置box1捕获所有鼠标按下的事件 // setCapture()只有IE支持,Chrome不支持会报错 // 当调用一个元素的setCapture()方法后,这个元素将会把下一次所有的鼠标按下的事件捕获到自身上 /*if(box1.setCapture){ box1.setCapture(); }*/ obj.setCapture && obj.setCapture(); event = event || window.event; // div的水平偏移量:鼠标.clientX - 元素.offsetLeft // div的垂直偏移量:鼠标.clientY - 元素.offsetTop var ol = event.clientX - obj.offsetLeft; var ot = event.clientY - obj.offsetTop; // 为document绑定一个onmousemove事件 document.onmousemove = function(event){ event = event || window.event; // =当鼠标移动时被拖拽元素跟随鼠标移动 // 获取鼠标的坐标 var left = event.clientX - ol; var top = event.clientY - ot; // 修改box1的位置 obj.style.left = left+"px"; obj.style.top = top+"px"; }; // 为元素绑定一个鼠标松开事件 document.onmouseup = function(){ // 当鼠标松开时,被拖拽元素国定在当前位置 // 取消document的onmousemove事件 document.onmousemove = null; // alert("鼠标松开了"); // 取消document的onmouseup事件 document.onmouseup = null; // 当鼠标松开时,取消对事件的捕获 obj.releaseCapture && obj.releaseCapture(); }; // 当拖拽一个网页中的内容,浏览器会默认去搜索页面,会导致拖拽功能的异常,这是浏览器的默认行为 // 如果不希望这个行为发生,则可以通过return false来取消默认行为 // 但是不支持IE8及以下浏览器 return false; }; }; 我是一段文字 0 || event.detail < 0){ // alert("向上滚"); // 向上滚box1变短 box1.style.height = box1.clientHeight - 10 + "px"; }else{ // alert("向下滚"); // 向下滚box1变长 box1.style.height = box1.clientHeight + 10 + "px"; } // 使用addEventListener()方法绑定的响应函数,取消默认行为时不能使用return false; // 需要使用event.preventDefault();来取消,不支持IE8及以下浏览器 event.preventDefault && event.preventDefault();//取消火狐的默认行为 // 当滚轮滚动时,如果浏览器有滚动条,浏览器的滚动条会随着滚动 // 这是浏览器默认行为,可以使用return false;取消默认行为 return false; }; // 为火狐绑定滚轮事件 bind(box1,"DOMMouseScroll",box1.onmousewheel) }; function bind(obj,eventStr,callback){ if(obj.addEventListener){ // 大部分浏览器兼容的方式 obj.addEventListener(eventStr,callback,flase); }else{ // this是由调用方式决定 // 可以使用匿名函数调用回调函数,这样就可以指定this // IE8及以下浏览器,加一个on // obj.attachEvent("on"+eventStr,callback); obj.attachEvent("on"+eventStr,function(){ // 在匿名函数中调用回调函数 callback.call(obj); }); } }; ``` ###### (22)键盘的事件 ```html window.onload = function(){ /* 键盘事件 onkeydown 按键被按下,如果一直按着某个按键不松手,事件会一直触发 当onkeydown连续触发时,第一次和第二次之间会间隔稍微长一点,其他的会非常快触发,是为了防止误操作的发生 onkeyup 按键被松开,松开一次触发一次 键盘事件一般都会绑定给一些可以获取到焦点的对象或者document */ document.onkeydown = function(event){ event = event || window.event; // 可以通过keyCode来获取按键的编码,通过它可以判断哪个按键被按下 // 除了keyCode,事件对象中还提供了几个固定属性 /*altKey 按键Alt是否被按下 **ctrlKy 按键Ctrl是否被按下 **shiftKey 按键Shift是否被按下 如果被按下则返回true否则返回false */ // 判断y键是否被按下 // 判断y键和Ctrl键是否被同时按下 if(event.keyCode == 89 && event.ctrlKey){ console.log("按键y和Ctrl都被按下了"); } }; document.onkeyup = function(){ console.log("按键被松开了"); }; // 获取input var input = document.getElementsByTagName("input")[0]; input.onkeydown = function(event){ event = event || window.event; console.log("按键被按下"); // 数字的keycode为48-57 // 使文本框中不能输入数字 if(event.keyCode >= 48 && event.keyCode ``` 键盘移动vid ```html #box1{ width:100px; height:100px; background-color:red; position:absolute; } // 使div可以根据不同的方向键向不同的方向移动 var box1 = document.getElementById("box1"); document.onkeydown = function(event){ event = event || window.event; // 定义一个变量来表示移动的速度 var speed = 20; // 当用户按了Ctrl以后速度加快 if(event.ctrlKey){ spend = 200; } // keyCode 37左 38上 39右 40下 switch(event.keyCode){ case 37: // alert("向左"); box1.style.left = box1.offsetLeft -speed +"px"; break; case 39: // alert("向右"); box1.style.left = box1.offsetLeft +speed +"px"; break; case 38: // alert("向上"); box1.style.top = box1.offsetTop -speed +"px"; break; case 40: // alert("向下"); box1.style.top = box1.offsetTop +speed +"px"; break; } }; ``` {nextPage/} > # BOM(浏览器对象模型) - BOM可以通过JS来操作浏览器 - 在BOM中提供了一组对象,用来完成对浏览器的操作 - BOM对象 {alert type="success"} - `Window` 代表的是整个浏览器的窗口,同时也是网页中的全局对象 - `Navigator` 代表当前浏览器的信息,通过该对象可以识别不同的浏览器 - `Location` 代表当前浏览器的地址栏信息,通过location可以获取地址栏信息或者操作浏览器跳转页面 - `History` 代表浏览器的历史记录,可以通过该对象来操作浏览器的历史记录 - `由于隐私原因,该对象不能获取到具体的历史记录,只能操作浏览器向前或向后翻页,而且该操作只在当次访问有效` - `Screen` 代表用户的屏幕信息,通过该对象可以获取到用户的显示器的相关信息 - 这些BOM对象在浏览器中都是作为window对象的属性保存的 {/alert} ```javascript // console.log(window.navigator); console.log(navigator); console.log(location); console.log(history); ``` #### 一、Navigator(浏览器信息) 代表当前浏览器的信息,通过该对象可以识别不同的浏览器 - 由于历史原因(网景公司倒闭了),Navigator对象中的大部分属性都已经不能识别浏览器了 - 一般只会使用userAgent来判断浏览器的信息 - userAgent是一个字符串,这个字符串包含有用来描述浏览器信息的内容,不同的浏览器会有不同的userAgent ```javascript // appCodeName 返回浏览器名称的代码 // appName 返回浏览器的名称 // userAgent 返回一个字符串来描述浏览器的信息 // alert(navigator.appName); // 在IE11中已经将微软和IE相关的标识都去除了,所以基本不能通过userAgent来识别浏览器是不是IE了 var ua = navigator.userAgent; console.log(ua); if(/firefox/i.test(ua)){ alert("我是火狐"); }else if(/chrome/i.test(ua)){ alert("我是Chrome"); }else if(/msie/i.test(ua)){ alert("我是IE浏览器"); }else if("ActiveXObject" in window){ alert("你是IE11,我已经抓住你了"); } // 如果不能通过userAgent来判断浏览器信息,还可以通过一些浏览器中特有的对象来判断浏览器的信息 // 比如:ActiveXObject // alert("ActiveXObject" in window); if("ActiveXObject" in window){ alert("你是IE,我已经抓住你了"); }else{ alert("你不是IE"); } ``` #### 二、History(历史记录) 代表浏览器的历史记录,可以通过该对象来操作浏览器向前或向后翻页 ```html // 可以通过History来操作浏览器向前或向后翻页 // length属性可以获取到当次访问的连接数量 // alert(history.length); window.onload = function(){ var btn = document.getElementById("btn"); btn.onclick = function(){ // alert(history.length); // back()方法可以用来回退到上一个页面,作用和浏览器的返回按钮一样 // history.back(); // forward()方法可以用来跳转到下一个页面,作用和浏览器的返回按钮一样 // history.forward(); // go()方法可以跳转到指定页面,需要一个整数作为参数 // 1:表示向前跳转一个页面,相当于forward() // 2:表示向前跳转两个页面 // -1:表示向后跳转一个页面,相当于back() // -2:表示向后跳转两个页面 history.go(1); }; }; 点我一下 History 去下一个页面 ``` #### 三、Location(浏览器地址栏) 该对象中封装了浏览器的地址栏的信息 ```html window.onload = function(){ var btn = document.getElementById("btn"); btn.onclick = function(){ // 如果直接打印Location则可以获取到地址栏的信息(当前页面的完整路径) // alert("location"); // 如果直接将location修改为一个完整的路径(或相对路径),则页面会自动跳转到该路径,并且会生成相应的历史记录 // location = "https://www.baidu.com"; // assign()用来跳转到其他页面,作用和直接修改location一样 // location.assign("https://www.baidu.com"); // reload()重新加载当前页面,作用和刷新按钮一样 // 在方法中传递一个true作为参数,则会强制清空缓存刷新 // location.reload(true); // replace()可以使用一个新的页面替换当前页面,调用完毕也会跳转到新的页面,但是不会生成历史记录(不能使用回退功能) location.replace("https://www.baidu.com"); }; }; 点我一下 ``` #### 四、Window(浏览器的窗口) window的方法 ##### 1、 定时调用 ```html window.onload = function(){ var count = document.getElementById("count"); // 使count中的内容自动切换 // js的程序执行速度是非常快的 // 如果希望一段程序可以每间隔一段时间执行一次,可以使用定时调用 /*for(var i=0; i= imgArr.length){ // 则将index设置为0,使其循环切换 index = 0; }*/ // index = index % imgArr.length; index %= imgArr.length; //与上面for循环功能一样 // 修改img1的src属性 img1.src = imgArr[index]; },1000); }; // 为btn02绑定一个单机响应函数 var btn02 = document.getElementById("btn01"); btn02.onclick = function(){ // 点击按钮以后停止图片的自动切换,关闭定时器 // clearInterval()可以接收任意参数,如果参数是一个有效的定时器标识则停止对应的定时器,如果参数不是有效的标识则什么也不做 clearInterval(timer); }; }; 开始 停止 ``` ###### (2)修改div移动练习 ```html #box1{ width: 100px; height: 100px; background-color: red; position: absolute; } //使div可以根据不同的方向键向不同的方向移动 /* * 按左键,div向左移 * 按右键,div向右移 * 。。。 */ window.onload = function(){ //定义一个变量,来表示移动的速度 var speed = 10; //创建一个变量表示方向 //通过修改dir来影响移动的方向 var dir = 0; //开启一个定时器,来控制div的移动 setInterval(function(){ /* * 37 左 * 38 上 * 39 右 * 40 下 */ switch(dir){ case 37: //alert("向左"); left值减小 box1.style.left = box1.offsetLeft - speed + "px"; break; case 39: //alert("向右"); box1.style.left = box1.offsetLeft + speed + "px"; break; case 38: //alert("向上"); box1.style.top = box1.offsetTop - speed + "px"; break; case 40: //alert("向下"); box1.style.top = box1.offsetTop + speed + "px"; break; } },30); //为document绑定一个按键按下的事件 document.onkeydown = function(event){ event = event || window.event; //当用户按了ctrl以后,速度加快 if(event.ctrlKey){ speed = 500; }else{ speed = 10; } //使dir等于按键的值 dir = event.keyCode; }; //当按键松开时,div不再移动 document.onkeyup = function(){ //设置方向为0 dir = 0; }; }; ``` ##### 2、 延时调用 ```html var num = 1; //开启一个定时器 /*setInterval(function(){ console.log(num++); },3000);*/ /*延时调用, * 延时调用一个函数不马上执行,而是隔一段时间以后在执行,而且只会执行一次 * 延时调用和定时调用的区别,定时调用会执行多次,而延时调用只会执行一次 * 延时调用和定时调用实际上是可以互相代替的,在开发中可以根据自己需要去选择*/ var timer = setTimeout(function(){ console.log(num++); },3000); //使用clearTimeout()来关闭一个延时调用 clearTimeout(timer); ``` ###### (1)定时器的应用一 ```html *{ margin: 0; padding: 0; } #box1{ width: 100px; height: 100px; background-color: red; position: absolute; left: 0; } window.onload = function(){ //获取box1 var box1 = document.getElementById("box1"); //获取btn01 var btn01 = document.getElementById("btn01"); //定义一个变量,用来保存定时器的标识 var timer; //点击按钮以后,使box1向右移动(left值增大) btn01.onclick = function(){ //关闭上一个定时器 clearInterval(timer); //开启一个定时器,用来执行动画效果 timer = setInterval(function(){ //获取box1的原来的left值 var oldValue = parseInt(getStyle(box1,"left")); //在旧值的基础上增加 var newValue = oldValue + 1; //判断newValue是否大于800 if(newValue > 800){ newValue = 800; } //将新值设置给box1 box1.style.left = newValue + "px"; //当元素移动到800px时,使其停止执行动画 if(newValue == 800){ //达到目标,关闭定时器 clearInterval(timer); } },30); }; }; /*定义一个函数,用来获取指定元素的当前的样式 * 参数: * obj 要获取样式的元素 * name 要获取的样式名 */ function getStyle(obj , name){ if(window.getComputedStyle){ //正常浏览器的方式,具有getComputedStyle()方法 return getComputedStyle(obj , null)[name]; }else{ //IE8的方式,没有getComputedStyle()方法 return obj.currentStyle[name]; } }; 点击按钮以后box1向右移动 ``` {nextPage/} ###### (2)定时器的应用二 ```html *{ margin: 0; padding: 0; } #box1{ width: 100px; height: 100px; background-color: red; position: absolute; left: 0; } window.onload = function(){ //获取box1 var box1 = document.getElementById("box1"); //获取btn01 var btn01 = document.getElementById("btn01"); //获取btn02 var btn02 = document.getElementById("btn02"); //点击按钮以后,使box1向右移动(left值增大) btn01.onclick = function(){ move(box1 , 800 , 10); }; //点击按钮以后,使box1向左移动(left值减小) btn02.onclick = function(){ move(box1 , 0 , 10); }; }; //定义一个变量,用来保存定时器的标识 var timer; //尝试创建一个可以执行简单动画的函数 /*参数: * obj:要执行动画的对象 * target:执行动画的目标位置 * speed:移动的速度(正数向右移动,负数向左移动) */ function move(obj , target ,speed){ //关闭上一个定时器 clearInterval(timer); //获取元素目前的位置 var current = parseInt(getStyle(obj,"left")); //判断速度的正负值 //如果从0 向 800移动,则speed为正 //如果从800向0移动,则speed为负 if(current > target){ //此时速度应为负值 speed = -speed; } //开启一个定时器,用来执行动画效果 timer = setInterval(function(){ //获取box1的原来的left值 var oldValue = parseInt(getStyle(obj,"left")); //在旧值的基础上增加 var newValue = oldValue + speed; //判断newValue是否大于800 //从800 向 0移动 //向左移动时,需要判断newValue是否小于target //向右移动时,需要判断newValue是否大于target if((speed < 0 && newValue < target) || (speed > 0 && newValue > target)){ newValue = target; } //将新值设置给box1 obj.style.left = newValue + "px"; //当元素移动到0px时,使其停止执行动画 if(newValue == target){ //达到目标,关闭定时器 clearInterval(timer); } },30); } /*定义一个函数,用来获取指定元素的当前的样式 * 参数: * obj 要获取样式的元素 * name 要获取的样式名 */ function getStyle(obj , name){ if(window.getComputedStyle){ //正常浏览器的方式,具有getComputedStyle()方法 return getComputedStyle(obj , null)[name]; }else{ //IE8的方式,没有getComputedStyle()方法 return obj.currentStyle[name]; } }; 点击按钮以后box1向右移动 点击按钮以后box1向左移动 ``` ###### (3)定时器的应用三 ```html *{ margin:0; padding:0; } #box1{ width:100px; height:100px; background:red; position:absolute; left:0; } #box2{ width:100px; height:100px; background:blue; position:absolute; left:0; top:200px; } window.onload = function(){ var box1 = document.getElementById("box1"); var btn01 = document.getElementById("btn01"); var btn02 = document.getElementById("btn02"); // 点击按钮后使box1向右移动(left增大) btn01.onclick = function(){ move(box1,"left",800,20); }; // 点击按钮后使box1向左移动(left减小) btn02.onclick = function(){ move(box1,"left",0,10); }; // 获取btn03 var btn03 = document.getElementById("btn03"); var box2 = document.getElementById("box2"); btn03.onclick = function(){ move(box2,"left",800,10); }; // 获取btn04 var btn04 = document.getElementById("btn04"); var box2 = document.getElementById("box2"); btn04.onclick = function(){ // move(box2,"top",800,10); // move(box2,"height",800,10); move(box2,"width",800,10,function(){ // alert("动画执行完了"); move(box2,"height",400,10,function(){ move(box2,"top",0,10,function(){ move(box2,"width",100,10,function(){ move(box2,"height",100,10,function(){ }); }); }); }); }); }; }; // 定义一个变量用来保存定时器的标识 // 目前定时器由全局变量timer保存,所有正在执行的定时器都在timer变量中保存 // var timer 点击按钮以后box1向右移动 点击按钮以后box1向左移动 点击按钮以后box2向右移动 测试按钮 ``` tools.js(用于存放工具程序) ```javascript // 尝试创建一个可以执行简单动画的函数 // 参数:obj:要执行动画的对象 // attr:要执行动画的样式,比如left height top // target:执行动画的目标位置 // speed:移动的速度(正数向右移动,负数向左移动) // callback:回调函数,将会在动画执行完毕以后执行 function move(obj,attr,target,speed,callback){ // 关闭上一个定时器 clearInterval(obj.timer); // 获取box1目前的位置 var current = parseInt(getStyle(obj,attr)); // 判断速度speed的正负值 // 如果从0向800移动则speed为正,如果从800向0移动则speed为负 if(current > target){ // 此时速度应为负值 speed = -speed; } // 开启一个定时器用来执行动画效果 // 向执行动画的对象中添加一个timer属性,用来保存它自己的定时器的标识 obj.timer = setInterval(function(){ // 获取box1原来的left值 var oldValue = parseInt(getStyle(obj,attr)); // 在旧值的基础上增加,给box添加移动速度 var newValue = oldValue + speed; // 向左移动时需要判断newValue是否小于target // 向右移动时需要判断newValue是否大于于target if((speed < 0 && newValue < target) || (speed > 0 && newValue > target)){ newValue = target; } // 将新值设置给obj obj.style[attr] = newValue + "px"; // 当box1移动到了0px时,使其停止执行动画 if(newValue == target){ // 达到目标关闭定时器 clearInterval(obj.timer); // 动画执行完毕,调用回调函数 callback && callback(); } },30); }; /* 定义一个函数,用来获取指定元素的当前的样式 * 参数: * obj 要获取样式的元素 * name 要获取的样式名*/ function getStyle(obj,name){ if(window.getComputedStyle){ //正常浏览器的方式,具有getComputedStyle()方法 return getComputedStyle(obj,null)[name]; }else{ //IE8的方式,没有getComputedStyle()方法 return obj.currentStyle[name]; } }; ``` {nextPage/} ##### 3、 轮播图的改进 ```html *{ margin:0; padding:0; } #outer{ width:520px; height:333px; margin:50px auto; background-color:greenyellow; padding:10px 0; /* 开启相对定位 */ position:relative; /* 裁剪溢出的内容 */ overflow:hidden; } /* 设置imgList */ #imgList{ /* 去除ul的项目符号 */ list-style:none; /* width:2600px; */ /* 开启绝对定位 */ position:absolute; /* 设置偏移量,默认为0 */ /* 每向左移动520px可以切换下一张图片 */ left:0; } /* 设置列表中li */ #imgList li{ /* 设置浮动 */ float:left; /* 设置左右外边距 */ margin:0 10px; } /* 设置导航按钮 */ #navDiv{ /* 开启绝对定位 */ position:absolute; /* 设置位置 */ bottom:15px; /* 设置居中显示 */ /* left:197px; */ } #navDiv a{ /* 设置超链接的浮动 */ float:left; width:15px; height:15px; background-color:red; /* 设置左右外边距 */ margin:0 5px; /* 设置透明 */ opacity:0.5; /* 兼容IE8透明 */ filter:alpha(opacity=50); } /* 设置鼠标移入的效果 */ #imgDiv a:hover{ background-color:black; } window.onload = function(){ // 获取imgList var imgList = document.getElementById("imgList"); // 获取页面中所有的img标签 var imgArr = document.getElementsByTagName("img"); // 设置imgList的宽度 imgList.style.width = 520*imgArr.length + "px"; // 设置导航按钮居中 // 获取navDiv var navDiv = document.getElementById("navDiv"); // 获取outher var outer = document.getElementById("outer"); // 设置navDiv的left值 navDiv.style.left = (outer.offsetWidth - navDiv.offsetWidth)/2 +"px"; // 默认显示图片的索引 var index = 0; // 获取所有的a var allA = document.getElementsByTagName("a"); // 设置默认选中的效果 allA[index].style.backgroundColor = "black"; // 点击超链接切换到指定的图片 // 为所有的超链接都绑定一个单击响应函数 for(var i=0; i= imgArr.length - 1){ // 则将index设置为0 index = 0; // 此时显示的是最后一张,而最后一张和第一张是一模一样的 // 通过CSS将最后一张切换为第一张 imgList.style.left = 0; } for(var i=0; i ``` {nextPage/} ##### 4、类的操作 ```html .b1{ width:100px; height:100px; background-color:yellowgreen; } .b2{ height:200px; background-color:red; } window.onload = function(){ // 获取box var box = document.getElementById("box"); // 获取btn01 var btn01 = document.getElementById("btn01"); // 为btn01绑定单击响应函数 btn01.onclick = function(){ // 修改box的样式 // 通过style属性来修改元素的样式,每修改一个样式浏览器就需要重新渲染一次 // 这样执行的性能是比较差的,而且这种方式当需要修改多个样式时也比较麻烦 /*box.style.width = "200px"; box.style.height = "200px"; box.style.backgroundColor:"red";*/ // 一行代码可以修改多个样式 // 修改box的class属性 // 可以通过修改元素的class属性来间接修改样式 // 这样只需修改一次即可同时修改多个样式,同时浏览器只需重新渲染一次,性能会提高一些 // 这种方式可以使表现(css)和行为(js)进一步分离 // b2会替换b1的样式 // box.className = "b2"; // 在b1的基础上加上b2的样式(添加一个空格防止b1和b2拼串为b1b2,应为b1 b2) // box.className += " b2" // addClass(box,"b2"); // alert(hasClass(box,"heelo")); // removeClass(box,"b2"); toggleClass(box,"b2"); }; }; // 定义一个函数来向一个元素添加指定的class属性值 /*参数: obj 要添加class属性的元素 cn 要添加的class值*/ function addClass(obj,cn){ // 检查obj中是否含有cn if(!hasClass(obj,cn)){ // 如果没有cn则添加cn(添加一个空格防止直接拼串) obj.className += " "+cn; } }; // 判断一个元素中是否含有指定的class属性值 /*参数 obj 要添加class属性的元素 cn 要添加的class值 如果有该class值则返回true,否则返回false*/ function hasClass(obj,cn){ // 判断obj中是否有cn这个class值 // 创建一个正则表达式 // var reg = /\bb2\b/; var reg = new RegExp("\\b"+cn+"\\b"); return reg.test(obj.className); }; // 删除一个元素中指定的class属性 function removeClass(obj,cn){ // 创建一个正则表达式 var reg = new RegExp("\\b"+cn+"\\b"); // 删除class obj.className = obj.className.replace(reg,""); }; // toggleClass用来切换一个类 // 如果元素中有指定类则删除,没有则添加 function toggleClass(obj,cn){ // 判断obj中是否含有cn if(hasClass(obj,cn)){ // 有则删除 removeClass(obj,cn); }else{ // 没有则添加 addClass(obj,cn); } }; 点击按钮修改box的样式 ``` tools.js(工具函数) ```javascript // 尝试创建一个可以执行简单动画的函数 // 参数:obj:要执行动画的对象 // attr:要执行动画的样式,比如left height top // target:执行动画的目标位置 // speed:移动的速度(正数向右移动,负数向左移动) // callback:回调函数,将会在动画执行完毕以后执行 function move(obj, attr, target, speed, callback) { // 关闭上一个定时器 clearInterval(obj.timer); // 获取box1目前的位置 var current = parseInt(getStyle(obj, attr)); // 判断速度speed的正负值 // 如果从0向800移动则speed为正,如果从800向0移动则speed为负 if (current > target) { // 此时速度应为负值 speed = -speed; } // 开启一个定时器用来执行动画效果 // 向执行动画的对象中添加一个timer属性,用来保存它自己的定时器的标识 obj.timer = setInterval(function () { // 获取box1原来的left值 var oldValue = parseInt(getStyle(obj, attr)); // 在旧值的基础上增加,给box添加移动速度 var newValue = oldValue + speed; // 向左移动时需要判断newValue是否小于target // 向右移动时需要判断newValue是否大于于target if ((speed < 0 && newValue < target) || (speed > 0 && newValue > target)) { newValue = target; } // 将新值设置给obj obj.style[attr] = newValue + "px"; // 当box1移动到了0px时,使其停止执行动画 if (newValue == target) { // 达到目标关闭定时器 clearInterval(obj.timer); // 动画执行完毕,调用回调函数 callback && callback(); } }, 30); }; /* 定义一个函数,用来获取指定元素的当前的样式 * 参数: * obj 要获取样式的元素 * name 要获取的样式名*/ function getStyle(obj, name) { if (window.getComputedStyle) { //正常浏览器的方式,具有getComputedStyle()方法 return getComputedStyle(obj, null)[name]; } else { //IE8的方式,没有getComputedStyle()方法 return obj.currentStyle[name]; } }; // 定义一个函数来向一个元素添加指定的class属性值 /*参数: obj 要添加class属性的元素 cn 要添加的class值*/ function addClass(obj, cn) { // 检查obj中是否含有cn if (!hasClass(obj, cn)) { // 如果没有cn则添加cn(添加一个空格防止直接拼串) obj.className += " " + cn; } }; // 判断一个元素中是否含有指定的class属性值 /*参数 obj 要添加class属性的元素 cn 要添加的class值 如果有该class值则返回true,否则返回false*/ function hasClass(obj, cn) { // 判断obj中是否有cn这个class值 // 创建一个正则表达式 // var reg = /\bb2\b/; var reg = new RegExp("\\b" + cn + "\\b"); return reg.test(obj.className); }; // 删除一个元素中指定的class属性 function removeClass(obj, cn) { // 创建一个正则表达式 var reg = new RegExp("\\b" + cn + "\\b"); // 删除class obj.className = obj.className.replace(reg, ""); }; // toggleClass用来切换一个类 // 如果元素中有指定类则删除,没有则添加 function toggleClass(obj, cn) { // 判断obj中是否含有cn if (hasClass(obj, cn)) { // 有则删除 removeClass(obj, cn); } else { // 没有则添加 addClass(obj, cn); } }; ``` ##### 5、二级菜单完善 ```html 二级菜单 * { margin: 0; padding: 0; list-style-type: none; } a,img { border: 0; text-decoration: none; } body { font: 12px/180%; } window.onload = function () { // 每个菜单都是一个div,当div具有collapsed这个类时,div就是折叠状态,没有则为展开状态 // 点击菜单切换菜单的显示状态 // 获取所以class为menuSpan的元素 var menuSpan = document.querySelectorAll(".menuSpan"); // 定义一个变量来保存当前打开的菜单 var openDiv = menuSpan[0].parentNode; // 为span绑定单击响应函数 for (var i = 0; i < menuSpan.length; i++) { menuSpan[i].onclick = function () { // this代表当前点击的span // 获取span的父元素 var parentDiv = this.parentNode; // 关闭parenDiv,给div添加collapsed值,toggleClass判断div中是否有collapsed,有则删除,无则添加 toggleClass(parentDiv, "collapsed"); // 判断openDiv和parentDiv是否相同 if (openDiv != parentDiv && !hasClass(openDiv,"collapsed")) { // 不相等才添加 // 打开菜单后给之前的菜单添加collapsed来关闭该菜单 // addClass(openDiv, "collapsed"); // 为了统一处理过渡动画,将addClass改为toggleClass // 此处toggleClass()不需要有移除功能 toggleClass(openDiv, "collapsed"); } // 修改openDiv为当前打开的菜单 openDiv = parentDiv; }; } }; 在线工具 图像优化 收藏夹图标生成器 邮件 梯度图像 按钮生成器 支持我们 图像优化 收藏夹图标生成器 邮件 梯度图像 按钮生成器 合作伙伴 图像优化 邮件 梯度图像 按钮生成器 支持我们 图像优化 邮件 梯度图像 按钮生成器 ``` 二级菜单动画过渡 ```html 二级菜单 * { margin: 0; padding: 0; list-style-type: none; } a,img { border: 0; text-decoration: none; } body { font: 12px/180%; } window.onload = function () { // 每个菜单都是一个div,当div具有collapsed这个类时,div就是折叠状态,没有则为展开状态 // 点击菜单切换菜单的显示状态 // 获取所以class为menuSpan的元素 var menuSpan = document.querySelectorAll(".menuSpan"); // 定义一个变量来保存当前打开的菜单 var openDiv = menuSpan[0].parentNode; // 为span绑定单击响应函数 for (var i = 0; i < menuSpan.length; i++) { menuSpan[i].onclick = function () { // this代表当前点击的span // 获取span的父元素 var parentDiv = this.parentNode; // 切换菜单的显示状态 toggleMenu(parentDiv); // 判断openDiv和parentDiv是否相同 if (openDiv != parentDiv && !hasClass(openDiv, "collapsed")) { // 不相等才添加 // 打开菜单后给之前的菜单添加collapsed来关闭该菜单 // addClass(openDiv, "collapsed"); // 为了统一处理过渡动画,将addClass改为toggleClass // 此处toggleClass()不需要有移除功能 // toggleClass(openDiv, "collapsed"); // 切换菜单的显示状态 toggleMenu(openDiv); } // 修改openDiv为当前打开的菜单 openDiv = parentDiv; }; } // 用来切换菜单折叠和显示状态 function toggleMenu(obj) { // 在切换类之前获取元素的高度 var begin = obj.offsetHeight; // 切换parenDiv的显示,给div添加collapsed值,toggleClass判断div中是否有collapsed,有则删除,无则添加 toggleClass(obj, "collapsed"); // 在切换类之后获取一个高度 var end = obj.offsetHeight; // console.log("begin=" + begin + ",end" + end); // 动画效果就是从begin向end过渡 // 将元素的高度充值为begin obj.style.height = begin + "px"; // 执行动画,从begin向end过渡 move(obj, "height", end, 10, function () { // 动画执行完毕,内联样式没有存在的意义,需要删除 obj.style.height = ""; }); }; }; 在线工具 图像优化 收藏夹图标生成器 邮件 梯度图像 按钮生成器 支持我们 图像优化 收藏夹图标生成器 邮件 梯度图像 按钮生成器 合作伙伴 图像优化 邮件 梯度图像 按钮生成器 支持我们 图像优化 邮件 梯度图像 按钮生成器 ``` #### 五、JSON ```javascript // - JS中的对象只有JS认识,其他的语言都不认识 // JSON就是一个特殊格式的字符串,这个字符串可以被任何语言所识别 // 并可以转换为任意语言中的对象,JSON在开发中主要用来进行数据的交互 // JSON // - JavaScript Object Notation JS对象表示法 // - JSON和JS对象的格式一样,只不过JSON字符串中的属性名必须加双引号,其他的和JS语法一样 /* JSON分类: 1、对象{} 2、数组[] JSON中允许的值: 1、字符串 2、数值 3、布尔值 4、null 5、对象 6、数组 */ // 创建一个对象 var obj = '{ "name": "孙悟空", "age": 18, "gender": "男" }'; // 创建一个数组 var arr = '[1,2,3,"hello",true]'; // console.log(obj); var onj2 = '{"arr":[1,2,3]}'; var arr2 = '[{ "name": "孙悟空", "age": 18},{ "name": "孙悟空", "age": 18}]' /* 将JSON字符串转换为JS中的对象 在JS中提供了一个工具类叫做JSON 这个对象可以将JSON转为JS对象,也可以将JS对象转换为JSON */ var json = '{ "name": "孙悟空", "age": 18, "gender": "男" }'; //JSON --> js对象 // JSON.parse()可以将JSON字符串转为JS对象 // 它需要一个JSON字符串作为参数,会将该字符串转换为JS对象 var o = JSON.parse(json); var o2 = JSON.parse(arr); // console.log(o.gender); // console.log(02[1]); var obj3 = {name:"猪八戒",age:28,gender:"男"}; // JS对象 -->JSON // JSON.stringify()可以将一个JS对象转换为JSON字符串 // 需要一个JS对象作为参数,会返回一个JSON字符串 var str = JSON.stringify(obj3); console.log(str); // JSON这个对象在IE7及以下不支持,会报错 // 必须加"",不然会报错 var str3 = '{"name":"孙悟空","age":18,"gender":"男"}'; JSON.parse(str3); ``` JSON的兼容性 ```javascript var str = '{ "name": "孙悟空", "age": 18, "gender": "男" }'; // eval()可以用来执行一段字符串形式的JS代码,并返回执行结果 // 如果使用eval()执行的字符串中含有{},它会将{}当成是代码块 // 如果不希望将其当成代码块解析,则需在字符串前后各加一个() // eval()这个功能很强大,可以直接执行一个字符串中的JS代码 // 但是在开发中尽量不要使用,性能较差,且具有安全隐患(用户也可以传入JS代码) var str2 = "alert('hello')"; // eval(str2); var obj = eval("("+str+")"); // console.log(obj); ```
2021年11月17日
9,252 阅读
0 评论
12 点赞
2021-11-17
『笔记』JavaScript基础学习笔记 5 — DOM(文本对象模型)
> # DOM(文档对象模型) #### 1、DOM的简介 ###### (1)什么是DOM: **DOM:文档对象模型(Document Object Model)**  ###### (2)模型:   ###### (3)节点:  节点的类型  节点的属性  例: ```html 我是一个按钮 /* 浏览器已经提供了文档节点对象,这个对象是window属性 可以在页面直接使用,文档节点代表的是整个网页 */ console.log(document); //获取到button对象 var btn = doucument.getElementById("btn"); //修改按钮的文字 console.log(btn.innerHTML); btn.innerHTML = "I'm Button"; ``` ###### (4)事件(Event) 事件:就是用户和浏览器之间的交互行为  1. 可以在事件对应的属性中设置一些js代码,当事件被触发时,这些代码将会执行 2. onclick 点击一次、ondblclick点击两次 3. 可以为按钮的对应事件绑定处理函数的形式来响应事件,这样当事件被触发时,其对应的函数将会被调用 ```html 我是一个按钮 //获取到button对象 var btn = doucument.getElementById("btn"); //可以为按钮的对应事件绑定处理函数的形式来响应事件 //这样当事件被触发时,其对应的函数将会被调用 //绑定一个单击事件 //为单击事件绑定的函数,称为单击响应函数 btn.onclick = function(){ alert("单击时触发"); }; btn.ondblclick = function(){ alert("双击才会出现"); }; ``` ###### (5)文档的加载 1. 浏览器在加载一个页面时,是按照自上向下的顺序加载的,读取到一行就运行一行 2. 将js代码编写到页面的下部是为了可以在页面加载完毕后再执行js代码 3. onload事件会在整个页面加载完毕后才触发 4. 可以为window绑定一个onload事件,可以确保代码执行时所有的DOM对象都已经加载完毕了 ```html //为window绑定一个onload事件 window.onload = function(){ //获取id为btn的按钮 var btn = document.getElementById("btn"); //为按钮绑定一个单击响应函数 btn.onclick = function(){ alert("hello"); }; }; 点我一下 ``` #### 2、DOM查询 ###### (1)获取元素节点  ```javascript window.onload = function(){ //为id为btn01的按钮绑定一个单击响应函数 var btn01 = document.getElementById("btn01"); btn01.onclick = function(){ var bj = document.getElenmentById("bj"); //打印bj //innerHTML 通过这个属性可以获取到元素内部的html代码 alert(bj.innerHTML); }; //为id为btn01的按钮绑定一个单击响应函数 var btn02 = document.getElementById("btn02"); btn02.onclick = function(){ //查找所以li节点 //getElementsByTagName()可以根据标签名来获取一组元素节点对象 //这个方法会返回一个类数组对象,所有查询到的元素都会封装到对象中 //即使查询到的元素只有一个也会封装到一个对象中 var lis = document.getElenmentsByTagName("li"); //打印lis //alert(lis); //变量lis for(var i=0; i
2021年11月16日
8,094 阅读
0 评论
4 点赞
2021-11-16
『笔记』JavaScript基础学习笔记 4
> ## 内建对象 ### 二、函数的方法 #### 1、 `call()` 和 `apply()` {alert type="success"} - 这两个方法都是函数对象的方法,需要通过函数对象来调用 - 当对函数调用call()和apply()都会调用函数执行 - 在调用call()和apply()可以将一个对象指定为第一个参数,此时这个对象将会成为函数执行时的 `this` - call()方法可以将实参在对象之后依次传递 - apply()方法需要将实参封装到一个数组中统一传递 {/alert} this的情况: {alert type="error"} 1. 以函数形式调用时,this永远都是window 2. 以方法的形式调用时,this是调用方法的对象 3. 以构造函数的形式调用时,this是新创建的那个对象 4. 使用call()和apply()调用时,this是指定的那个对象 {/alert} ```javascript function fun(){ // alert(this.name); console.log("a="+a); console.log("b="+b); } var obj = { name:"obj", sayName:function(){ alert(this.name); } }; // fun.call(); // fun.apply(); // fun(); fun.call(obj,2,2); fun.apply(obj,[2,3]); var obj2 = { name:"obj2" }; fun.call(obj); fun.apply(obj2); // fun(); //this为window obj.sayName.apply(obj2); ``` ### 三、 `arguments` 对象 在调用函数时,浏览器每次都会传递进两个隐含的参数 1. 函数的上下文对象this 2. 封装实参的对象arguments 3. arguments是一个类数组对象,可以通过索引来操作数据,也可以获取长度 4. 在调用函数时,所传递的实参都会在arguments中保存 5. arguments.length可以用来获取实参的长度 6. 即使不定义形参,也可以通过arguments来使用实参 - arguments[0]表示第一个实参 - arguments[1]表示第二个实参。。。。。。 7. arguments里面有一个属性叫做callee,这个属性对应一个函数对象,就是当前正在指向的函数的对象 ```javascript function fun(){ // console.log(arguments instanceof Array); // console.log(Array.isArray(arguments)); // console.log(arguments.length); // console.log(arguments[1]); console.log(arguments.callee); } fun("hello",true); ``` ### 四、 `Date`对象 在JS中使用Date对象来表示一个时间 {alert type="success"} - 如果直接使用构造函数创建一个Date对象,则会封装为当前代码执行的时间 - 创建一个指定的时间对象,需要在构造函数中传递一个表示时间的字符串作为参数 - 日期的格式: `月份/日/年份 时:分:秒` {/alert} {alert type="error"} - getDate() 获取当前日期对象是几日 - getDay() 获取当前日期对象是周几, `会返回0-6的值,0表示周日` - getMonth() 获取当前时间对象的月份, `会返回0-11的值,0表示1月.....11表示12月` - getFullYear() 获取当前时间对象的四位数年份 - getTime() 获取当前日期对象的时间戳 - `时间戳,指的是从格林威治标准时间的1970年1月1日0时0分0秒到当前日期所花费的毫秒数` (1秒=1000毫秒) - 计算机底层在保存时间时使用的都是时间戳 - 可以使用时间戳来测试代码执行的性能 {/alert} ```javascript //创建一个Date对象 var d = new Date(); //创建一个指定的时间对象 var d2 = new Date("12/03/2016 11:10:30") var date = d2.getDate(); var day = d2.getDay(); var month = d2.getMonth(); var year = d2.getFullYear(); var time = d2.getTime(); console.log("date="+date); console.log("day="+day); console.log("month="+month); console.log("year="+year); console.log("time="+time/1000/60/60/24/365); var d3 = new Date("1/1/1970 0:0:0");// 表示东八区北京时间 time = d3.getTime(): console.log(time); //获取当前的时间戳 time = Date.now(); console.log(time); var start = Date.now(); for(var i=0; i
2021年11月10日
3,996 阅读
0 评论
5 点赞
2021-11-10
『笔记』JavaScript基础学习笔记 3
> ## this 解析器(浏览器)在调用函数时每次都会向函数内部传递进一个隐含的参数 #### 1、this的定义 {alert type="success"} - 这个隐含的参数就是this,this指向的是一个对象,这个对象我们称为函数执行的上下文对象 - 根据函数的调用方式的不同,this会指向不同的对象 - 1、 **以函数的形式调用时,this永远都是window** - 2、 **以方法的形式调用时,this就是调用方法的那个对象** {/alert} ```javascript function fun(){ //console.log("a=" +a+",b="+b); console.log(this.name); } fun();//输出object.window //创建一个对象 var obj = { name:"孙悟空", sayName:fun }; var obj2 = { name:"沙和尚", sayName:fun }; //console.log(obj.sayName == fun);//输出true var name = "全局的name属性" obj.sayName();//输出object.object [name:"孙悟空",sayName:fun] //以函数形式调用,this时window fun(); //以方法的形式调用,this是调用方法的对象 obj.sayName(); obj2.sayName(); ``` #### 2、this补充 ```javascript //创建一个name变量 var name = "全局"; //创建一个fun()函数 function fun(){ console.log(this.name); } //创建两个对象 var obj = { name:"孙悟空", sayName:fun }; var obj2 = { name:"沙和尚", sayName:fun }; //调用obj.sayName()时输出obj的名字 obj.sayName();//输出 孙悟空 obj2.sayName();//输出 沙和尚 ``` > ## 对象 #### **1、使用工厂方法创建对象** 可以使用该方法大批量创建对象 使用工厂方法创建的对象使用的构造函数都是Object 所以创建的对象都是Object类型,导致无法区分出多种不同类型的对象 ```javascript function createPerson(name,age,gender){ //创建一个新的对象 var obj = new Object(); //向对象中添加属性 obj.name = name; obj.age = age; obj.gender = gender; obj.sayName = function(){ alert(this.name); } //将新的对象返回 return obj; } var obj2 = createPerson("猪八戒",18,"男"); var obj3 = createPerson("白骨精",17,"女"); var obj4 = createPerson("蜘蛛精",16,"女"); console.log(obj2); console.log(obj3); console.log(obj4); obj2.sayName(); ``` #### **2、构造函数** {alert type="success"} - 构造函数就是一个普通函数,创建方式和普通函数没有区别,不同的是构造函数习惯上首字母大写 - 构造函数和普通函数的区别就是调用的方式不同,普通函数是直接调用, **而构造函数需要使用 `new` 关键字俩调用** - 使用同一个构造函数创建的对象称为一类对象,也将一个构造函数称为一个类 - **将通过一个构造函数创建的对象称为该类的实例** {/alert} **构造函数的执行流程:** {alert type="warning"} 1. 立刻创建一个新的对象 2. 将新建的对象设置为函数中的this 3. 逐行执行函数中的代码 4. 将新建的对象作为返回值返回 {/alert} 使用同一个构造函数创建的对象,称为一类对象,也将构造函数称为一个类 {alert type="success"} - 通过一个构造函数创建的对象,称为该类的实例 {/alert} **使用instanceof可以检查一个对象是否是一个类的实例** 语法: `对象 instanceof 构造函数` {alert type="success"} - 如果是返回true,否则返回false - 所有的对象都是Object的后代 - **任何对象和Object作instanceof检查时都会返回true** {/alert} ```javascript //创建一个构造函数,专门用来创建Person对象 var per = new Person(); function Person(name,age,gender){ this.name = name; this.age = age; this.gender = gender; this.sayNmae = function(){ alert(this.name); }; } var per = new Person("孙悟空",18,"男") var per = new Person("玉兔精",17,"女") console.log(per); console.log(per instanceof Person); ``` **this的情况:** {alert type="error"} - 1、当以函数的形式调用时,this是window - 2、当以方法的形式调用时,谁调用方法this就是谁 - 3、当以构造函数的形式调用时,this就是新创建的那个对象 {/alert} #### **3、构造函数修改** 在Person构造函数中,为每一个对象都添加了一个sayName方法 ```javascript //创建一个Person构造函数 function Person(name,age,gender){ this.name = name; this.age = age; this.gender = gender; //向对象中添加一个方法 this.sayName = function(){ alert("Hello大家好,我是:"+this.name); }; } //创建一个Person的实例 var per = new Person("孙悟空",18,"男"); var per = new Person("猪八戒",19,"男"); per.sayName(); ``` - 方法是在构造函数内部创建的,构造函数每执行一次就会创建一个新的sayName方法, **也就是所有实例的sayName都是唯一的** - 会导致构造函数每执行一次就会创建一个新的方法 可以将将sayName方法在全局作用域中定义(尽量不要将函数定义在全局作用域) {alert type="info"} - 将函数定义在全局作用域会污染全局作用域的命名空间 - 而且定义在全局作用域中也很不安全 {/alert} ```javascript //创建一个Person构造函数 function Person(name,age,gender){ this.name = name; this.age = age; this.gender = gender; //向对象中添加一个方法 this.sayName = fun; }; } //将sayName方法在全局作用域中定义 function fun(){ alert("Hello大家好,我是:"+this.name); //创建一个Person的实例 var per = new Person("孙悟空",18,"男"); var per = new Person("猪八戒",19,"男"); per.sayName(); ``` #### **4、原型对象** 原型 prototype 创建的每一个函数,解析器都会向函数中添加一个属性prototype  {alert type="success"} - 这个属性对应着一个对象,这个对象就是原型对象 - 如果函数作为普通函数调用prototype没有任何作用 - 当函数以构造函数的形式调用时,它所创建的对象中都会有一个隐含的属性,指向该构造函数的原型对象,可以通过 `__proto__` 来访问该属性  - 原型对象就相当于一个公共的区域,所以同一个类的实例都可以访问到这个原型对象 - 可以将对象中共有的内容,统一设置到原型对象中 - 当访问对象的一个属性时,它会先在对象自身找,如果有则直接使用,如果没有则会向原型对象中选择,如果找到会直接使用  {/alert} ```javascript function MyClass(){ } //向MyClass的原型中添加属性a MyClass.prototype.a = 123; //向MyClass的原型中添加一个方法 MyClass.prototype.sayHello = function(){ alert("hello"); }; var mc = new MyClass(); console.log(MyClass.prototype); console.log(mc.__proto__ == MyClass.prototype);//输出true console.log(mc.a);//输出123 //向mc中添加a属性 mc.a = "我是mc中的a"; console.log(mc.a);//输出 我是mc中的a mc.sayHello();//输出 弹窗hello ```  创建构造函数时,可以将这些对象共有的属性和方法,统一添加到构造函数的原型对象中 这样不用分别为每一个对象添加,就可以使每个对象都具有这些属性和方法,也不会影响到全局作用域 **例:** ```javascript //创建一个Person构造函数 function Person(name,age,gender){ this.name = name; this.age = age; this.gender = gender; //向中添加一个方法 // this.sayName = fun; }; } //向原型中添加sayName方法 Person.prototype.sayName = function(){ alert("Hello大家好,我是:"+this.name); //创建一个Person的实例 var per = new Person("孙悟空",18,"男"); var per = new Person("猪八戒",19,"男"); per.sayName(); // 输出弹窗 ``` **补充:** {alert type="success"} - 使用 `in` 检查对象中是否含有某个属性时,如果对象中没有单数原型中有,也会返回true - 可以使用对象的 `hasOwnProperty()` 来检查对象自身是否含有该属性 - 使用该方法只有当对象自身含有该属性时才会返回true - 原型对象也是对象,所以他也有原型 - ** `当使用一个原型一个对象的属性或方法时,会先在自身中寻找,自身中如果有则直接使用,如果没有则去原型对象中寻找,如果原型对象中有则使用,如果没有则去原型的原型中寻找,直到找到Object对象的原型` ** - `Object对象的原型没有原型,如果在Object的原型中依然没有找到则返回undefined`  {/alert} ```javascript //创建一个构造函数 function MyClass(){ } //向MyClass的原型中添加一个name属性 MyClass.prototype.name = "我是原型中的name"; var mc = new MyClass(); console.log(mc.name); //使用in检查对象中是否含有某个属性时,如果对象中没有单数原型中有,也会返回true console.log("name" in mc); //输出 true //可以使用对象的hasOwnProperty()来检查对象自身是否含有该属性 //使用该方法只有当对象自身含有该属性时才会返回true console.log(mc.hasOwnProperty("name"));//返回false console.log(mc.hasOwnProperty("hasOwnProperty"));//返回false console.log(mc.__protp__.hasOwnProperty("hasOwnProperty"));//输出false console.log(mc.__proto__.__proto__.hasOwnProperty("hasOwnProperty"));//输出true ``` #### 5、toString {alert type="success"} - 当直接在页面中打印一个对象时,实际上是输出的对象的 `toString()` 方法的返回值 - 如果希望在输出对象时不输出 `[object Object]` ,可以为对象添加一个 `toString()` 方法 {/alert} ```javascript function Person(name,age,gender){ this.name = name; this.age = age; this.gender = gender; } //修改Person原型中的toString Person.prototype.toString = function(){ return "Person[name="+this.name+",age="+this.age+",gender="+this.gender+"]" }; //创建一个Person实例 var per = new Person("孙悟空",18,"男"); var per2 = new Person("猪八戒",28,"男"); //console.log(per); //console.log(per.toString);//与上面相同 /*输出Person[name=孙悟空,age=18,gender=男] per.toString = function(){ return "Person[name="+this.name",age="+this.age",gender="+this.gender"]" }; */ var result = per.toString(); //console.log("result = "+result); //console.log(per.__pro__.__pro__.hasOwnProperty("toString"));//返回true console.log(per); console.log(per2); ``` #### 6、垃圾回收(GC) 1. 当一个对象没有任何的变量或者属性对它进行引用时,将永远无法操作该对象,此时这种对象就是一个垃圾 2. 这种对象过多会占用大量的内存空间,导致程序运行过慢,所以这种垃圾必须进行清理 {alert type="success"} - 程序运行过程中会产生垃圾,垃圾积攒过多以后,会导致程序运行的速度过慢 - 所以需要一个垃圾回收的机制,来处理程序运行过程中产生的垃圾 - 在JS中拥有自动的垃圾回收机制,会自动将这些垃圾对象从内存中销毁 - **不需要也不能进行垃圾回收的操作, `要做的只是将不再使用的对象设置null即可` ** {/alert}  ```javascript //创建一个对象 var obj = new Object(); //对对象进行各种操作。。。。 obj = null; ``` {nextPage/} > # 内建对象 对象的类型:内建对象、宿主对象、自定义对象 ### 一、数组 #### 1、数组(Array)的简介 {alert type="success"} - 数组也是一个对象,和普通对象功能类似,也是用来存储一些值的 - 不同的是普通对象是使用字符串作为属性名的,而数组是使用数字来作为索引操作元素的  - 索引(index):从0开始的整数就是索引 - **数组的存储性能比普通对象要好** ,所以在开发中经常使用数组来存储一些数据 {/alert} - 向数组中添加元素,语法: `数组[索引] = 值` - 读取数组中的元素,语法: `数组[索引]` {alert type="error"} - 如果读取不存在的索引,不会报错而是返回undefined - 可以使用 `length` 属性来获取数组的长度(元素的个数),语法: `数组.length` - 对于连续的数组,使用 `length` 属性可以获取数组的长度(元素的个数) - 对于非连续的数组,使用 `length` 属性会获取数组的最大索引+1 - 尽量不要创建非连续的数组,会空出不存在的元素的位置,占用内存 - 向数组的最后一个位置添加元素,语法: **数组[数组.length] = 元素; ** {/alert} ```javascript //创建数组对象 var arr = new Array(); //使用typeof检查一个数组时,会返回Object console.log(typeof arr); //向数组中添加元素 arr[0] = 10; arr[1] = 33; arr[2] = 22; arr[3] = 25; //arr[10] = 21; //arr[100] = 210; //console.log(arr[3]);//输出undefined //获取数组的长度 console.log(arr.length); console.log(arr); //修改length /* 如果修改的length大于原长度,则会空出多出的元素 如果修改的length小于原长度,则会删除多出的元素 */ //arr[10] = 21; arr[2] = 22; //向数组的最后一个位置添加元素 arr[arr.length] = 20; console.log(arr.length); console.log(arr); ``` #### 2、数组字面量 使用字面量来创建数组,语法:[] {alert type="success"} - 使用字面量创建数组时,可以在创建时就指定数组中的元素 - 使用构造函数创建数组时,也可以同时添加元素,将要添加的元素作为构造函数的参数传递 - 元素之间使用 `,` 隔开 - 数组中的元素可以是任意的数据类型,也可以是对象,亦可以是一个函数 {/alert} ```javascript //var arr = new Array(); /* 无意义 arr[0] = 123; arr.hello = "abc"; console.log(arr.hello); */ //使用字面量来创建数组 //var arr = []; var arr = [1,2,3,4,5,6,10]; console.log(arr[1]); console.log(arr.length); var arr = new Array(10,20,30); console.log(arr2); //创建一个数组中只有一个元素10 arr = [10]; //创建一个长度为10的数组 arr2 = new Array(10); console.log(arr[0]); console.log(arr2); //数组中的元素可以是任意的数据类型 arr = [10,"hello",true,null,undefined]; var obj = {name:"孙悟空"}; arr[arr.length] = obj; arr = [{name:"孙悟空"},{name:"沙和尚"},{name:"猪八戒"}] console.log(arr[1].name); arr = [function(){alert(1)},function({alert(2)})]; //console.log(arr); arr[0](); //数组中可以放数组,如下这种数组称为二维数组 arr = [[1,2,3],[3,4,5],[5,6,7]]; console.log(arr[1]); ``` #### 3、数组的方法 ###### (1) `push()` : 语法: **`数组.push(参数一,参数二,参数N);` ** 可以向数组的末尾添加一个或多个元素,并返回数组新的长度 {/alert}{alert type="success"} - 可以将要添加的元素作为方法的参数传递,这些元素将会自动添加到数组的末尾 - 该方法会将数组新的长度作为返回值返回 {/alert} ```javascript //创建一个数组 var arr = ["孙悟空","猪八戒","沙和尚"]; var result = arr.push("唐僧","蜘蛛精","白骨精"); console.log(arr); console.log("result = "+result); ``` ###### (2) `pop()` : 语法: ** `数组.pop();` ** 该方法可以删除啊数组的最后一个元素,并将被删除的元素作为返回值返回,删除几次就写几次 ```javascript //创建一个数组 var arr = ["孙悟空","猪八戒","沙和尚"]; var result = arr.push("唐僧","蜘蛛精","白骨精","玉兔精"); arr.pop(); arr.pop(); console.log(arr); console.log("result = "+result); ``` ###### (3) `unshift()` 语法: **`数组.unshift(参数一,参数二,参数N);` ** {alert type="success"} - 向数组开头添加一个或多个元素,并返回新的数组长度 - 向前边插入元素以后,其他的元素索引会依次调整 {/alert} ```javascript //创建一个数组 var arr = ["孙悟空","猪八戒","沙和尚"]; var result = arr.push("唐僧","蜘蛛精","白骨精","玉兔精"); arr.unshift("牛魔王","二郎神"); console.log(arr); console.log("result = "+result); ``` ###### (4) `shift()` 语法: **`数组.shift();` ** 可以删除数组的第一个元素,并将被删除的元素作为返回值返回,要删除几个就写几个 ```javascript //创建一个数组 var arr = ["孙悟空","猪八戒","沙和尚"]; var result = arr.push("唐僧","蜘蛛精","白骨精","玉兔精"); arr.shift(); console.log(arr); result = arr.shift(); console.log("result = "+result); ``` ###### (5) `slice()` 语法: **`数组.slice(参数一,参数二);` ** 可以从已有的数组中返回选定的元素 参数: 1. 截取开始的位置的索引,包含开始索引 2. 截取结束的位置的索引,不包含结束索引 {alert type="success"} - 该方法不会改变原数组,而是将截取到的元素封装到一个新的数组中返回 - 第二个参数可以省略不写,此时会截取从开始索引以后的所有元素 - 索引也可以传递一个负值,如果传递负值则从后往前计算,例:-1:倒数第一个 {/alert} ```javascript //创建一个数组 var arr = ["孙悟空","猪八戒","沙和尚","唐僧","玉兔精"]; var result = arr.slice(0,2); console.log(result); ``` ###### (6) `splice()` 语法: **`数组.splice(参数一,参数二,参数三,参数N);` ** 可以用于删除数组中的指定元素,并向数组中添加新的元素 参数: 1. 第一个:开始的位置的索引 2. 第二个:删除的数量 3. **第三个及以后的参数可以传递一些新的元素,这些元素将会自动插入到开始位置的索引前面** {alert type="success"} - 使用该方法会改变原数组,会将指定元素从原数组中删除,并将被删除的元素作为返回值返回 {/alert} ```javascript //创建一个数组 var arr = ["孙悟空","猪八戒","沙和尚","唐僧","玉兔精"]; var result = arr.splice(1,0,"牛魔王","红孩儿"); console.log(result); ``` ###### (7)数组去重练习 ```javascript //创建一个数组 var arr = [1,2,3,2,1,3,4,2,5]; //去除数组中重复的数字 ``` 解法: ```javascript //创建一个数组 var arr = [1,2,3,2,2,1,3,4,2,5]; //去除数组中重复的数字 //获取数组中的每一个函数 for(var i=0; i
2021年11月01日
5,281 阅读
0 评论
7 点赞
2021-11-01
『笔记』JavaScript基础学习笔记 2
> ## 对象 JS中的数据类型 {alert type="success"} - String 字符串 - Number 数值 - Boolean 布尔值 - Null 空值 - Undefined 未定义 **`以上五种类型属于基本类型,只要不是以上五种,都是对象`** - Object 对象 {/alert} 基本数据类型都是单一的值,值和值之间没有任何联系 在JS中用来表示一个人的信息(name gender age) ```javascript var name="张三"; var gender="男"; var age="18"; ``` 如果使用基本数据类型,创建的变量都是独立的,不能成为一个整体 对象属于一种复合的数据,在对象中可以保存多个不同数据类型的属性 ### 一、对象的分类 1、内建对象 {alert type="success"} - 由ES标准中定义的对象,在任何的ES的实现中都可以使用 - 比如:Math String Number Boolean Function Object…… {/alert} 2、宿主对象 {alert type="success"} - 由JS的运行环境提供的对象,主要由浏览器提供的对象 - 比如:BOM(浏览器对象模型) DOM(文档对象模型) {/alert} ```javascript console.log(); document.write(); //都是由浏览器提供 ``` 3、自定义对象 {alert type="success"} - 由开发人员自己创建的对象 {/alert} ### 二、创建对象 1、 使用 **new** 关键字调用的函数,是构造函数constructor 2、 构造函数是专门用来创建对象的函数 3、 使用typeof来检查一个对象时,会返回object {alert type="warning"} - 在对象中保存的值称为属性 - 向对象添加属性,语法: `对象.属性名=属性值;` {/alert} ```javascript var obj = new Object(); //console.log(typeof obj); //向obj添加一个name属性 obj.name="张三"; //向obj添加一个gender属性 obj.gender="男"; //向obj添加一个age属性 obj.age="18"; console.log(obj); ``` {alert type="warning"} 读取对象中的属性 语法: `对象.属性名;` 如果读取对象中没有的值,不会报错而是会返回undefined {/alert} ```javascript var obj = new Object(); //向obj添加一个name属性 obj.name="张三"; //向obj添加一个gender属性 obj.gender="男"; //向obj添加一个age属性 obj.age="18"; console.log(obj.name);//输出“张三” ``` {alert type="warning"} 修改对象中的属性 语法: `对象.属性名 = 新值;` {/alert} ```javascript var obj = new Object(); //向obj添加一个name属性 obj.name="张三"; //向obj添加一个gender属性 obj.gender="男"; //向obj添加一个age属性 obj.age="18"; //修改obj的name属性值 obj.name="孙悟空" console.log(obj.name);//输出“孙悟空” ``` {alert type="warning"} 删除对象中的属性 语法: `delete 对象.属性名;` {/alert} ```javascript var obj = new Object(); //向obj添加一个name属性 obj.name="张三"; //向obj添加一个gender属性 obj.gender="男"; //向obj添加一个age属性 obj.age="18"; //删除obj的name属性值 delete obj.name; console.log(obj.name);//没有该值,输出undefined ``` ### 三、属性名和属性值 ##### 1、属性名 - 对象的属性名不强制要求遵守标识符的规范 - 尽量按照标识符的规范设置 {alert type="success"} - 如果使用特殊的属性名,不能采用.的方式来操作 - 需要使用另一种方式,语法: `对象["属性名"]=属性值;` - 读取时也需要采用这种方式 - 使用[]这种形式去操作属性更加灵活 - 在[]中可以直接传递一个变量,这样变量值是多少就会读取那个属性 {/alert} ```javascript var obj = new Object(); obj["123"]=567; obj["nihao"]="你好"; var n = "nihao" console.log(obj["123"]); console.log(obj[n]); ``` ##### 2、属性值 JS对象的属性值,可以是任意的数据类型, **甚至也可以是一个对象** {alert type="warning"} in 运算符 - 通过该运算符可以检查一个对象中是否含有制定的属性,有返回true,没有则返回false - 语法:"属性名" in 对象 {/alert} ```javascript var obj = new Object(); obj.name="孙悟空"; obj.test= true; obj.test= null; obj.test= undefined; var obj2 = new Object(); obj2.name="猪八戒"; obj.test=obj2; console.log(obj.test);//返回 name=“猪八戒” console.log(obj.test.name);//返回 “猪八戒” console.log("name" in obj);//返回true ``` ### 四、基本、引用数据类型 #### (一)基本数据类型 String Number Boolean null Undefined {alert type="success"} JS中的变量都是保存在栈内存的 - 基本数据类型的值直接在栈内存中存储 - 值与值之间是独立存在的,修改一个变量不会影响其他变量 {/alert}  ```javascript var a = 123; var b = a; a++; console.log("a"= +a); //输出为124 console.log("b"= +b); //输出为123 ``` #### (二)引用数据类型 对象:Object {alert type="success"} JS中的变量都是保存在栈内存的 - 对象是保存到堆内存中的,每创建一个新的对象,就会在堆内存中开辟一个新的空间 - 而变量保存的是对象的内存地址(对象的引用),如果两个变量保存的是同一个对象引用 - 当通过一个变量修改属性时,另一个也会受到影响 - {/alert}  ```javascript var obj = new Object(); obj.name = "孙悟空"; var obj2 = obj; console.log(obj.name);//输出 孙悟空 console.log(obj2.name);//输出 孙悟空 //修改obj的name属性 obj.name = "猪八戒"; console.log(obj.name);//输出 猪八戒 console.log(obj2.name);//输出 猪八戒 obj2 = null; console.log(obj);//输出 Object console.log(obj2);//输出 null ```  {alert type="success"} - 当比较两个基本数据类型的值时,就是比较他们的值 - 当比较两个引用数据类型时,是比较对象的内存地址 `如果两个对象一模一样,但是地址不同,它也会返回false` {/alert} ```javascript var a = 10; var b = 10; console.log(a == b); // 返回true var obj3 = new Object(); var obj4 = new Object(); obj3.name = "沙和尚"; obj4.name = "沙和尚"; console.log(obj3 == obj4); // 返回false ```  ### 五、对象字面量 使用对象字面量,可以在创建对象时,直接指定对象的属性 语法: `{属性名:属性值,属性名:属性值....}` {alert type="success"} - 对象字面量的属性名可以加引号也可以不加, **建议不加** - 如果要使用一些特殊的名字,则必须加引号 - 属性名和属性值是一组一组的名值对结构 - 名和值之间使用冒号 `:` 连接多对名值之间使用逗号 `,` 隔开 - 如果一个属性之后没有其他属性时, **就不要写逗号 `,` 了** {/alert} ```javascript //创建一个对象 //var obj = new Object(); //使用对象字面量来创建一个对象 var obj = {}; obj.name = "孙悟空"; var obj2 = { name:"猪八戒", age:28, gender:"男" test:{ name:"沙和尚", age:27 } }; console.log(obj2.test);//输出name:沙和尚 age:27 ``` > ## 函数 ### 一、函数的简介 函数(function):也是一个对象 {alert type="warning"} - 普通对象只能封装属性 - 函数对象可以封装一些功能(代码),在需要时可以执行这些功能 - 函数可以保存一些代码在需要时调用 - 使用typeof检查一个函数时会返回function {/alert} ##### 1、使用构造函数的方式来创建函数 {alert type="success"} - **可以将要封装的代码以字符串的形式传递给构造函数** - 封装到函数中的代码不会立即执行 - 函数中的代码会在函数调用的时候执行 - **调用函数,语法: `函数对象()` ** - 当调用函数时,函数中封装的代码会按照顺序执行 - `在实际开发中很少使用构造函数来创建一个函数` {/alert} ```javascript var fun = new Function( "console.log('这是我的第一个函数');" ); fun.hello = "你好"; console.log(fun.hello);//输出 你好 fun();//输出 这是我的第一个函数 ``` ##### 2、使用函数声明来创建一个函数 语法: 中括号可选,可不写 ```javascript function 函数名([形参1,形参2,形参n]){ 语句... } ``` ```javascript function fun2(){ console.log("这是我的第二个函数"); alert("哈哈哈哈"); document.write("你好"); } fun2();//按顺序输出3个函数 ``` ##### 3、使用函数表达式来创建一个函数 语法: ```javascript var 函数名 = function([形参1,形参2,形参n]){ 语句... } ``` 将一个匿名函数赋值给一个变量 ```javascript var fun3 = function (){ console.log("这是一个匿名函数"); } fun3(); ``` ### 二、函数的参数 ##### 1、形参与实参 可以在函数的()中来指定一个或多个形参(形式参数) {alert type="success"} - 多个形参之间使用 `,` 隔开,声明形参就相当于在函数内部声明了对应的变量,但是 **并不赋值** - 在函数调用时,可以在()中指定实参(实际参数) - 实参将会赋值给函数中对应的形参 - 调用函数时解析器不会检查实参的类型(可能会存在非法参数) - 调用函数时解析器也不会检查实参的数量(多余实参不会被赋值) - 函数的实参可以是任意的数据类型 - 如果实参的数量少于形参的数量,则没有对应实参的形参将会是undefined {/alert} ```javascript function sum(){ var a = 1; var b = 1; console.log(a+b); } sum(); // 输出 求和值2 //a,b都是形参 function sum (a,b){ cosole.log(a+b+c); } //1,2都是实参,实参可以是任意数据类型 sum(1,2);//输出 求和值3 //3没有对应的形参,将变为undefined sum(1,2,3);//输出 求和值null ``` ##### 2、函数的返回值 可以使用return来设置函数的返回值 语法: return 值 {alert type="success"} - return后的值将会作为函数的执行结果返回 - 可以定义一个变量来接受该结果 - **在return后的语句不会再执行** - 如果return语句后不跟任何值就相当于返回一个undefined - 函数中不写return也会返回undefined {/alert} ```javascript function sum(a,b,c){ // alert(a+b+c); var d = a+b+c; return d; //return; alert("hello"); } //调用函数 // sum(1,2,3) //变量result的值就是函数的执行结果 //函数返回什么result的值就是什么 var result = sum(4,7,8); console.log("result="+result);//输出 求和值19 ``` ##### 3、实参的类型 **例1:** 定义一个函数,判断一个数字是否为偶数,如果是返回true,否则返回false ```javascript function isOu(num){ if(unm % 2 == 0){ return true; }else{ return false; } //相等于上面的式子 return num % 2 == 0 ; } var result = isOu(2); console.log("result = "+result);//输出true ``` **例2:** 定义一个函数,可以根据半径计算一个圆的面积,并返回计算结果 ```javascript function mianji(r){ return 3.14*r*r; } var result = mianji(10); console.log("result = "+result);//输出314 ``` **例3:** 创建一个函数,可以在控制台输出一个人的信息 实参可以是任意的数据类型,也可以是一个对象 - 当参数过多时,可以将参数封装到一个对象中,然后通过对象传递 ```javascript function sayHello(o){ console.log("我是"+o.name+",今年我"+o.age+"岁了,"+"我是一个"+o.gender+"人,我住在"+o.address); } //创建一个对象 var obj = { name:"孙悟空", age:18, address:"花果山", gender:"男" }; sayHello(obj); ``` **例4:** 实参可以是一个对象,也可以是一个函数 {alert type="warning"} - `fun(sayHello)` 函数对象,相当于直接调用函数对象 - `fun(sayHello())` 调用函数,相当于使用函数的返回值 {/alert} ```javascript function sayHello(o){ console.log("我是"+o.name+",今年我"+o.age+"岁了,"+"我是一个"+o.gender+"人,我住在"+o.address); } //创建一个对象 var obj = { name:"孙悟空", age:18, address:"花果山", gender:"男" }; function fun(a){ console.log("a = "+a);//输出sayHello整个函数 a(obj);//输出sayHello(obj);的结果 } fun(sayHello); fun(sayHello());//输出函数sayHello的返回值 ``` ##### 4、返回值的类型 ```javascript function fun(){ alert("函数要执行了"); for(var i=0; i
2021年10月25日
5,267 阅读
0 评论
8 点赞
2021-10-25
『原创』『教程』首页及文章页滚动广告栏
> ## 前言 因为之前在很多网站上都能看到广告,虽然但是,这对很多博主来说也是一笔额外的收入,我一直是入不敷出!:@(吐血倒地) 然后我看到了执念博客的首页广告栏,虽然曝光确实大,但是用户体验极其不好,因为要翻很多广告才能翻到文章,就像这样:  所以我就想到了滚动广告,一个广告的位置,能够显示多条广告 > ## 成果展示 {tabs} {tabs-pane label="首页"}  {/tabs-pane} {tabs-pane label="文章页"}  {/tabs-pane} {/tabs} > ## 教程开始 灵感及相关代码来自于Joe主题的首页轮播图 ### 一、添加后台 打开 `functions.php` 添加以下代码 {tabs} {tabs-pane label="代码"} ```php $JADPost = new Typecho_Widget_Helper_Form_Element_Textarea( 'JADPost', NULL, NULL, '文章页顶部广告', '介绍:用于设置文章页顶部广告 格式:广告图片 || 跳转链接 (中间使用两个竖杠分隔) 注意:如果您只想显示图片不想跳转,可填写:广告图片 || javascript:void(0) 其他:一行一个,一行代表一个轮播广告图' ); $JADPost->setAttribute('class', 'joe_content joe_post'); $form->addInput($JADPost); ``` {/tabs-pane} {tabs-pane label="代码位置"} 因为有位小伙伴放错了位置,所以再贴一张图  {/tabs-pane} {/tabs} 这是文章页的代码,因为首页广告主题自带了  ### 二、添加滚动广告栏 {tabs} {tabs-pane label="首页"} 因为首页已经有广告位了,所以直接替换就行了 将主题 `index.php` 的以下代码直接替换为新代码 {collapse} {collapse-item label="代码位置" open}  {/collapse-item} {collapse-item label="新代码" open} {hide} ```php
2021年10月15日
34,212 阅读
77 评论
901 点赞
2021-10-15
『笔记』JavaScript基础学习笔记 1
> **前言** 学无止境,继续加油! > # **代码块 ** {alert type="success"} - 程序是由一条一条语句构成的 - 语句是按照自上而下的顺序一句一句执行的 - 在JS中可以使用 `{}` 来为语句进行分组 - 同一个 `{}` 中的语句称为一组语句,也叫代码块 `代码块要么都执行,要么都不执行` - 在代码块的后面不需要再编写 `;` 结束 - JS中的代码块只具有分组的作用 ,没有其他用途 `代码块内部的内容,在其外部是完全可见` {/alert} ```javascript { alert("hello"); document.write('class="link"') } { var a = 10; alert("hello"); document.write('class="link"') } console.log("a = "+a) ``` > # **流程控制语句 ** 通过流程控制语句可以控制程序执行流程,使程序可以根据一定的条件来选择执行 #### **一、条件判断语句** 在执行某个语句之前进行判断,成立才会执行语句,不成立则语句不执行 **注意:条件判断语句不要使用赋值运算符 `=` 否则会直接返回true** (一)语法一:`if语句` ```javascript if(条件表达式){ 语句… } ``` {alert type="success"} - `if` 语句在执行时,会先对条件表达式进行求值判断,如果条件表达式的值为true则执行if后的语句,为false则不会执行if后的语句 - if语句只能控制紧随其后的那个语句 `如果希望if语句可以控制多条语句,可以将这些语句放到一个代码块内` - **代码块不是必须的,但是开发中建议编写,哪怕只有一条语句** {/alert} ```javascript var a = 20; if(a > 10 && a = 60){ alert("你已经退休了"); }else{ alert("你还要继续工作") } ``` (三)语法三:`if…else if…else语句` ```javascript if(条件表达式){ 语句… }else if{ 语句… }else if{ 语句… }else{ 语句… } ``` {alert type="success"} - `if…else if…else` 语句执行时,会从上到下依次对条件表达式进行求值判断 `如果值为true则执行当前语句,如果值为false则继续向下判断` - 只会有一个代码块被执行,一旦执行语句会直接结束 {/alert} ```javascript var age = 60; if(a > 100){ alert("活着挺没意思"); }else if(a > 60){ alert("你该退休了"); }else if(a > 50){ alert("你还要继续工作"); }else if(a > 17){ alert("你已经成年了"); }else{ alert("你还只是个孩子"); } ``` 4、prompt()函数 {alert type="warning"} - 可以在页面弹出一个带有文本框的提示框 - 用户可以在文本框中输入内容,该函数需要一个字符串作为参数 - prompt()函数的返回值都是字符串string类型 {/alert} ```javascript var score = prompt("参数"); alert(score); ``` **(四)实例练习:** 1、练习一 输入0-100的成绩后进行判断并输出相应的结果 ```javascript var score = prompt("请输入成绩"); // 排除小于0大于100的值,同时排除非数字number类型的值 if(score >100 || score < 0 || isNaN(score)) { alert("毙了"); }else{ if(score ==100) { alert("奖励BMW"); }else if(score >= 80){ alert("奖励手机"); }else if(score >= 60){ alert("奖励参考书"); }else{ alert("啥都没有"); } } ``` 2、练习二 输入三个数据后进行判断并输出相应的结果 ```javascript var height = prompt("请输入身高(cm)"); var money = prompt("请输入财富(万)"); var face = prompt("请输入颜值(px)"); if(height >180 && money > 1000 && face > 500) { alert("一定嫁"); }else if(height >180 || money > 1000 || face > 500) { alert("将就一下"); }}else{ alert("坚决不嫁"); } ``` 3、练习三 输入三个数据后进行排序并从小到大输出 ```javascript var num1 = +prompt("请输入第一个数"); var num2 = +prompt("请输入第二个数"); var num3 = +prompt("请输入第三个数"); if(num1 < num2 && num1 < num3) { // num1最小,比较num2和num3 if(num2= 60){ alert("奖励参考书"); }else{ alert("啥都没有"); } ``` **(三) `for` 循环** 在for循环中,提供了专门的位置来放 `初始化表达式` 、 `条件表达式` 、 `更新表达式` 1、语法: ```javascript for(①初始化表达式;②条件表达式;④更新表达式){ ③语句…… } ``` (1)执行流程 {alert type="error"} ① 执行初始化表达式,初始化变量(只会执行一次) ② 执行条件表达式,判断是否执行循环 `如果为true则执行循环语句③,如果为false则终止循环` ④执行更新表达式,更新表达式执行完毕继续重复执行条件表达式② {/alert} (2)for循环中的三个表达式可以省略,也可以写在外部 `如果在for循环中不写任何表达式,只写两个;;则变成死循环。 慎用!!!` ```javascript for(var i = 0 ; i < 10 ; i++ ){ alert(i); } for(;;){ alert("hello"); } ``` 2、实例练习 (1)打印1-100之间所有奇数之和 ```javascript for(var i=1 , sum=0; i
2021年08月21日
5,269 阅读
0 评论
4 点赞
2021-08-21
『笔记』JavaScript基础学习笔记 0
> ## JS简介 JavaScript(简称“JS”) 是一种具有函数优先的轻量级,解释型或即时编译型的编程语言。虽然它是作为开发Web页面的脚本语言而出名,但是它也被用到了很多非浏览器环境中,JavaScript 基于原型编程、多范式的动态脚本语言,并且支持面向 `对象、命令式、声明式、函数式` 编程范式。 JavaScript在1995年由Netscape公司的Brendan Eich,在网景导航者浏览器上首次设计实现而成。因为Netscape与Sun合作,Netscape管理层希望它外观看起来像Java,因此取名为JavaScript。但实际上它的语法风格与Self及Scheme较为接近。 JavaScript的标准是ECMAScript 。截至 2012 年,所有浏览器都完整的支持ECMAScript 5.1,旧版本的浏览器至少支持ECMAScript 3 标准。2015年6月17日,ECMA国际组织发布了ECMAScript的第六版,该版本正式名称为 ECMAScript 2015,但通常被称为ECMAScript 6 或者ES2015。 > ## JS基础语法 **从上至下按行顺序执行** ```javascript alert("警告"); //弹出警告框 document.write("在文档输出内容"); //在body中输出内容 document:文档 console.log("控制台输出内容"); //向控制台中输出内容 ``` > ## JS编写的位置 1、可以直接编写到标签的onclick属性中 ```javascript 可以点击的超链接 不可点击的超链接 ``` 2、可以将JS编写到script标签中 ```javascript alert("script标签中的代码") ``` 3、可以将js代码编写到外部js文件中,再通过script标签引入 ```javascript ``` **注意:** script标签一旦用于引入外部文件了,就不能再编写代码,即使写了浏览器也会忽略 如果需要,可以再创建一个新的script标签用于编写内部代码 > ## JS基本语法 ```javascript /* 多行注释:注释的内容不会被执行,但是在源代码中查看 可以通过注释来对代码进行一些简单的调试 */ // 单行注释,只注释//后的内容,换行即无效 /* 1、JS中严格区分大小写 2、JS中每一条语句以分号(;)结尾 -如果不写分号,浏览器会自动补齐,但是会消耗系统资源 而且有些时候会加错分号导致错误,所以在开发中分号必须写 3、JS中会忽略多个空格和换行 */ ``` > ## 字面量和变量 字面量:都是一些不可改变的值 比如:1 2 3 4 等 字面量都是可以直接使用,但是一般不会直接使用字面量 变量:可以用来保存字面量,变量的值是可以改变的 -变量更加方便使用,开发中通常通过变量保存一个字面量 -可以通过变量对字面量进行描述,例如 var age = 18; 声明变量:在js中使用var关键字来声明一个变量 ```javascript // 声明变量 var a; // 为变量赋值 a = 123; //声明与赋值同时进行 var a = 123; ``` > ## 标识符 - 在js中所有可以自主命名的都可以称为标识符 - 例如:变量名、函数名、属性名都属于标识符 - 命名一个标识符时需要遵守以下规则 1、标识符中可以含有字母、数字、_、$ 2、标识符不能以数字开头 3、标识符不能使用ES中的关键字或保留字 4、一般使用驼峰命名法:首字母小写,每个单词开头字母大写,其他字母小写。 例如:xxxYyyZzz - JS底层保存标识符时是采用的Unicode编码,所以理论上所有utf-8中含有的内容都可以作为标识符 > ## 数据类型 数据类型指的就是字面量的类型 - 在JS中一共有六种数据类型 {alert type="success"} - String 字符串 - Number 数字 - Boolean 布尔值 - Null 空值 - Undefined 未定义 - Object 对象 {/alert} - 其中String、Number、Boolean、Null、Undefine属于基本数据类型,而Object属于引用数据类型 #### 一、String字符串 - 在JS中字符串需要使用引号引起来 - 使用单引号或者双引号都可以,但是不能混着用 - 引号不能嵌套:双引号内不能放双引号,单引号内不能放单引号 - 在字符串中可以使用\作为转义字符 {alert type="info"} 当表示一些特殊符号时可以使用\进行转义 - \" 表示 " - \n 表示换行 - \t 制表符 - \\ 表示\ {/alert} ```javascript var str = "hello"; str = '我说:"你好"'; alert(str); //输出变量值,值为 我说:“你好” alert("str"); //输出字面量str,值为 str ``` #### 二、Number数字 在JS中所有的数字都是Number类型,包括整数和浮点数(小数点后的数) JS中可以便是数字的最大值:Number.MAX_VALUE - 如果使用Number表示的数字超过了最大值,则会返回一个Infinity {alert type="warning"} - Infinity表示正无穷 - -Infinity表示负无穷 {/alert} - 使用typeof检查Infinity会返回Number - 大于0的最小值为:Number.Min_VALUE NaN是一个特殊的数字,表示Not A Number - 使用typeof检查NaN也会返回Number ```javascript //数字123 var a = 123; //字符串123 var b= "123"; 可以使用typeof检查变量类型 -语法:typeof 变量 -检查字符串时会返回string -检查数值时会返回number console.log(typeof a); console.log(typeof b); ``` {callout color="#ff0000"} 在JS中整数的运算基本可以保证精确 如果使用JS进行浮点元素运算,可能得到一个不精确的结果 {/callout} ```javascript var a = 1; var b = 2; var c = a+b; console.log(c); ``` #### 三、Boolean布尔值 布尔值只有两个,主要用来做逻辑判断 {alert type="success"} - true -表示真 - false -表示假 {/alert} #### 四、Null和Undefined Null类型的值只有一个,就是Null {alert type="success"} - null这个值专门用来表示一个为空的对象 - 使用typeof检查null值时,会返回object {/alert} Undefined类型的值只有一个,就是undefined {alert type="success"} - 当声明一个变量,但是不给变量赋值时,他的值就是undefined - 使用typeof检查undefined值时,会返回undefined {/alert} > ## 强制类型转换 将一个数据类型强制转换为其他数据类型 类型转换主要指,将其他数据类型转换为String Number Boolean #### 一、将其他数值类型转换为String {alert type="success"} 1、调用被转换数据类型的toString()方法 - 该方法不会影响到原变量,它会将转换的结果返回 - Null和Undefined两个值没有toString方法,会报错 {/alert} ```javascript var a = 123; a.toString(); a = a.toString(); console.log(a); console.log(typeof a); ``` {alert type="success"} 2、调用String()函数,并将被转换的数据作为参数传递给函数 - 使用String()函数做强制类型转换时, 对于Number和Boolean实际上就是调用的toString()方法 对于null和undefined就不会调用toString()方法 会将null直接转换为"null",将undefined直接转换为"undefined" {/alert} ```javascript var a = 123; a = String(a); console.log(a); console.log(typeof a); ``` #### 二、将其他数值类型转换为Number 1、使用Number()函数 {alert type="success"} - 字符串转换为数字 ① 如果是纯数字的字符串,直接转换为数字 ② 如果字符串中有非数字内容,则转换为NaN ③ 如果是一个空串或者是一个全是空格的字符串,则转换为0 {/alert} ```javascript var a = "123"; var a = "abc"; var a = " "; a = Number(a); console.log(a); console.log(typeof a); ``` {alert type="success"} - 布尔值转换为数字 ① true 转为 1 ② false 转为 0 {/alert} ```javascript var a = true; var a = false; a = Number(a); console.log(a); console.log(typeof a); ``` {alert type="success"} - null转换为数字时为 0 - undefined转换为数字时为 NaN {/alert} ```javascript var a = null; var b = undefined; a = Number(a); b = Number(b); console.log(a); console.log(typeof a); console.log(b); console.log(typeof b); ``` 2、字符串专用转换方法 {alert type="success"} - parseInt()将一个字符串转换为一个整数 `parseInt()可以将一个字符串中的有效整数内容取出来,然后转换为Number` - parseFloaf()将一个字符串转换为一个浮点数 `parseFloaf()可以将一个字符串中的有效浮点数内容取出来,然后转换为Number` - 如果对非String使用parseInt()和parseFloaf(),会先将其转换为String再换为Number {/alert} ```javascript var a = "123px"; var b = "123.321px"; a = parseInt(a); b = parseFloaf(b); console.log(a); console.log(typeof a); console.log(b); console.log(typeof b); ``` ** 其他进制数字 ** {card-describe title="在JS中"} - 如果需要表示16进制的数字,则需要以0x开头 - 如果需要表示8进制的数字,则需要以0开头 - 如果需要表示2进制的数字,则需要以0b开头(某些浏览器会不支持) - 可以在parseInt()中传递一个第二个参数,用来指定数字的进制 {/card-describe} ```javascript var a = "070"; a = parseInt(a,8); // 制定解析为8进制 console.log(a); console.log(typeof a); ``` #### 三、将其他数值类型转换为Boolean 1、 直接使用Boolean()函数 {alert type="success"} - 数字转Boolean,除了0和NaN,其余都是true - 字符串转Boolean,除了空字符串都是true - null和undefined转Boolean都为false - 对象也会转换为true {/alert} ```javascript var a = 0; var b = " "; var c = null; var c = undefined; a = Boolean(a); b = Boolean(b); c = Boolean(c); console.log(a); console.log(b); console.log(c); console.log(typeof a); ``` 2、可以为任意一个数据类型取两次反!!,将其转换为布尔值 ```javascript var a = "hello"; var a = !!a; console.log(a); // 输出为true console.log(typeof a); //类型为Boolean布尔值 ``` > ## 运算符 运算符也叫操作符,可以对一个或多个值进行运算,并获取运算结果 - tpyeof就是运算符,可以用来获得一个值的类型 - tpyeof会将该值的类型以字符串的形式返回,如number、string、boolean、undefined、object等 ```javascript var a = 123; var result = typeof a; console.log(result); console.log(typeof a); ``` {nextPage/} #### 一、算数运算符 (1)当对非Number类型的值进行运算时,会将这些值转换为Number,然后再进行运算 (2)任何数和NaN进行运算都会输出NaN (3)`+` 可以对两个值进行加法运算,并将结果返回 {alert type="success"} **`① 如果对两个字符串进行加法运算,会将两个字符串拼成一个字符串,然后再将结果返回`** **`② 任何值和字符串做加法运算,都会现转换为字符串然后再和字符串做拼串操作`** **`③ 为任意的数据类型加一个空字符串""即可将其转换为String,这是一种隐式的类型转换,由浏览器自动完成,实际也是调用的String()`** **`④ 加法从左向右运算,会根据数据类型进行转换后再运算`** {/alert} ```javascript var a = 123; a + 1; var result = a + true; // true会转换为1,输出为124 var result = a + NaN; // 输出为NaN var result = "I" + "Love" + "You"; // 输出为ILoveYou var result = 123 + "1"; // 输出为1231 console.log(result); console.log(typeof result); console.log("a=" + a); // 输出为a=124 ``` (4) `-` 可以对两个值进行减法运算,并将结果返回 (5) `*` 可以对两个值进行乘法运算,并将结果返回 (6) `/` 可以对两个值进行除法运算,并将结果返回 - 任何值做 `-` `*` `/` 运算时都会自动转换为Number - 可以通过为一个值 `-0` `*1` `/1` 将其转换为Number,原理和Number()函数一样 ```javascript var a = "123"; var b = a - 0; console.log(b); console.log(typeof b); ``` (7) `%` 取模运算(取余数) ```javascript var a = 9; var b = a % 3; var c = a % 4; var d = a % 5; console.log(b); // 输出9/3的余数为0 console.log(c); // 输出9/4的余数为1 console.log(d); // 输出9/5的余数为4 console.log(typeof b); ``` #### 二、一元运算符 一元运算符,只需要一个操作数 (1) `+` 正号 - 正号不会对数字产生任何影响 (2) `-` 负号 - 负号可以对数字进行负号的取反 (3) 对于非Number类型的值 {alert type="success"} - 会先将其转换为Number,然后再运算 - 可以对一个其他的数据类型使用 `+` 来将其转换为Number,原理和Number()函数一样 {/alert} ```javascript var a = true; var b = -a; console.log(b); // true转换为1,输出为-1 console.log(typeof b); ``` #### 三、自增和自减 (1) 自增 `++` {alert type="success"} - 通过使用自增可以使变量在自身的基础上增加 1 - 一个变量自增以后,原变量的值会立即自增 1 - 自增分为两种: `后++` (a++)和 `前++` (++a) {/alert} ```javascript var a = 1; a++; console.log(a); // 输出为2 console.log(typeof a); ``` - 无论是 `前++` 还是 `后++` ,都会立即使原变量的值自增1 `不同的是a++和++a的值不一样` - **`a++` 的值等于原变量的值(自增前的值)** - **`++a` 的值等于原变量的新值(自增后的值)** ```javascript var a = 1; console.log(a++) ; // 输出为1 console.log(++a) ; // 输出为2 // a++为1,++a是在a++的基础上自增所以为3,a相当于原变量a已经在自身基础上自增两次所以也为3 var b = a++ + ++a +a ; console.log("b = "+b) ; // 输出为1+3+3=7 ``` (1) 自减 `--` {alert type="success"} - 通过使用自减可以使变量在自身的基础上减少 1 - 一个变量自减以后,原变量的值会立即自减 1 - 自减分为两种: `后--` (a--)和 `前--` (--a) {/alert} ```javascript var a = 10; a--; console.log(a); // 输出为9 console.log(typeof a); ``` - 无论是 `前--` 还是 `后--` ,都会立即使原变量的值自减 1 `不同的是a--和--a的值不一样` - **`a--` 的值等于原变量的值(自减前的值)** - **`--a` 的值等于原变量的新值(自减后的值)** ```javascript var a = 10; console.log(a--) ; // 输出为10 console.log(--a) ; // 输出为9 // a--为10,--a是在a--的基础上自减所以为8,a相当于原变量a已经在自身基础上自减两次所以也为8 var b = a-- + --a +a ; console.log("b = "+b) ; // 输出为10+8+8=26 ``` **练习:** ```javascript var n1=10, n2=20; var n = n1++; // n1 = 11 n1++ = 10 console.log('n='+n); // 10 console.log('n1='+n1); // 11 n = ++n1; // n1 = 12 ++n1 = 12 console.log('n='+n); // 12 console.log('n1='+n1); // 12 n = n2--; // n2 = 19 n2-- = 20 console.log('n='+n); // 20 console.log('n1='+n2); // 19 n = --n2; // n2 = 18 --n2 = 18 console.log('n='+n); // 18 console.log('n1='+n2); // 18 ``` #### **四、逻辑运算符** {callout color="#00fbff"} **布尔值的逻辑运算** {/callout} JS中提供了三种运算符 (1) `!` 非,可以用来对一个值进行 `非` 运算 {alert type="success"} - 非运算就是对一个布尔值Boolean进行取反操作 - true变false,false变true {/alert} ```javascript var a = true; a = !a; console.log(a); // 输出为false ``` {alert type="success"} - 如果对一个值进行两次取反,值不会变 - 如果对非布尔值进行非运算,会先将其转换为布尔值再进行取反 `可以为任意一个数据类型取两次反!!将其转换为布尔值,可以用来将其他数据类型转换为布尔值` {/alert} ```javascript var a = "hello"; var a = !!a; console.log(a); // 输出为true console.log(typeof a); //类型为Boolean布尔值 ``` (2) `&&` 与,可以对符号两侧的值进行 `与` 运算并返回结果 {alert type="success"} - 两个值中只要有一个值为false就会返回false - 两个值都为true才会返回true - JS中如果第一个值为false,就不会检查第二个值,直接返回false ```javascript 如果两端的值都为true,返回true var a = true && true; console.log(a); // 输出为true 只要有一个false,都返回false var a = true && false; console.log(a); // 输出为false ``` {/alert} (3) `||` 或,可以对符号两侧的值进行 `或` 运算并返回结果 {alert type="success"} - 两个值都是false,则返回false - 两个值中只要有一个true,则返回true - JS中如果第一个值为true,就不会检查第二个值,直接返回true ```javascript 如果两端的值都为false,返回false var a = false || false; console.log(a); // 输出为false 只要有一个true,都返回true var a = true || false; console.log(a); // 输出为true ``` {/alert} {callout color="#00fbff"} **非布尔值的 `与` 、 `或` 运算** {/callout} 对非布尔值进行 `与` 、 `或` 运算时会先将其转换为布尔值,然后再运算,并且返回原值 (1) `&&` 与 运算:找false {alert type="success"} - 如果第一个值为true,则必然返回第二个值 - 如果第一个值为false,则直接返回第一个值 ```javascript var a = 1 && 3; console.log(a); // 输出为3 var a = NaN && 0; console.log(a); // 输出为NaN ``` {/alert} (2) `||` 或 运算:找true {alert type="success"} - 如果第一个值为true,则直接返回第一个值 - 如果第一个值为false,则直接返回第二个值 ```javascript var a = 1 || 3; console.log(a); // 输出为1 var a = NaN || 0; console.log(a); // 输出为0 ``` {/alert} #### **五、赋值运算符** (1) `=` 可以将符号右侧的值赋值给左侧的变量 ```javascript var a = 3; console.log(a); // 输出为3 ``` (2) `+=` 可以将符号右侧的值相加后再赋值给左侧的变量 (3) `-=` 可以将符号右侧的值相减后再赋值给左侧的变量 (4) `*=` 可以将符号右侧的值相乘后再赋值给左侧的变量 (5) `/=` 可以将符号右侧的值相除后再赋值给左侧的变量 (6) `%=` 可以将符号右侧的值取模(取余数)后再赋值给左侧的变量 ```javascript var a = 10; a += 5; // 等价于a = a + 5 输出为15 a -= 5; // 等价于a = a - 5 输出为5 a *= 5; // 等价于a = a * 5 输出为50 a /= 5; // 等价于a = a / 5 输出为2 a %= 5; // 等价于a = a % 5 取模(取余数)输出为0 console.log(a); ``` #### **六、关系运算符** 通过关系运算符可以比较两个值之间的大小关系 {alert type="success"} - 如果关系成立会返回true,如果关系不成立则返回false - 对于非数字进行比较时,会将其转换为数字再进行比较 `任何值和NaN比较都是false` - **如果符号两侧都是字符串时,不会将其转换为数字进行比较,而会比较两个字符串的Unicode编码** `比较字符编码时会一位一位进行比较,如果两位一样则比较下一位,第一位与第一位比,第二位于第二位比,以此类推` ```javascript console.log( "a" > "b"); // 输出false console.log( "abc" > "aa"); // 输出true ``` {/alert} (1) `>` 大于号 {alert type="info"} - 判断符号左侧的值是否大于右侧的值 - 如果关系成立则返回true,如果关系不成立则返回false {/alert} ```javascript var a = 10 > 5; //返回true a = 5 > 5; //返回false a = 5 > 10; //返回false console.log(a); ``` (2) `>=` 大于等于号 {alert type="info"} - 判断符号左侧的值是否小于 `或` 等于右侧的值 - 如果关系成立则返回true,如果关系不成立则返回false {/alert} ```javascript var a = 10 >= 5; //返回true a = 5 >= 5; //返回true a = 5 >= 10; //返回false console.log(a); ``` (3) `c ? a :c) : (b > c ? b : c) // 不推荐,不易阅读 console.log( "最大值max = "+max); // 谁大输出谁 "hello"?alert("语句1"):alert("语句1"); // hello转换为true然后执行输出语句1 ``` **`,`逗号运算符** 使用 `,` 可以分割多个语句,可以使用`,` 逗号运算符同时声明多个变量并进行赋值 ```javascript var a , b , c; var a=1 , b=2 , c=3; alert(b); ``` #### **九、运算符的优先级** {alert type="success"} - 在JS中运算符也有优先级,比如:先乘除后加减 - 在JS中有一个运算符的优先级标准表,优先级越高越优先计算,如果优先级相同,则从左向右计算 {/alert}  > 最后 因为学习笔记较为详细,字数比较多,所以只好另开一篇继续( ~~再水一篇文章~~ :@(装大款) )
2021年08月16日
3,685 阅读
0 评论
6 点赞
2021-08-16
『原创』『代码』为你的博客添加悬浮打赏按钮(按钮切换)
> ## 前言 博客搭建已经有一段时间了,文章也写了不少了(虽然有些是扒的:@(狂汗)XD) 但是前几天有人发消息说觉得我的文章帮到他了,想要打赏,却没有打赏途径 找了很久,除了几个插件就没有我心仪的,但是插件又要下载上传,太麻烦了 XD 所以我就用自学的HTML写了一个悬浮打赏按钮,添加到文章点赞旁边,效果很好,我非常满意,所以现在分享出来 > ## 成果展示 {tabs} {tabs-pane label="第一版"}  {/tabs-pane} {tabs-pane label="第二版"}  {/tabs-pane} {tabs-pane label="切换版"}  {/tabs-pane} {/tabs} > ## 版本升级 当我把这个功能做好后,发给要打赏我的人时,Ta却说打赏不了,在微信中总是识别成支付宝的链接 :@(吐血倒地) 然后我自己试了一下,发现确实会识别错位,不知道是不是支付宝的二维码更要强一些,识别十次九次都是支付宝链接,打赏的人都不想给我打赏了,气死我了 :@(内伤) {dotted startColor="#ff6c6c" endColor="#1989fa"/} 然后我就想到了点击切换二维码,说干就干,首先我用css试了很久,发现光用css已经实现不了我的需求了 然后我就开始琢磨JS来实现,开始用了if语句来切换 `img` 的 `url` ,确实可以切换了,但是if语句只能对应一个按钮,如果别人不知道按钮可以切换,那就仅显示一个二维码 突然想到,既然用js了,那为什么不直接根据不同的 `input` 按钮给 `img` 赋值呢,然后我就写了三段赋值语句(学艺不精啊) :@(尴尬) 然后就实现了一个按钮切换一个二维码了 {dotted startColor="#ff6c6c" endColor="#1989fa"/} 再发给要打赏我的人,结果.... :@(无奈) 只打赏了0.01元 :@(扇耳光) > ## 代码分享 其实这个功能很简单,其实就是CSS的 `:hover` 来实现的 我使用的是Joe主题,所以我直接添加在点赞旁边,让它看看起来跟整个主题更协调 首先找到Joe主题目录中的点赞文件 `public/handle.php` 再在点赞按钮后添加以下代码 隐藏内容,请前往内页查看详情 添加到 `public/handle.php` 的倒数第二行  保存后,刷新网站,打赏按钮就出现了,试着把鼠标移上去看看效果吧! > ## 切换版下载
2021年04月05日
26,099 阅读
207 评论
1,278 点赞
2021-04-05
『原创』『教程』给你的Typecho博客侧边栏加一个恋爱计时(修复夜间模式样式)
> ## 前言 前几天在翻主页的时候,看到 [Nots](https://blog.n0ts.cn/) 分享了他和他女朋友的甜蜜日常。 然后注意到了他网站侧栏的小部件,有一个他和他女朋友恋爱的计时模块,很感兴趣 我刚好也想给自己女朋友制作一点小浪漫,所以就着手把他分享的代码搬了过来,做了一些优化 > ## 紧急修复 刚测试时发现夜间模式下,会直接透明显示,没有浮块显示 我估计是主题作者忘记给自定义模块设置背景色了,所以显示很不协调,就像这样  所以我又调用了Joe主题的CSS样式,让这个模块会根据日间模式和夜间模式改变背景颜色,达到和其他模块样式统一 顺便修改了这个模块的文字颜色,夜间模式下不会再是一片漆黑了(**PE端同时修复**)  > ## 成果展示 {tabs} {tabs-pane label="**PC端**"}  {/tabs-pane} {tabs-pane label="**手机端**"}  {/tabs-pane} {/tabs} > ## 实现方法 本教程仅适用于typecho且使用了Joe主题的小伙伴,其他主题或者博客的小伙伴请自行发挥你们的才能 {tabs} {tabs-pane label="PC端"} {callout color="#f0ad4e"} PC端代码:(样式我已经根据Joe主题适配好了,不喜欢的自己修改) {/callout} {mtitle title="在文章最后下载"/} 如果是使用的 [**Joe for typecho**](https://www.fuuuy.cn/archives/292.html) ,那就很简单了,直接在后台的主题设置里 登录你的网站后台,进入 **外观设置-网站外观-设置外观(必须使用Joe主题)-侧栏设置**  找到 **自定义侧边栏模块-PC**  保存好后,再刷新自己的网站就可以看到了! {/tabs-pane} {tabs-pane label="PE端"} {callout color="#ab74e4"} PE端代码:(因为是后端代码,所以我就直接套用了Joe主题的样式) {/callout} {mtitle title="在文章最后下载"/} 手机端的侧栏要复杂一点,但你都进入我的博客了,那我肯定要手把手把你教会了:@(得意) 如果你懂一些 **HTML**,那就很容易能找到PE端的侧栏文件 PE端的样式配置在 **Joe/public/header.php**里 那我们直接在 **header.php** 添加代码就行了,找到PE端侧栏配置位置  然后找到想要加入的位置,可以加在作者信息下,也可以加在网站统计下 我是加在了作者信息下,可以更为直接显示,也更明显,主要是女朋友能够一眼就看到:@(得意)  当然这里添加的代码跟上面的是有一点区别的,我试了几次,发现同样的代码会出现PE端显示,而PC端文字不显示 测试了很多次,终于被我发现,原来是 **JS** 的 **id** 重复了,导致PHP后端的id占用了前端的id 而因为PE端的代码是直接加在源代码里的,所以导致PC端文字不显示了 因此我又对代码进行了优化,没错,从发现bug-测试bug-修改bug又磨了我一小时:@(喷血) **注意:**因为是修改了后端代码,每次更新Joe的主题时都会被覆盖,所以每次更新主题后记得去 **header.php** 重新添加代码 希望Joe主题作者后期能够添加自定义PE侧栏的功能,~~或者不要更新太频繁~~ :@(扇耳光) {/tabs-pane} {/tabs} > ## 结语 教程到此结束,祝各位早日找到心仪的另一半,幸福美满! 感谢 **Nots** 分享的代码。 > ## 代码下载
2021年03月08日
34,701 阅读
170 评论
672 点赞
2021-03-08