1、什么是DOM:Document Object Model(文档对象模型) 将每一个标签、元素、属性、文本、注释,都看作一个DOM节点/元素/对象(提供了一些操作元素的属性和方法)
面试题:HTML/XHTML/DHTML/XML分别是什么?
1、HTML - 网页
2、XHTML - 更严格的网页
3、DHTML - 动态的网页:D:Dynamic:其实并不是新技术、新概念,是将现有技术的整合的统称,使我们的网页在离线状态依然具有动态效果
DHTML=HTML+CSS+JS(dom)
4、XML - 数据格式
DOM:原本是可以操作一切结构化文档的 HTML 和 XML,后来为了方便各类开发者细分为了3部分:
1、核心DOM:【无敌的】,既可以操作HTML,又可以操作XML
缺点:API比较繁琐
2、HTML DOM:只能操作HTML,优点:API非常简单
缺点:比如属性部分,只能访问/设置标准属性,不能操作自定义属性
3、XML DOM:只能操作XML,XML已经淘汰了,现在最流行的数据格式是JSON
开发建议:优先使用HTML DOM,HTML DOM满足不了的操作我们再用核心DOM进行补充
2、DOM树:树根:document - 不需要我们创建,一个页面只有一个document对象,由JS解释器自动创建 可以通过树根找到每一个DOM元素/节点/对象,提供了很多很多的API等待我们学习
3、每个DOM元素都有三大属性: 1、xx.nodeType - 描述节点的类型 document节点:9 element节点:1 attribute节点:2 text节点:3
以前有用:判断xx是不是一个页面元素,因为我们以前没有children找儿子,只有childNodes
2、xx.nodeValue - 获取元素的属性值的
以前有用:获取一个属性节点的值,因为以前没有getAttribute,只有getAttributeNode
3、***xx.nodeName:节点的名称 - 判断xx是什么标签
注意:返回的是一个全大写的标签名!
今日目标:学会找元素&找数据 4、*通过关系获取元素: 父:xx.parentNode; 子:xx.children; - 集合,问题:仅仅只能找到儿子,找不到孙子、曾孙... 第一个儿子:xx.firstElementChild; 最后一个儿子:xx.lastElementChild; 前一个兄弟:xx.previousElementSibling; 后一个兄弟:xx.nextElementSibling;
5、*****递归:简单来说就是函数中,又一次调用了函数自己,迟早有一天也会停下来 何时使用:遍历DOM树,专门用于【层级不明确】的情况,既可以遍历层级不明确的DOM,又可以遍历层级不明确的数据
如何使用:2步
function 函数名(root){
1、第一层你要做什么操作直接做!
2、判断他有没有下一级,如果有下一级再次调用此函数,但是传入的实参是下一级的东西
}
函数名(实际的根);
算法:深度优先!优先遍历当前节点的子节点,子节点遍历完毕后才会跳到兄弟节点
缺点:同时开启大量的函数调用,消耗大量的内存,只有一个情况才会使用:【遍历层级不明确】
递归 vs 纯循环
递归:优点:直观易用
缺点:性能低下
纯循环:优点:性能高,几乎不占用内存
缺点:难得批爆
6、遍历层级不明确的API: 语法:1、创建tw对象 var tw=document.createTreeWalker(根元素,NodeFilter.SHOW_ELEMENT);
2、反复调用tw的nextNode()函数找到每一个元素
while((node=tw.nextNode())!=null){
node要干什么操作
}
缺点:1、必然跳过根元素,不会对根元素做操作
2、不可以遍历层级不明确的数据,仅能遍历层级不明确的DOM元素
7、*API直接找到元素: 1、通过HTML的一些特点去找元素 1、id:var elem=document.getElementById("id值") 2、标签名和class名和Name名:var elems=document/parent.getElementsByTagName/ClassName/Name("标签名/class名") name这个属性,input必写,那我们以后input就可以不class了
2、*通过css选择器获取元素:
1、单个元素:var elem=document.querySelector("任意css选择器");
强调:1、万一选择器匹配到多个,只会返回第一个
2、没找到null
2、*多个元素:var elems=document.querySelectorAll("任意css选择器");
强调:找到了 返回集合,没找到返回空集合
更适合用于做复杂查找
面试题:getXXX 和 queryXXX的区别?
返回结果不同?
1、getXXX:返回的是一个动态集合HTMLCollection
2、queryXXX:返回的是一个静态集合NodeList
动态集合:根据DOM树的改变,悄悄的一起跟着变化,每一次修改DOM,都会悄悄的再次查找页面元素,缺点:性能低,而且不能使用forEach
静态集合:根据DOM树的改变,不会一起变化,只会认准当时找的时候的数据,优点:复杂查找时简单、性能高、使用forEach
总结:找元素 1、直接找:getXXX、queryXXX 2、通过关系 3、层级不明确才用递归 操作元素: 1、元素的内容: 1、*elem.innerHTML:获取或设置开始标签到结束标签之间的HTML代码,可以识别标签 获取:elem.innerHTML 设置:elem.innerHTML="新内容"
2、elem.textContent:获取或设置开始标签到结束标签之间的纯文本,具有兼容性问题,不能识别标签
获取:elem.textContent
设置:elem.textContent="新文本"
老IE:elem.innerText - 第一次碰到小三上位,原本这个只有老IE可用,但随着各个浏览器的升级发展也支持了,老IE没有将就大家 ,反而大家在将就老IE
3、*input.value:获取或设置input的值
获取:input.value;
设置:input.value="新值";
2、元素的属性: 1、*获取属性值 核心DOM:elem.getAttribute("属性名");
HTML DOM:elem.属性名;
2、*设置属性值
核心DOM:elem.setAttribute("属性名","属性值");
HTML DOM:elem.属性名="新值";
3、*删除属性值:
核心DOM:elem.removeAttribute("属性名");
HTML DOM:elem.属性名="";
4、判断有没有:垃圾:只能判断有没有,不能判断具体是什么
核心DOM:elem.hasAttribute("属性名");
HTML DOM:elem.属性名!="";
强调:HTML DOM确实简单,但是需要注意:
1、class必须写为className
2、只能操作标准属性,不能操作自定义属性
3、删除属性时,删不干净,有的属性删不干净依然具有功能:比如:href没有属性值会有默认的刷新功能,disabled没有属性值依然具有禁用的功能
3、元素的样式 1、*内联样式:优先级最高,一定会覆盖其他的样式 仅仅当前元素可用,不会牵一发动全身 获取:elem.style.css属性名; 设置:elem.style.css属性名="css属性值"; 唯一的小缺陷:获取样式时,只能获取到内联的样式 - 忍一忍就过了
2、样式表:
//1、获取你想要操作的样式表
var sheet=document.styleSheets[i];
//2、获取所有的样式规则
var rules=sheet.cssRules;
//3、所有的规则中挑选出你需要操作的规则
var rule=rules[i];
//4、做获取 或 设置
console.log(rule.style.width);
rule.style.width="100px"
1、*创建元素并且渲染DOM树:3步 1、创建空元素: var elem=document.createElement("标签名");
2、为这个空标签设置必须要的属性和事件
elem.属性名="属性名";
elem.on事件名=function(){操作}
3、将这个元素渲染到DOM树上
*父元素.appendChild(elem); - 将elem追加到父元素里面当了最后一个儿子
父元素.insertBefore(elem,已有子元素); - 将elem追加到父元素里面,并且插入到已有子元素的前面
父元素.replaceChild(elem,已有子元素) - 将elem追加到父元素里面,并且替换已有子元素
2、*删除元素:elem.remove();
恭喜你:核心DOM已经全部学习完毕了,总结:DOM到底干了什么事? 增、删、改、查(元素、属性、样式、文本)
3、HTML DOM提供了一些常用对象:并且对这些对象进行了简化,但是不是人人都可以简化 1、image对象:图片对象,仅仅只是简化了创建 创建:var img=new Image();//完全等效于var img=document.createElement("img"); 注意:不是人人都有构造函数创建方式
2、form对象:简化了表单对象,简化的是查找:
查找form元素:var forms=document.forms;
查找当前这个form元素下面的input:var inps=forms[1].elements;
专属事件:form.onsubmit=function(){//提交事件,只会在提交的一瞬间触发,防止用户输错还能提交
return false;
}
3、*select对象:
属性:1、select.options;//得到select下面的所有的option,完全等效于xx.children
2、select.selectedIndex;//获取到当前选中项的下标,当时我们还说除了select其他元素都需要自定义下标才能完成此操作
方法:1、*select.add(option);//完全等效于appendChild
专属事件:select.onchange=function(){//选中项发生【改变】的时候才会触发}
4、*option对象:仅仅只是简化了创建,但是却非常牛逼!!
var opt=new Option("innerHTML","value");
一句话:完成4个操作:
select.add(new Option("innerHTML","value"));
1、BOM:Browser Object Model(浏览器对象模型) 专门提供了用于操作浏览器的API - 没有标准,不像DOM由W3C来制定标准,但是大部分浏览器已经统一实现了,唯独老IE与众不同,相当于DOM使用也会较少
2、window对象:扮演着两个角色: 1、在前端/浏览器端,他代替了全局对象global,保存着全局变量和全局函数 window.变量名; window.函数名(); - 只不过window可以省略不写 2、指代当前窗口本身 目的:优化用户的体验感,多为用户考虑 1、网页打开新链接的方式 1、替换当前页面,可后退 HTML:<a/ href="url">内容 JS:open("url","_self");
2、替换当前页面,禁止后退:使用场景:结账后不允许后退
history对象:保存着当前窗口打开过的历史记录url,只有产生了窗口历史才能前进后退
location对象:保存着当前窗口正在打开的url
JS:location.replace("url") - 替换网址后页面肯定变化,但是替换并不叫跳转,不会产生任何的历史纪录
3、在新窗口打开,可以打开多个
HTML:<a/ href="url" target="_blank">内容</a>
JS:open("url","_blank");
4、在新窗口打开,只能打开一个:使用场景:打开结账页面时
HTML:<a/ href="url" target="自定义name">内容</a>
窗口的底层其实是有名字的,如果重新打开相同的名字,新打开的窗口会替换掉旧的窗口
JS:open("url","自定义name");
扩展:a标签的其他用处:
1、跳转
2、锚点
3、下载:<a href="xx.exe/zip/rar">下载</a>
4、打开:<a href="xx.txt/jpg...">图片/文本</a>
5、直接执行js操作:<a href="javascript:js代码;">图片/文本</a>
2、window窗口的属性和方法:
属性:
获取大小:
1、获取浏览器的完整的大小:outerWidth/Height
2、*获取浏览器的文档显示区域的大小:innerWidth/Height
3、获取完整屏幕的大小:没用,我们并不做桌面应用
screen.width/height
方法:
1、打开新窗口:var newW=open("url","自定义name","width=?,height=?,left=?,top=?");
//第三个参数如果没传入,那么新窗口大小和位置会与浏览器融为一体
//第三个参数如果传入,新窗口会脱离浏览器独立成为一个小窗口
2、关闭新老窗口:window/newW.close();
//以下两个操作:仅仅只能对脱离浏览器的新窗口可用
3、移动新窗口:newW.moveTo(x,y);
4、改变新窗口的大小:newW.resizeTo(new宽,new高);
5、定时器:
何时使用:只要过一段时间就希望执行的特效或操作,必须使用定时器
如何使用:
1、周期性:只要不停止会等待时间,反复不断的执行
开启:timer=setInterval(callback,间隔毫秒数);
停止:clearInterval(timer);
2、一次性:等待时间后只会执行一次,就结束
开启:timer=setTimeout(callback,间隔毫秒数);
停止:clearTimeout(timer);
其实以后你不会是周期性还是一次性都无所谓,因为两者的底层是一样的,用哪个停止其实无所谓,甚至可以互换!
BOM之中只有两个重点:定时器和event,BOM存在大量的兼容性问题
BOM对象: 1、history:封装着当前窗口打开过的历史记录url: 前进:history.go(1); 后退:history.go(-1); 刷新:history.go(0); 垃圾:浏览器自带此功能,没必要
2、navigator:封装着当前浏览器的基本信息,判断此浏览器是什么浏览器以及版本号 navigator.userAgent; - 想办法截取你需要的部分 垃圾:说白了专门为判断是不是IE存在的,但是开发效率慢远远不如css hack来的简单(其实现在做兼容越来越少了:1、微软不推荐我们用IE 2、流行移动端,移动端不存在IE 3、前辈们其实已经提供好了兼容方法,都不需要我们去判断浏览器)
3、*location:封装着当前窗口正在打开的url: *常识:面试时:一个url由几部分组成? www.baidu.com/s?wd=%E6%9D… http://127.0.0.1:8020/bom02/new/02%E5%88%A4%E6%96%AD%E6%B5%8F%E8%A7%88%E5%99%A8%E4%BB%A5%E5%8F%8A%E7%89%88%E6%9C%AC%E5%8F%B7.html?__hbt=1668478029615
*属性:其实一这块根本不需要记单词属性,你只需要打开控制台输出location对象即可查看
protocol - 协议:https/http/ftp/ws... - 固定的,我们想要免费肯定用http
hostname - 域名/主机号/IP:域名是需要花钱购买的,ip是免费的,而且自己访问自己可以用主机号127.0.0.1
port - *端口号:默认端口号可以省略不写:https默认端口为443,http默认端口为80
pathname - *文件相对路径/路由:百度加密了,意味着你现在看到的是哪个页面
search - *查询字符串/请求消息:前端提交到后端的东西,前端说的话
协议://域名:端口号/文件相对路径?前端告诉后端的话
方法:
1、跳转:location="新url";
2、跳转后禁止后退:location.replace("新url");
4、*****event:事件:用户手动触发的 或 浏览器自动触发的 1、绑定事件:3种 1、在HTML种定义事件处理属性: <elem on事件名="js语句"> 缺点: 1、不符合内容(HTML)和行为(JS)的分离 2、无法动态绑定事件 - 一次只能绑定一个元素 3、无法同时绑定多个函数对象
2、*在JS中使用元素的事件处理函数属性
elem.on事件名=function(){}
优点:
1、符合内容(HTML)和行为(JS)的分离
2、动态绑定事件
3、没有兼容性问题
缺点:
1、无法同时绑定多个函数 - 个人认为不是缺点,我们可以把多个函数汇总为一个函数
3、使用API绑定事件
主流:elem.addEventListener("事件名",callback);
老IE:elem.attachEvent("on事件名",callback);
兼容:
if(elem.addEventListener){
elem.addEventListener("事件名",callback);
}else{
elem.attachEvent("on事件名",callback);
}
优点:
1、符合内容(HTML)和行为(JS)的分离
2、动态绑定事件
3、同时绑定多个函数对象
缺点:
1、存在兼容性问题 - 导致代码量巨大
2、*事件周期:从事件发生到事件结束的全过程
1、捕获阶段:由外向内:记录着要执行的事件有哪些
2、目标触发:目标元素:实际发生事件的元素
3、冒泡阶段:由内向外执行
3、*获取事件对象event:
主流:在事件处理函数中传入一个形参,就会自动得到event对象了
老IE:window.event;
兼容:这是我们第二次见到小三上位,老IE的操作,主流也可以使用了,建议:如果不考虑老IE,明显写一个形参e更简单
*****事件对象event可以干什么?
1、获取鼠标位置
2、***阻止冒泡:面试/笔试
主流:e.stopPropagation();
老IE:e.cancelBubble=true;
兼容:这是我们第三次见到小三上位,老IE的操作,主流也可以使用了
3、*****利用冒泡/事件委托:
优化:如果多个子元素定义了相同的事件处理函数,最好只给父元素定义一次
为什么:每次绑定一个事件处理函数,其实就创建了一个事件监听对象,创建的监听对象越多,那么网页的效率就越低下
获取目标元素:【实际】触发事件的元素
主流:e.target;
老IE:e.srcElement;
兼容:这是我们第4次见到小三上位,老IE的操作,主流也可以使用了
好处:
1、事件只需要给父元素绑定一次,搭配上nodeName/className等判断则无敌
2、不用担心冒泡了,我们就是要利用冒泡
3、再也不用使用this这个【当前对象】了,【目标对象】更舒服
4、阻止浏览器的默认行为:比如:a标签href默认刷新,submit按钮默认提交,比如F5刷新页面,比如F12打开控制台,比如阻止右键的弹出菜单
主流:e.preventDefault();
老IE:e.returnValue=false;
兼容:4e.returnValue=false; //不光老IE可用,主流也可以用 - 小三上位
5、获取键盘的键码
e.keyCode - 不需要你记忆:要么console输出看,要么百度搜索
新事件:
1、window.oncontextmenu - 右键菜单事件
2、window.onkeyDown - 键盘按下事件 - 不做游戏开发几乎不用
学习的原因: 1、web前端招聘要求 - 熟悉或了解一门服务器端技术者优先(node.js) 2、熟悉服务器端机制 和 流程后,更好提高前端的开发(防止背锅)
扩展: 技术类型发展方式 全栈 - 客户端(PC+移动端)+ 服务器端 + 数据库,设置到多个领域,每个领域都不精通,但是会用,不会创造(你会就行,不用做,工资够高就可以) 专家 - 在某一个领域最屌的 管理 - 项目经理、技术总监 销售 - 产品:出去和别人谈生意,需要知道业务逻辑/流程 创业 - 不推荐 教育
可能成为全栈的语言
java - 不包含移动端
JavaScript语言
客户端 - 开发根本
服务器端 - node.js历史上第一次出现一门语言可以通吃前后端
数据库 - mongoDB非关系型数据库中最火的一个,mysql,oracle关系型数据库
移动端 - 跨所有平台的(andriod+ios),你只需要学习一点点ios和andriod的语法即可完成(三阶段混合开发框架uniapp)
全栈课程:Node.js2天 + mongoDB1天 + ajax3天 + Node.js框架(express框架) 最终目的:登录+注册+注销账号+修改密码+全栈一条龙
基本内容: 服务器概念 简单来说就是一台PC机 生活中使用的是 微机 商业中使用 小型机(ibm和联想:大概造价在几十万,好的上百万)、中型机、大型机、超级计算机(国家:天河一、二号,神威太湖之光)
我们如何才能获得一个服务器呢?
1、硬买一台 - 中小型公司难以承受
2、租一台 - 新浪/阿里/腾讯/百度云...租服务器,按年/月,根据你选择的配置不同价格也不同
3、买二手货 - 一万块左右就能搞定
4、配置一台性能好一点的微机 - 同时访问量过大,可能就会down机了
对于开发人员
硬件服务器 - PC机
软件服务器 - 中间件(软件将我们普通电脑变为一个服务器node.js)
应用架构
C/S - client客户端/server服务器端
举例:
QQ、微信、微博
大型网游
优点:
1、用户体验感好
2、运行稳定的
3、对带宽的要求低
缺点:
1、占硬盘空间
2、更新过于复杂 - 服务器端要更新,客户端还要更新
B/S - browser浏览器端/server服务器端
举例:
网页QQ、微信、微博
网页游戏
优点:
1、更新容易 - 服务器端更新
2、不占硬盘空间
3、不看你的电脑配置
缺点:
体验相对较差(越来越好)
对带宽的要求高(我们现在的网速越来越快了)
1、Node.js概述: Node.js不是JS,但是和JavaScript的语法非常相似,是一种服务器端技术,他的竞争对手PHP/JAVA/C++/C#/PYTHON - 历史上第一次一门语言可以通吃前后端 - 前端崛起原因之一 很像:但是做的事儿不一样 JS:做特效 Node:前端 <=桥梁(服务器端)=>数据库的 版本:16年初(0.12) 16年中(4.x) 16年底(6.x) 22年底(19.x) 意味着:行业有发展,正在发展中,现在确实不算牛逼,缺乏一个超级大框架。其实每次都没更新啥 目的:1、通过node.js书写代码来搭建一个私网服务器&文件系统,让我们局域网内的人员可以来进行访问 - 免费 2、搭配上数据库玩全栈 下载安装:LTS长效稳定版 - 双击node-v18.12.1-x64.msi,一直点下一步,不要取消任何东西,就装C盘 检查自己是否安装成功:打开cmd输入node -v回车如果你能看到版本号则安装成功
2、如何运行node.js - 我们安装的node.js其实是一个运行环境,可以让我们的"js"脱离浏览器运行,但其实已经不是javascript 1、交互模式:- 用于临时测试 打开cmd输入node回车,就可以开始敲你的"js"语句 输入一行执行一行
2、脚本模式 - 开发常用方式
建一个xx.js文件,里面书写您的"js"代码 ,
打开cmd输入node 完整的文件绝对路径,回车
3、随着编辑器慢慢的强大,我们编辑器有了插件:
前提:cmd可用,才能安装插件
1、HBuilder:node eclipse - 安装好了重启HBuilder,然后对着文件代码处右键运行
2、VSCode:code runner - 安装好了重启VSCode,然后对着文件代码处右键第一个选项就可以运行,或者 右上有个开始按钮
我们写的不是JavaScript只是和JavaScript长得很相似的Node.js
3、JavaScript和Node.js区别: 1、JavaScript:ES356+DOM+BOM 2、Node:ES356一切东西都可用,但是没有DOM和BOM,意味着他不是做特效,很多成百上千上万上几百万个【模块】等待我们学习
modal - 模态框/半透明遮罩层 model - 模型/数据 module - 模块
4、Node.js特有概念 - 模块 一个web项目功能可以分为很多个不同的模块,比如商品模块、用户模块、支付模块、促销模块、商家模块... node.js按照功能的不同,可以将函数、对象分别放到不同的文件/目录下,这些文件/目录在node.js中就称之为是一个模块,暂时可以简单理解为xx.js就是一个模块 1、*模块化开发:分工合作、明确责任 node底层其实有一句话,我们虽然看不见: (function(exports,require,三个){ //exports - {}空对象,放在此空对象里面的,向外部公开自己的成员 - 公开/暴露/导出 //require - 函数,引入其实模块 - 引入 //你写的代码 })()
1、*主模块 - 引入别的模块进行使用
var xx=require("./模块文件名");//xx就是别人公开的对象
特殊:./不可以省略
2、*分支/子模块 - 公开东西给别人使用
1、第一种方式:
exports.属性名=属性值;
exports.方法名=function(){};
2、第二种方式:
module.exports={
属性名:属性值,
方法名:function(){};
}
小练习:
1、呆老湿充当主模块
2、程海峰你负责给我提供两个方法,分别计算圆的周长和面积
3、万洪渝你负责给我提供两个方法,分别计算矩形的周长和面积
4、邹莹杰你负责给我提供两个方法,分别计算数组的求和和平均值
2、Node.js中模块的分类
1、官方模块 - 不需要下载安装,在你安装node.js环境的时候就已经安好了
2、第三方模块 - 需要用npm去下载,明天再玩,多的一批:mongoose(数据库)、express(Node的框架,简化原生Node的)
3、自定义模块:目前说白了就是一个xx.js
3、官方模块学习:
官方模块不确定要不要引入,理论来说需要观看官方文档,但是有为师在
1、global - 不需要引入的,可以直接使用的,全局对象依然可以省略不写
exports:用于向外导出自己的成员
require:引入其他模块
__filename:返回当前模块的文件绝对路径 - 全名
__dirname:返回当前模块的文件绝对路径但是不包含模块名 - 对vscode你们有的人有用:你可能在node.js某一处不允许使用相对路径,但是你写绝对路径又怕累,怎么办,就靠__dirname
module:指代当前模块本身!包含着以上4个操作
以下两个人不是当初的人,但是用法和当初一致
console:控制台对象
定时器:周期性和一次性和瞬间定时器
面试题:exports可以公开,那module.exports也可以公开,他们的区别在哪里?
node.js底层有一句话:var exports=module.exports;意味着两个人其实都可以公开/暴露
但是如果你用了这句话: exports={},就覆盖了上面module.exports这句话,不再具有公开暴露的功能了
真正具有公开功能的是module.exports
2、querystring - 查询字符串:解析前端传来的查询字符串(请求消息、前端发来的东西)部分
必须引入:var qs = require('querystring');
var obj=qs.parse("查询字符串部分")
垃圾:仅仅只能解析查询字符串部分,一个url可是由5个部分组成,url里面带有他,我们绝对不会单独使用此模块
3、***url - 解析前端传来的完整的url网址的各个部分
必须引入:var url = require('url');
var obj=url.parse("完整的url",true);//只要传入第二个实参true,则会自动调用querystring模块的parse方法解析查询字符串部分
尤其记住两点:明天有大用
*获取路由:obj.pathname;
*获取请求消息:obj.query.键名;
目的:node.js代码来搭建服务器&文件系统
nodejs最大的优点:速度快、node.js的速度是php的14倍,
官方模块: 1、buffer模块 - 缓冲区,本质是一块内存区域,用于暂存以后可能用到的数据(数字、字符串、二进制图片、视频、音频),该区域就称之为缓存 不需要引入的直接使用 //可以给想要的数据分配缓冲区,变成一个我们不认识的十六进制的一串数字 var buf=Buffer.from("hello world");
注意:buffer我们可以简单理解为是一个node.js新提供的数据类型,但不方便我们认识/看懂,此方法我们绝对不会手动使用,
但是node中的别的API可以执行了某个操作过后,就会返回我们一个buffer类型,也别怕,因为node中大部分API是支持直接使用buffer
2、fs模块 - 全称filesystem - 文件系统 - 小重点!
fs模块提供了对象文件系统中的文件进行读写的功能
需要引入:
var fs=require("fs");
//异步:不会卡住后续代码的,这块代码就算再耗时也无所谓,后续代码先跑了,我们慢慢做 - 异步才能发挥我们node.js的特点/优点
//*读取文件:
fs.readFile("文件路径",(err,buf)=>{
buf - 就是你读取到的东西,只不过自动转为了buffer类型
})
//写入文件:
fs.writeFile("文件路径","新内容"/buf,(err)=>{
//用于你写入完毕后要做什么
})
//追加文件:
fs.appendFile("文件路径","新内容"/buf,(err)=>{
//用于你写入完毕后要做什么
})
注意:vscode的部分同学可能不能再此处书写相对路径,只能写绝对路径__dirname
小练习:通过node.js代码把public/css/index.css【复制一份】public/css/index.backup.css
3、http模块 - 代码搭建http服务器 - 大重点
http:请求 - 响应模式,有请求才有响应,一个请求一个响应
功能:
1、可以接受前端发来的请求消息的
2、解析前端发来的请求消息
3、根据前端的需求我们回去去读请求到的文件,响应给他看
如何使用: 固定模块 //引入http、url、fs模块 var http=require("http"); var url=require("url"); var fs=require("fs"); //创建服务器应用 var app=http.createServer(); //设置服务器的监听端口号 app.listen(80); //为服务器绑定请求监听事件 - request:请求,想要触发请求事件,那必须前端来发起请求,我们都没有接收到请求自然不会执行 app.on("request",(req,res)=>{ //req - request:请求对象,有一个非常重要的属性,req.url可以得到前端传来的路由和请求消息!解析req.url,单独得到路由部分,通过判断前端的路由的不同的,做不同的响应 var objUrl=url.parse(req.url,true); //单独获取路由部分 var router=objUrl.pathname; //判断你的路由给你响应不同的内容 if(router=="/index.html" || router=="/"){ //res - response:响应对象,有一个非常重要的方法:res.end("后端想要给前端东西"),前端就不会一直转圈圈了 fs.readFile("./public/html/index.html",(err,buf)=>{ res.end(buf); }) }else if(router.match(/html/)!=null){//响应其他的html fs.readFile("./public/html"+router,(err,buf)=>{ res.end(buf); }) }else if(router.match(/css|js|jpg|png|gif|woff|woff2|ttf/)!=null){//响应其他的资源 fs.readFile("./public"+router,(err,buf)=>{ res.end(buf); }) } }) 特殊: 1、有的同学,可能写不了相对路径,必须书写绝对路径 2、一旦搭配服务器端不允许出现中文路径 3、以后会有更多的路由可能是跟数据库挂钩的
1、自定义模块:两种形式 学了这个你就知道为什么有的模块要加./引入,有的模块不用加./引入 1、*文件模块 创建一个xx.js,导出需要公开的数据,主模块想要引入必须写为require("./文件路径")
2、目录模块
方式1:创建一个文件夹,名为m1,其中再创建一个名为index.js的文件导出需要公开的数据,主模块想要引入必须写为require("./文件夹路径")
方式2:创建一个文件夹,名为m2,其中再创建一个名为xx.js的文件导出需要公开的数据,但是需要再创建一个必须名为package.json的配置文件写入:{"main":"xx.js"},主模块想要引入必须写为require("./文件夹路径")
*方式3:创建一个文件夹,必须名为node_modules,再在其中创建一个文件夹:名为m3,其中再创建一个名为index.js的文件导出需要公开的数据,主模块想要引入必须写为require("m3")
第三种方式看上去最屌,但是操作起来最麻烦,而且这个玩意儿根本不是给人用的,给机器自动生成的,理论上来说我们正式开发自己会使用的是文件模块
2、NPM:Node Package Manager:Node.js的第三方模块包/模块管理器:可用于下载、更新、删除、维护包的依赖关系 npm不需要下载安装,再你安装node.js的时候就已经安装好了 检查一下是否有npm:打开cmd:输入npm -v 如果有版本号出现说明你电脑里已经有了npm 打开npm官网:www.npmjs.org,搜索我想要的模块 下载:npm i 包名; 更新:npm up 包名; 删除:npm un 报名;
毕竟npm是国外的,下载速度可能很慢,你希望快一点可以先安装一个cnpm:
npm install cnpm -g --registry=https://registry.npmmirror.com
3、数据库:很多很多的跟网页/网站/软件/小程序挂钩的数据(新闻、产品、用户...) 关系型数据库:以表格形式为主 Oracle - Oracle公司(甲骨文) 适用于【企业级】开发市场:大公司、国企、事业单位(医院、警察局)。安全性极高
MySQL - Oracle公司(甲骨文)
适用于【互联网】开发市场:中小型公司、免费!
SQLServer - 微软:大学讲课
非关系型数据库 - 没有固定格式,是一种运动,反关系型数据库
mongoDB - 以JSON格式为主 - 免费!
吹牛逼:
MySQL/mongoDB一经退出立刻爆火
原因:免费 开源 简单
最初使用MySQL AB软点化公司推出,后来被收购sun公司,再后来sun公司又被oracle收购了
oracle
mysql - 社区版(免费)和 商业版(收费)
java
mongoDB:DATABASE - 数据库 1、安装&启动步骤: 1、解压呆老湿提供的mongodb-win32-x86_64-2008plus-ssl-3.6.11,放到哪里都可以 2、我们得到了一个bin文件夹里面有:mongo.exe(客户端) 和 mongod.exe(服务器端) 3、如何启动: 打开命令行:输入:.\mongod.exe --dbpath=你想要保存的绝对文件地址 - mongo数据库的服务器已经启动成功 千万不要关闭此命令行 再打开一个命令行:输入:.\mongo.exe - 再检查上一个命令行看看连接是否成功 - mongo数据库的客户端已经启动成功
2、mongo语法:都是运行在mongo客户端的命令行中 1、数据库操作: 1、查询数据库:show dbs 2、创建/切换数据库:use 数据库名称; 3、查看当前选中的数据库:db 4、创建数据表:db.createCollection("表名") - 一定要先创建表后,才能看到自己创建的数据库,不做限制 5、删除数据库:db.dropDatabase(); - 不要记忆,删除公司的数据库会坐牢3年起步
2、数据表操作:
1、创建数据表:db.createCollection("表名",{size:5242880,capped:true,max:5000}) - 最大存储空间为5mb,存储最多5000个数据,意味着做了一个限制,我不推荐
2、查看目前所有的数据表:db.getCollectionNames();
3、删除数据表:db.表名.drop();
3、数据操作:
1、增:db.表名.save({键值对,...}) - 一次只能插入一条数据
db.表名.save([{},{},{},{}]) - 一次插入多条数据
举例:
db.user.save([{"name":"猎魔人","age":18,"pwd":"666666","email":"zqh@qq.com"},{"name":"袍哥","age":19,"pwd":"999999","email":"pg@qq.com"},{"name":"袍哥","age":20,"pwd":"999999","email":"pg@qq.com"},{"name":"袍哥","age":21,"pwd":"999999","email":"pg@qq.com"},{"name":"袍哥","age":22,"pwd":"999999","email":"pg@qq.com"}])
2、删:db.表名.remove({}) - 会删除数据表中所有的数据,不推荐
db.表名.remove({pwd:"123123"}) - 只会删除数据库中pwd:123123的数据
3、改:db.表名.update({pwd:"999999"},{$set:{name:"xxx"}}) - 找到pwd为999999的,修改name为xxx
4、查:db.表名.find({}) - 所有
db.表名.find({age:18}) - 找到所有年龄为18的
db.表名.find({age:{$gt:19}}) - 找到所有年龄大于19的
db.表名.find({name:/正则/}) - 甚至可以写正则进行模糊查询
db.表名.find({},{name:1,pwd:1}) - 只需要name和pwd,其余的不要,1和0都相当于是开关(只要登录必拿用户名和密码)
db.表名.find().sort({age:1}) - 按照age升序排列,-1为降序(后端数据库排序了,前端就不必了)
db.表名.find().skip(2).limit(2) - 跳过前2条,再拿2条,可以立即理解为2-4条数据(只要做分页条)
db.表名.find().count() - 获取此表有多少条数据(只要做分页条)
数据库中一切的删除都要小心:一旦删除就回不来
学习mongo语句的目的,是为了下午和node.js(桥梁)进行搭配
3、安装mongodb-compass-1.33.1-win32-x64 数据库图形化界面 - 一般只用于查看,方便我们观看即可
Node.js操作mongoDB 1、安装mongoose第三方模块
2、使用步骤:
1、引入:var mongoose = require('mongoose');
2、服务器端【连接】数据库:mongoose.connect("mongodb://127.0.0.1/h52205");
3、创建/选择一个新的数据表的同时,设置数据类型的控制,防止用户乱输
//创建数据类型
const userSchema=mongoose.Schema({
name: String,
age: Number,
pwd: String
})
//创建数据表以及设置数据类型
// 模型名称
var User=mongoose.model("User",userSchema,"数据表名");
4、新增:
//使用模型/构造函数 - 创建出我们需要新增的对象
var user=new User({
name:"dy1",
age:20,
pwd:"123123"
})
//把创建好的对象,放到数据库中
user.save((err)=>{//回调函数:
console.log(err);//检查错误或者返回东西给前端
})
5、删除:
User.remove/deleteOne/deleteMany({age:18},(err)=>{//不推荐remove再mongoose第三方模块中已经被淘汰了,会有一个警告
console.log(err);//检查错误或者返回东西给前端
})
6、修改:
User.update/updateOne/updateMany({条件},{$set:{新内容}},(err)=>{//不推荐update再mongoose第三方模块中已经被淘汰了,会有一个警告
console.log(err);//检查错误或者返回东西给前端
})
7、查找:
User.find({条件-上午教你的},(err,result)=>{
console.log(result);
})
1、基本概念: 同步交互 客户端向服务器发起请求,直到服务器端响应的全过程,用户是不可以做其他事情的(等) 典型:网址请求、表单请求,这两种请求都会导致整个页面跳转 执行速度相对较慢,响应完整的HTML网页
异步交互
客户端向服务器发起请求,直到服务器端响应的全过程,用户是可以做其他事情的(不等)
典型:ajax请求,不严格的定义:客户端与服务器端进行交互,而无需刷新当前页面的技术,称之为ajax,局部发生了变化
执行速度相对较快,响应部分的HTML网页
AJAX - Asynchronous JavaScript And XML - 异步的javascript和xml
其实以前我们也见过一个异步技术:定时器,哪怕定时器的代码在耗时也不无所谓,他不会卡住后续代码,目的:做特效
今天我们学一个新的异步技术:ajax,目的:【没有表单的情况下】,也能和服务器端进行沟通 - 前端技术:有没有表单无所谓了
2、Ajax如何使用:4步 1、创建核心对象xhr var xhr=new XMLHttpRequest();
2、连接服务器:
xhr.open("GET/POST","随便路由");
3、发送请求消息:
xhr.send("key=value&pwd=value&...");
特殊:
1、如果你是GET请求方式,那么send失效,但是还不能省略必须写为send(null),你必须把你的请求消息放到url?后面
xhr.open("GET","随便路由?key=value&pwd=value&...");
xhr.send(null);
//找别人拿东西都用get
2、Node.js目前不允许使用POST,而且ajax的POST也麻烦 - 不准用
xhr.open("POST","随便路由")
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.send("随便路由key=value&pwd=value&...")
4、绑定监听状态事件
xhr.onreadystatechange=()=>{
if(xhr.readyState==4&&xhr.status==200){
console.log(xhr.responseText);//表单做不到,只有ajax可以做到 - 最难的点就在于,你拿到了数据,要干什么?
}
}
1、XML数据格式 1、面试题:HTML\XHTML\DHTML\XML分别是什么? HTML - 网页 XHTML - 更严格的网页,现在用到版本是HTML5,HTML5之前的版本就是XHTML,在之前才是HTML4.01 DHTML - 动态的网页,D:Dynamic - 不是新技术、新概念,只是将现有技术的整合统称:HTML+CSS+JS(dom),让我们的网页在离线版依然具有动态特效(依然是静态网页:不去修改的前提下,页面永远不会变化) XML - 配置文件|【数据格式】 其实保存数据有两种方式: 1、把数据放到数据库中 2、把数据保存在一个文件之中.xml文件 - 老土的、过时的
2、如何使用xml :未知的标记语言,一切的标签需要我们自行定义,没有任何预定义标签,目的:数据格式,不需要样式
1、创建xx.xml文件
2、必须写上一个声明标签:<?xml version="1.0" encoding="utf-8"?>
version - 版本号:目前有1.0和1.1,但是1.1升级不理想,市场上没人使用,学完过后以后也不需要在学了,他不会更新,淘汰了!被JSON格式代替了
3、必须写上【一个根标签】,必须是一个双标签,因为双标签才可以包含别的标签,标签名你随意,想写什么就写什么
4、里面随你,你想放什么就放什么
5、恭喜你学完了
依然玩全栈:
需要使用node.js搭建好服务器&静态资源(文件系统),根据前端请求读取你存储好的xml文件,响应给前端:
前端依然使用ajax去访问node.js,接住响应的XML数据:xhr.responseXML,得到一个DOM对象,可以使用核心DOM(既可以操作HTML又可以操作XML)来进行解析
这也就是最恶心的一点,核心DOM本来就是最麻烦的
2、JSON数据格式:JavaScript Object Notation:JS对象表示法,本来就属于JS的一部分,只不过现在火了,单独脱离出来让各大语言所支持 文本(字符串)数据格式,作用XML类似:更快、更简洁、更容易【解析】
1、哪些东西可以说是一个JSON字符串:- 认识哪些是JSON即可
1、'[1,2,3,4,5]';
2、'{"属性名":属性值}'
3、'[{},{},{},{}]' - 最常见的JSON就是它
4、'{"names":[张三,李四,王麻子],ages:[18,19,20]}'
Node.js后端要负责穿衣服:JSON.stringify(obj)
2、前端真的拿到了这个JSON字符串,并不方便我们获取里面的数据,学会JSON字符串脱衣服
1、eval("("+JSON字符串+")");
2、JSON.parse(JSON字符串);
1、jQueryUI框架:呆老师更爱称呼他是一个组件/插件库:基于Jquery的开源网页用户界面代码库 - 没必要学习jQuery,jQuery已经淘汰了,而且jQueryUI非常简单:提供了HTML/CSS/JS,你做的最多的一件事,复制粘贴 组件:组成网页一部分的部件(导航条、banner...); 插件:根组件差不多,但是带有生命JS(轮播、选项卡...);
在三大主流框架出现之前,jQuery就是全球最火的,从06-15年都是全最火的
三大框架:vue.js、react.js、angular.js(三阶段不学,中国市场用的少,北上广深杭10家用不到一家,重庆就更拉)
如何使用:不需要记忆
1、打开jQueryUI中文网
2、下载jQueryUI插件库,引入到你的项目之中:
<link rel="stylesheet" type="text/css" href="jquery-ui-1.13.2.custom/jquery-ui.css"/>
<script src="jquery-ui-1.13.2.custom/external/jquery/jquery.js" type="text/javascript" charset="utf-8"></script>
<script src="jquery-ui-1.13.2.custom/jquery-ui.js" type="text/javascript" charset="utf-8"></script>
3、挑选你喜欢的组件/插件:
个人推荐:
1、标签页/选项卡
2、菜单
3、折叠面板/手风琴
4、自动完成/模糊搜索
5、特效:$( "#div" ).toggle( "特效名称", 动画的时长 );
6、其余的特效可以自行玩玩
4、源代码可以复制过来:HTML+CSS+JS
5、根据设计图修改样式 - 如果你改了样式发现没生效,一定是因为优先级权重不够
6、使用ajax去获取数据库中的数据,然后来渲染此插件,最后再去调用jQueryUI提供的JS代码
2、layUI.js组件/插件库/框架: 使用方式几乎和jQueryUI一致:下载、引入、查看示例DEMO,但是比jQueryUI更漂亮 1、日期选择器 2、轮播
3、网站:jQuery插件库(登陆账号,一天可以免费下载两次) 和 jQuery之家(免费) 下载后解压,里面放着HTML和CSS和JS,复制到你的项目即可
目前为主:简化了各种各样的特效,网上一抓一大把,插件库(elementUI,VantUI); - 量大
客户端存储技术:3个 1、url网址后面可以跟着一个查询字符串,缺点:仅仅适合两个页面之间互传,但是不适合多页面传递 2、cookie:缺点:只能保存2kb,操作麻烦 3、webStorage:优点:大小8mb,操作非常简单:两部分 1、sessionStorage - 会话级:一旦关闭浏览器数据就死亡了 ! 2、localStorage - 本地级:只要不删除不清空,永远存在! 这两个对象都是不用我们创建的,浏览器自带
存储:xxxStorage.属性名=属性值;
获取:xxxStorage.属性名;
删除:xxxStorage.removeItem("属性名"); - 只能删一个
清空:xxxStorage.clear();
1、插件库的使用步骤: 1、打开jqueryUI、layUI、jQuery之家、jQuery插件库网站 2、去挑选你需要的插件 3、下载、引入(html+css+js) 4、根据设计图修改样式 5、根据数据库的数据重新渲染页面
2、html5 十大新特性:html5其实是一个概念,里面不光包含了标签,甚至还有一些js操作 - 老IE都是不支持的 1、新的语义化标签:header、footer、nav、section、aside 2、增强型表单:type="range/date/week/month/email/tel/url/color/number" 3、音频和视频 4、webStorage:客户端存储技术(sessionStorage和localStorage) 设置/添加:xxxStorage.属性名="属性值" 或者 xxxStorage.setItem("属性名","属性值") 获取/得到:xxxStorage.属性名 或者 xxxStorage.getItem("属性名") 删除一个:xxxStorage.removeItem("属性名"); 清空所有:xxxStorage.clear(); 5、canvas画图 - 用于做数据可视化(统计图),不会学习如何画图,因为我们程序员大部分人,没有学过美术,你画出来不会好看,三阶段会学习chart.js和echart.js框架 6、svg画图 - 几乎同上,用于画矢量图、实现小图标 7、web worker 8、web socket - 搭配上node.js的框架express:websocket直播、在线聊天、机器人、股票走势图实时应用 9、地图 - 百度地图、高德地图 10、拖拽事件 - jQueryUI一句话稿定
上午的目的: 1、完成无缝轮播 2、地图:固定步骤 1、打开百度:搜索百度地图开放平台 2、注册、登录:百度账号 3、拉到最下面,立即注册为开发者 4、百度地图控制台,点击应用管理->我的应用->创建应用 - 需要实名认证 5、创建应用:名称无所谓,应用类型选择浏览器端,白名单不做任何网站限制:写为0.0.0.0/0,提交,得到了密钥(AK) 6、鼠标放到导航条开发文档上,点击JavaScriptAPI,点击示例DEMO,挑选你喜欢的地图 7、百度地图有两个版本:普通版 和 webGL版本,而且不可以混搭使用
3、express:Node.js后端语言的框架两个核心概念: 1、路由 目的: 1、express搭建服务器&文件系统 2、前端->后端(表单、ajax - get、post)
如何使用:
1、第三方框架,下载:npm i express
2、写服务器代码引入:var express=require("express")
3、固定步骤:
var express=require("express");
//创建服务器
var app=express();
//绑定端口
app.listen(80);
//不需要绑定请求事件,有一个方法:直接判断路由,然后你要干什么
app.get("/",(req,res)=>{
//获取到前端发来的请求消息:ajax、表单(get)
req.query.键名
//响应数据给前端
res.send(数据库的数据)
//读取静态资源发送给用户观看
res.sendFile(__dirname+"/public/html/index.html");
})
//post如何操作?要麻烦一些,需要加上两句中间件操作,帮助我们解析post提交的东西,因为post不是显示提交,而是隐式提交
app.use(express.json())
app.use(express.urlencoded({ extended: false }))
app.post("/",(req,res)=>{
//获取到前端发来的请求消息:ajax、表单(get)
req.body.键名
//响应数据给前端
res.send(数据库的数据)
//读取静态资源发送给用户观看
res.sendFile(__dirname+"/public/html/index.html");
})
2、中间件
express是一个自身功能极简的框架,完全由路由和中间件构成的一个开发框架,从本质来说express就是要各种调用各种中间件
中间件是一个函数,他也可以访问请求对象(req),响应对象(res)。和web应用中处于请求 - 响应循环流程的中间部分,一般被命名为next的变量
中间件的功能包含:
执行任何代码
修改请求和响应对象
终止请求 - 响应循环,不会一直转圈圈了
调用下一个中间件
中间件的语法:
app.use("url",(req,res,next)=>{
//....中间件要执行代码
//next(); 放行:调用下一个中间件 或 路由
})
最大的作用:
1、除了post这两句话:
app.use(express.json())
app.use(express.urlencoded({ extended: false }))
2、加载其他静态资源
app.use(express.static("public"));
html5有十大新特性: websocket - 代码不复杂,重在理解 http协议:属于"请求 - 响应"模型,只有客户端发起请求消息,服务器端才能响应消息,没有请求就没有响应,一个请求,只能得到一个响应,有的场景下就力不从心了,比如:实施走势图、在线聊天室等等 解决:定时器 + ajax(心跳请求、长轮询) - 每过一段时间就请求一次,服务器压力太大,而且不够频繁
websocket协议:简称ws协议,属于"广播 - 收听"模型,客户端连接到服务器端就不会再断开了,永久的连接,【双方】可以随时随地随意向对方发送消息,且不是对等发送:WS完美解决上述问题
如何使用:以斗鱼为例:整体网站来说还是一个https协议的,但是呆老师说其中某一部分一定用到了ws协议
以我们的网站为例:整体网站来说还是一个http协议的,但是呆老师说其中某一部分一定用到了ws协议
1、WS服务器端:用node.js编写
使用步骤:
1、下载引入第三方模块ws
2、创建一个ws服务器端
var server=new ws.Server({port:端口号})
3、为服务器设置连接监听 - 只要有人来接上,就能知道
server.on("connection",(socket)=>{
socket.send("");//服务器端发送
socket.on("message",(data)=>{
var arr=[...server.clients];//server.clients记录着[当前服务器连接的客户端]有哪些(其实socket有很多个,我要对每个人都要说话),但是他是个set类型,我们没学过,所以将set类型转为了数组类型
data;//客户端发来的
})
})
2、WS客户端:用HTML编写
使用步骤:
1、连接WS服务器:
var socket=new WebSocket("ws:127.0.0.1:端口号");
2、听:
socket.onmessage=(e)=>{e.data//得到服务器端发送的东西}
3、说:
socket.send("");
作业:图书管理系统:HTML+CSS+JS+NODE+MONGO: 要求: 1、个人中心:修改密码+升级为超级vip 2、你书籍搞多点,做一个分页条,一页只显示4条,要5页,至少20条数据
扩展: 1、免费设计logo:U钙网,免费有点丑 2、sessionStorage:【客户端】存储技术,其实就是一个预定义对象,你可以往里面添加你想要放的东西 - 好处:只要浏览器不关闭,任何一个html页面都可以使用sessionStorage里面得东西 添加:sessionStorage.属性名=属性值; 获取:sessionStorage.属性名; 其实和查询字符串传输差不多,但是查询字符串传入解析麻烦,而且查询字符串只能传到下一个页面,除非每个页面单独穿一次
3、复杂思路
删除按钮:点击不会跳转页面,直接发ajax删除对应的那一本书籍,前端也要跟着一起删除
查看按钮:点击要先保存住书名再跳转到详情页,再详情页发起ajax拿去对应的那一本书籍的书名和内容,进行渲染展示 - 新闻
更新按钮:点击要先保存住书名再跳转到更新页,再详情页发起ajax拿去对应的那一本书籍的所有东西, 渲染到各个input上
点击更新按钮的时候表单提交到后端,后端再去修改数据库