BOM简介、Navigator、Location、History、定时器、调用栈(调用堆栈)、消息队列、定时器的本质——DOM

28 篇文章 0 订阅
21 篇文章 2 订阅

目录

一、BOM简介

二、Navigator

三、Location

四、History

五、定时器

六、调用栈(调用堆栈)

七、消息队列

八、定时器的本质

一、BOM简介

BOM

        - 浏览器对象模型

        - BOM为我们提供了一组对象,通过这组对象可以完成对浏览器的各种操作

        - BOM对象:

                - Window  —— 代表浏览器窗口(全局对象)

                - Navigator —— 浏览器对象(可以用来识别浏览器,如火狐、IE)

                - Location —— 浏览器的地址栏信息

                - History —— 浏览器的历史记录(控制浏览器的前进后退)

                - Screen —— 用户屏幕的信息

        - BOM对象都是作为 window 对象的属性保存的,所以可以直接在JS中访问这些对象

	<script>
		console.log(history);//访问history对象
		console.log(navigator);//访问navigator对象
	</script>

二、Navigator

Navigator —— 浏览器对象(可以用来识别浏览器,如火狐、IE)

Navigator 的属性和方法特别多,如果有需要可以去查看文档

https://developer.mozilla.org/en-US/docs/Web/API/Navigator

如 Navigator.language 用来读取用户浏览器页面的语言信息

Navigator.userAgent属性  返回一个用来描述浏览器信息的字符串

        通过该字符串可以检查出使用的浏览器

	<script>
		// 文档中的例子
		function getBrowserName(userAgent) {
  // The order matters here, and this may report false positives for unlisted browsers.

  if (userAgent.includes("Firefox")) {
    // "Mozilla/5.0 (X11; Linux i686; rv:104.0) Gecko/20100101 Firefox/104.0"
    return "Mozilla Firefox";
  } else if (userAgent.includes("SamsungBrowser")) {
    // "Mozilla/5.0 (Linux; Android 9; SAMSUNG SM-G955F Build/PPR1.180610.011) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/9.4 Chrome/67.0.3396.87 Mobile Safari/537.36"
    return "Samsung Internet";
  } else if (userAgent.includes("Opera") || userAgent.includes("OPR")) {
    // "Mozilla/5.0 (Macintosh; Intel Mac OS X 12_5_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36 OPR/90.0.4480.54"
    return "Opera";
  } else if (userAgent.includes("Trident")) {
    // "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729)"
    return "Microsoft Internet Explorer";
  } else if (userAgent.includes("Edge")) {
    // "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299"
    return "Microsoft Edge (Legacy)";
  } else if (userAgent.includes("Edg")) {
    // "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36 Edg/104.0.1293.70"
    return "Microsoft Edge (Chromium)";
  } else if (userAgent.includes("Chrome")) {
    // "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36"
    return "Google Chrome or Chromium";
  } else if (userAgent.includes("Safari")) {
    // "Mozilla/5.0 (iPhone; CPU iPhone OS 15_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6 Mobile/15E148 Safari/604.1"
    return "Apple Safari";
  } else {
    return "unknown";
  }
}

const browserName = getBrowserName(navigator.userAgent);
console.log(`You are using: ${browserName}`);
	</script>

三、Location

Location  表示的是浏览器的地址栏信息

        - 可以直接将location 的值修改为一个新的地址,这样会使网页发生跳转

        - location.assign( )  跳转到一个新的地址

        - location.replace( ) 使用新地址替换原地址(无法通过回退按钮回退)

        - location.reload( )  刷新页面,刷新页面,可以传递一个true,来强制清缓存刷新

        - location.href 可以获取当前的地址

<body>
	<button id="btn">点我一下</button>
	<form action="#">
		<input type="text" name="username" >
	</form>
	<!-- 在网页的在表单中输入数据时,在IE浏览器中点击刷新或使用location.reload()时,数据会消失,
		但在火狐浏览器中,不会消失,因为火狐浏览器会缓存输入的数据,
		若我们不想要这个缓存数据,可以在location.reload()中传入true ,表示强制清空缓存数据 -->
	<script>
		const btn = document.getElementById("btn")
		btn.addEventListener("click",()=>{
			console.log(location);
			// location = "https://www.baidu.com"//将location 的值修改为一个新的地址,这样会使网页发生跳转
			console.log(location.href); //  http://127.0.0.1:5500/html/index.html#
			// location.assign("https://www.baidu.com")//assign()方法也可以使地址发生跳转
			// location.replace("https://www.baidu.com")//assign()方法也可以使地址发生跳转
			location.reload(true)//刷新页面
		})
	</script>
</body>

四、History

History   浏览器的历史记录(控制浏览器的前进后退)

        - history.back( )  回退按钮

        - history.forward( )  前进按钮

        - history.go( )  可以向前跳转也可以向后跳转

                                当传入的参数为1时,等价于history.forward(),传入2时,表示前进2个...

                                当传入的参数为-1时,等价于history.back(),传入-2时,表示后退2个...

<body>
	<button id="btn">点我一下</button>
	<script>
		const btn = document.getElementById("btn")
		btn.onclick = function(){
			// console.log(history.length);
			// history.back()
			history.forward()
		}
	</script>
</body>

五、定时器

通过定时器,可以使代码在指定时间之后执行

        - 设置定时器的方式有两种:

                setTimeout( )(只会执行一次)

                        - 参数:

                                1. 回调函数(要执行的代码)

                                2. 间隔的时间(单位为毫秒)

                        - 返回:timeoutID是一个正整数值,它标识调用setTimeout()创建的计时器

                        - 关闭定时器

                                clearTimeout( timeoutID ) 

                setInterval( )(每间隔一段时间代码就会执行一次)

                        - 参数:

                                1. 回调函数(要执行的代码)

                                2. 间隔的时间(单位为毫秒)

                        - 返回:timeoutID是一个正整数值,它标识调用setInterval()创建的计时器

                        - 关闭定时器

                                clearInterval( timeoutID ) ,在关闭定时器时可以加上条件

在应用中,setTimeout( ) 使用得更多

<body>
	<h1 id="num"></h1>
	<script>
		// 设置接收计时器返回的timeoutID
		// const timer = setTimeout(()=>{
		// 	alert("我是定时器中的代码")
		// },3000)		
		// clearTimeout(timer)

		let num = 0
		const numH1 = document.getElementById("num")
		const timer1 = setInterval(()=>{
			num++
			numH1.textContent = num

			// 在关闭定时器时可以加上条件
			if(num === 20){
				clearInterval(timer1)
			}
		},1000)
		
	</script>
</body>

六、调用栈(调用堆栈)

事件循环(event loop)

        - 函数在每次执行时,都会产生一个执行环境

        - 执行环境负责存储函数执行时产生的一切数据(如局部变量、this等)

        - 问题:函数的执行环境要存储到哪里?

                - 函数的执行环境存储到了一个叫做调用栈的地方

                - 栈,是一种数据结构,特点:后进先出

        调用栈(call stack)

                - 调用栈负责存储函数的执行环境

                - 当一个函数被调用时,它的执行环境会作为一个栈帧插入到调用栈的栈顶

                        函数执行完毕其栈帧会自动从栈中弹出

调用栈(调用堆栈)放的都是正在执行的代码的函数

	<script>
		function fn(){
			let a = 10
			let b = 20
			function fn2(){
				console.log("fn2");
			}
			fn2()
			console.log("fn");
		}
		fn()
		console.log(123);
	</script>

 

七、消息队列

队列,也是一种数据结构,特点: 先进先出

消息队列

        - 消息队列负责存储将要执行的函数

        - 当我们触发一个事件时,其响应函数并不是直接就添加到调用栈中的

                因为调用栈中有可能会存在一些还没有执行完的代码

        - 事件触发后,JS引擎是将事件响应函数插入到消息队列中排队

<body>
	<button id="btn">点我一下</button>
	<button id="btn02">点我一下2</button>
	<script>
		function fn(){
			let a = 10
			let b = 20
			function fn2(){
				console.log("fn2");
			}
			fn2()
			console.log("fn");
		}
		fn()
		console.log(123);

		const btn = document.getElementById("btn")
		const btn02 = document.getElementById("btn02")
		btn.onclick = function (){
			alert(1111)

			const begin = Date.now()

			while(Date.now() - begin < 5000){}//会使点击按钮后出现alert,点击确定后停 5 秒之后再执行之后的
							// 因此,会导致点击按钮出现alert,确定后,点击按钮2,并不会立即执行,会过几秒再出来
			
		}
		btn02.onclick = function (){

			alert(2222)
		}
	</script>
</body>

 

八、定时器的本质 

定时器的本质,就是在指定时间后将函数添加到消息队列中 

使用concole.time( ) 和 concole.timeEnd( ) 来计算一段代码的执行时间

	<script>
		console.time()
		setTimeout(function(){
			console.timeEnd()//输出数为6 秒多,因为定时器的本质,就是在指定时间后将函数添加到消息队列中 
					// 我们在3秒后将该函数加入到消息队列中,但后面有一个循环使程序停了6 秒(全局)
					// 也就是要至少6 秒后才能进入调用栈中执行函数
			console.log("定时器执行了~~");
		},3000)

		// 使程序停止6 秒
		const begin = Date.now()
		while(Date.now() - begin < 6000){
		}
	</script>

setInterval( ) 每间隔一段时间就将函数添加到消息队列中,

        但是如果函数执行的速度比较慢,它是无法确保每次执行的间隔都是一样的

	<script>

		console.time("间隔")
		setInterval(function(){
			console.timeEnd("间隔")
			// console.log("定时器执行了");
			alert("定时器执行了")

			console.time("间隔")
		},3000)//每隔3 秒将其放到消息队列中
		// 假设该回调函数的代码执行时间较长,如6秒,并不是每隔3秒执行一次,
		// 而是每隔3秒将其放到消息队列中,待调用栈空了之后,依次执行
	</script>

希望可以确保函数每次执行都有相同间隔

	<script>
		console.time("间隔")
		setTimeout(function fn(){
			console.timeEnd("间隔")
			// console.log("函数执行了~~");
			alert("函数执行了~~");

			console.time("间隔")
			// 在setTimeout的回调函数的最后,再调用一个setTimeout
			setTimeout(fn,3000)
		},3000)

	</script>
	<script>
		setTimeout(()=>{
			console.log(1111);
		},0)
		console.log(2222);
		// 2222先出来,因为setTimeout为0表示立即将其添加到消息队列中,
		// 要等调用栈空出来后才能执行消息队列里的函数,而2222是在直接调用栈中

		// 上面代码打印为
		// 2222
		// 1111
	</script>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值