python 全栈开发,Day52(关于DOM操作的相关案例,JS中的面向对象,定时器,BOM,client、offset、scroll系列)
昨日作业讲解:
京东购物车
京东购物车效果:
实现原理:
用2个盒子,就可以完整效果。
先让上面的小盒子向下移动1px,此时就出现了压盖效果。小盒子设置z-index压盖大盒子,将小盒子的下边框去掉,就可以实现效果。
代码如下:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title></title>
- <style type="text/css">
- *{
- padding: 0;
- margin: 0;
- }
- /*背景盒子*/
- .box{
- width: 500px;
- height: 110px;
- margin: 100px auto;
- background-color: rgba(0,0,0,0.2);
- /*相对定位*/
- position: relative;
- }
- /*购物车*/
- .car{
- width: 150px;
- height: 30px;
- background-color: #fff;
- /*设置绝对定位,参考对象为box*/
- position: absolute;
- left: 200px;
- /*这里必须是3.1,如果是3,放大时,会看到细线*/
- top: 3.1px;
- /*设置元素的堆叠顺序*/
- z-index: 9;
- border: 1px solid green;
- }
- .shop{
- width: 310px;
- height: 70px;
- background-color: #fff;
- position: absolute;
- top:33px;
- left: 40px;
- border: 1px solid green;
- /*隐藏不显示*/
- display: none;
- }
- /*去掉底部的边框*/
- div.c{
- border-bottom-width: 0;
- }
- /*设置盒子边框*/
- div.t{
- border: 1px solid green;
- }
- </style>
- </head>
- <body>
- <div class="box">
- <div class="car" id="myCar">我的购物车</div>
- <div class="shop t" id="shop"></div>
- </div>
- <script type="text/javascript">
- var myCar = document.getElementById('myCar'); //小盒子
- var shop = document.getElementById('shop'); //大盒子
- //onmouseenter 事件在鼠标指针移动到元素上时触发
- myCar.onmouseenter = function(){
- shop.style.display = 'block'; //此元素将显示为块级元素
- myCar.className += ' c'; //去掉底部的边框
- }
- // onmouseleave 事件在鼠标移除元素时触发
- myCar.onmouseleave = function(){
- //大盒子隐藏
- shop.style.display = 'none'; //此元素不会被显示
- myCar.removeAttribute('class'); //删除class属性,此时有2个class,分别是car和c。都会被删除
- myCar.className = 'car'; //重新设置class为car,让它显示默认样式。
- }
- </script>
- </body>
- </html>
网页效果:
一、关于DOM操作的相关案例
1.模态框案例
需求:
打开网页时有一个普通的按钮,点击当前按钮显示一个背景图,中心并弹出一个弹出框,点击X的时候会关闭当前的模态框
第一种方法,先创建一个div,默认隐藏
第二种方法,使用dom,来创建div。
下面主要采用第二种方法,能把昨天学习的内容应用的到
代码如下:
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title></title>
- <style type="text/css">
- *{
- padding: 0;
- margin: 0;
- }
- html,body{
- height: 100%;
- }
- #box{
- width: 100%;
- height: 100%;
- background: rgba(0,0,0,.3);
- }
- #content{
- position: relative;
- top: 150px;
- width: 400px;
- height: 200px;
- line-height: 200px;
- text-align: center;
- color: red;
- background-color: #fff;
- margin: auto;
- }
- #span1{
- position: absolute;
- background-color: red;
- top: 0;
- right: 0;
- width: 30px;
- height: 30px;
- line-height: 30px;
- text-align: center;
- color: #fff;
- }
- </style>
- </head>
- <body>
- <button id="btn" style="margin-left: 50%">弹出</button>
- </body>
- <script type="text/javascript">
- //获取dom元素 1.获取事件源
- var oBtn = document.getElementById('btn');
- //创建弹出模态框的相关DOM对象
- var oDiv = document.createElement('div');
- var oP = document.createElement('p');
- var oSpan = document.createElement('span');
- // 设置属性
- oDiv.id = 'box';
- oP.id = 'content'
- oP.innerHTML = '模态框成功弹出'
- oSpan.innerHTML = 'X';
- oSpan.id = 'span1'
- // 追加元素
- oDiv.appendChild(oP);
- oP.appendChild(oSpan);
- // 点击弹出按钮 弹出模态框
- oBtn.onclick = function(){
- //动态的添加到body中一个div
- // insertBefore(插入的元素,参考节点)
- this.parentNode.insertBefore(oDiv,btn)
- }
- // 点击X 关闭模态框
- oSpan.onclick = function(){
- // 移除oDiv元素
- oDiv.parentNode.removeChild(oDiv) //由于div有多个元素,直接移除整个div即可
- }
- </script>
- </html>
网页效果:
2.简易留言板
需求:
当在textarea中输入内容,点击留言按钮,会添加到浏览器中
图如下:
图如下:
代码如下:
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>留言板</title>
- <style type="text/css">
- *{
- padding: 0;
- margin: 0;
- }
- /*去掉默认的ul样式*/
- ul {
- list-style: none;
- }
- .close{
- /*inline-block 通俗来讲,不独占一行的块级元素*/
- display: inline-block;
- width: 20px;
- height: 20px;
- line-height: 20px;
- text-align: center;
- /*cursor显示的指针(光标)的类型
- pointer 光标呈现为指示链接的指针(一只手)
- */
- cursor: pointer;
- background-color: rgba(0,0,0,.1);
- margin-left: 20px;
- }
- </style>
- </head>
- <body>
- <div style="margin-left: 20px">
- <h1>简易留言板</h1>
- <div id="box">
- <!--<ul></ul>-->
- </div>
- <textarea id="msg"></textarea>
- <input type="button" id="btn" value="留言"/>
- <button onclick="sum()">统计</button>
- </div>
- </body>
- <script type="text/javascript">
- // 0 将ul标签添加到div#box标签中
- var oUl = document.createElement('ul'); //创建ul标签
- var oBox = document.getElementById('box'); //获取box对象
- oBox.appendChild(oUl); //添加到box中
- var oBtn = document.getElementById('btn'); //获取btn对象
- var oMsg = document.getElementById('msg')
- // 控制留言的总数量
- var count = 0; //默认为0
- oBtn.onclick = function(){
- // 点击留言按钮事件操作
- // 1.创建li标签
- var oLi = document.createElement('li');
- //2.设置内容
- oLi.innerHTML = oMsg.value + "<span class='close'>X</span>" //输入框内容+X图标
- // 3.如果想在插入的第一个li获取的前面继续添加li标签
- //3.1 获取li标签
- var olis = document.getElementsByTagName('li');
- //3.2 如果是第一次添加的li标签,则直接添加到ul的后面
- if(olis.length == 0){ //默认长度为0
- oUl.appendChild(oLi);
- count++; //统计留言个数
- }else{
- // 3.3 如果不是第一次添加的li标签,则插入到第一个li标签的前面
- oUl.insertBefore(oLi,olis[0]);
- count++;
- }
- // 4.添加完成之后 清空textarea的值
- oMsg.value = '';
- // 5.点击X的时候删除当前的一条数据
- //5.1 先获取所有的X
- var oSpans = document.getElementsByTagName('span');
- // 5.2 for循环 对所有的X添加点击事件
- for(var i = 0; i< oSpans.length; i++){
- oSpans[i].onclick = function(){
- // 5.3 移除当前的li标签
- oUl.removeChild(this.parentNode)
- count--; //统计结果减1
- }
- }
- }
- //显示统计结果
- function sum(){
- alert('一共发布了'+count+'条留言');
- }
- </script>
- </html>
网页效果:
3.使用js模拟选择器中hover
- <!DOCTYPE html>
- <html>
- <head lang="en">
- <meta charset="UTF-8">
- <title></title>
- <style>
- button {
- margin: 10px;
- width: 100px;
- height: 40px;
- /*设置光标为一只手*/
- cursor: pointer;
- }
- /*背景颜色*/
- .current {
- background-color: red;
- }
- </style>
- </head>
- <body>
- <button>按钮1</button>
- <button>按钮2</button>
- <button>按钮3</button>
- <button>按钮4</button>
- <button>按钮5</button>
- <script>
- //需求:鼠标放到哪个button上,改button变成黄色背景(添加类)
- //获取button按钮
- var btnArr = document.getElementsByTagName("button");
- //绑定事件
- for(var i=0;i<btnArr.length;i++){ //要为每一个按钮绑定事件,所以用到了for循环
- btnArr[i].onmouseover = function () {
- //【重要】排他思想:先把所有按钮的className设置为空,然后把我(this)这个按钮的className设置为current
- //排他思想和for循环连用
- for(var j=0;j<btnArr.length;j++){
- btnArr[j].className = ""; //清空class
- }
- this.className = "current"; //【重要】核心代码
- }
- }
- //鼠标离开current时,还原背景色
- for(var i=0;i<btnArr.length;i++){ //要为每一个按钮绑定事件,所以用到了for循环
- btnArr[i].onmouseout = function () { //鼠标离开任何一个按钮时,就把按钮的背景色还原
- this.className = ""; //清空class
- }
- }
- </script>
- </body>
- </html>
代码解释:
鼠标悬停时,current栏变色,这里用到了排他思想:先把所有按钮的className设置为空,然后把我(this)这个按钮的className设置为current,就可以达到变色的效果。核心代码是:
- //排他思想:先把所有按钮的className设置为空,然后把我(this)这个按钮的className设置为current
- //排他思想和for循环连用
- for(var j=0;j<btnArr.length;j++){
- btnArr[j].className = "";
- }
- this.className = "current";
网页效果:
4.tab栏选项卡
代码如下:
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title></title>
- <style type="text/css">
- *{
- padding: 0;
- margin: 0;
- }
- /*去除ul默认样式*/
- ul{
- list-style: none;
- }
- #tab{
- width: 480px;
- margin: 20px auto;
- border: 1px solid red;
- }
- ul{
- width: 100%;
- /*清除浮动*/
- overflow: hidden;
- }
- ul li{
- float: left;
- width: 160px;
- height: 60px;
- line-height: 60px;
- text-align: center;
- background-color: #cccccc;
- }
- ul li a{
- /*去除a标签下划线*/
- text-decoration: none;
- /*颜色为黑色*/
- color:black;
- }
- li.active{
- background-color: red;
- }
- /*隐藏P标签*/
- p{
- display: none;
- height: 200px;
- text-align: center;
- line-height: 200px;
- background-color: red;
- }
- /*显示P标签*/
- p.active{
- display: block;
- }
- </style>
- </head>
- <body>
- <div id="tab">
- <ul>
- <li class="active">
- <a href="#">首页</a>
- </li>
- <li>
- <a href="#">新闻</a>
- </li>
- <li>
- <a href="#">图片</a>
- </li>
- </ul>
- <p class="active">首页内容</p>
- <p>新闻内容</p>
- <p>图片内容</p>
- </div>
- </body>
- <script type="text/javascript">
- window.onload = function(){
- // //需求:鼠标放到上面的li上,li本身变色(添加类),对应的p也显示出来(添加类);
- //思路:1.点亮上面的盒子。 2.利用索引值显示下面的盒子。
- var tabli = document.getElementsByTagName('li'); //获取li标签
- var tabContent = document.getElementsByTagName('p') //获取p标签
- for(var i = 0; i < tabli.length; i++){
- // 绑定索引值(新增一个自定义属性:index属性)
- //下面的绑定事件无法直接获取i,所以这里定义了一个属性i,让它成为全局变量
- tabli[i].index = i;
- // 绑定点击事件
- tabli[i].onclick = function(){
- // 1.点亮上面的盒子。 2.利用索引值显示下面的盒子。(排他思想)
- for(var j = 0; j < tabli.length; j++){
- tabli[j].className = ''; //清空li标签的class
- tabContent[j].className = ''; //清空p标签的class,那么p标签会隐藏
- }
- this.className = 'active' //li标签显示背景颜色
- //p标签设置class为active,表示显示p标签
- tabContent[this.index].className = 'active';//【重要代码】
- }
- }
- }
- </script>
- </html>
网页效果:
一个{}表示一个作用域,多个作用域之间的变量是不能直接引用的。怎么办呢?
将变量设置为全局变量,就可以调用了。
虽然事件的作用域在for循环的下面,但是它们是2个不同的作用域,不能调用i
所以上面的代码中,加了一行,就是为了解决这个问题的。
- tabli[i].index = i;
5、购物车案例
请参考上面的作业讲解
二、JS中的面向对象
js中没有class 的概念,它是一个伪面向对象。因为它没有多态!
创建对象的几种常用方式
1.使用Object或对象字面量创建对象
2.工厂模式创建对象
3.构造函数模式创建对象
4.原型模式创建对象
1.使用Object或对象字面量创建对象
JS中最基本创建对象的方式:
- var student = new Object();
- student.name = "easy";
- student.age = "20";
- console.log(student);
查看结果:
这样,一个student对象就创建完毕,拥有2个属性name
以及age
,分别赋值为"easy"
和20
。
如果你嫌这种方法有一种封装性不良的感觉。来一个对象字面量方式创建对象。
- var student = {
- name : "easy",
- age : 20
- };
- console.log(student);
查看结果,效果同上!
这样看起来似乎就完美了。但是马上我们就会发现一个十分尖锐的问题:当我们要创建同类的student1,student2,…,studentn时,我们不得不将以上的代码重复n次....
- var sutdent1 = {
- name : "easy1",
- age : 20
- };
- var sutdent2 = {
- name : "easy2",
- age : 20
- };
- ...
- var sutdentn = {
- name : "easyn",
- age : 20
- };
有个提问?能不能像工厂车间那样,有一个车床就不断生产出对象呢?我们看”工厂模式”。
2.工厂模式创建对象
JS中没有类的概念,那么我们不妨就使用一种函数将以上对象创建过程封装起来以便于重复调用,同时可以给出特定接口来初始化对象
- function createStudent(name, age) {
- var obj = new Object();
- obj.name = name;
- obj.age = age;
- return obj;
- }
- var student1 = createStudent("easy1", 20);
- var student2 = createStudent("easy2", 20);
- ...
- var studentn = createStudent("easyn", 20);
这样一来我们就可以通过createStudent函数源源不断地”生产”对象了。看起来已经高枕无忧了,但贪婪的人类总有不满足于现状的天性:我们不仅希望”产品”的生产可以像工厂车间一般源源不断,我们还想知道生产的产品究竟是哪一种类型的。
比如说,我们同时又定义了”生产”水果对象的createFruit()函数:
- function createFruit(name, color) {
- var obj = new Object();
- obj.name = name;
- obj.color = color;
- return obj;
- }
- var v1 = createStudent("easy1", 20);
- var v2 = createFruit("apple", "green");
对于以上代码创建的对象v1、v2,我们用instanceof操作符去检测,他们统统都是Object类型。我们的当然不满足于此,我们希望v1是Student类型的,而v2是Fruit类型的。为了实现这个目标,我们可以用自定义构造函数的方法来创建对象
3.构造函数模式创建对象
在上面创建Object这样的原生对象的时候,我们就使用过其构造函数:
- var obj = new Object();
在创建原生数组Array类型对象时也使用过其构造函数:
- var arr = new Array(10); //构造一个初始长度为10的数组对象
在进行自定义构造函数创建对象之前,我们首先了解一下构造函数
和普通函数
有什么区别。
1、实际上并不存在创建构造函数的特殊语法,其与普通函数唯一的区别在于调用方法。对于任意函数,使用new操作符调用,那么它就是构造函数;不使用new操作符调用,那么它就是普通函数。
2、按照惯例,我们约定构造函数名以大写字母开头,普通函数以小写字母开头,这样有利于显性区分二者。例如上面的new Array(),new Object()。
3、使用new操作符调用构造函数时,会经历(1)创建一个新对象;(2)将构造函数作用域赋给新对象(使this指向该新对象);(3)执行构造函数代码;(4)返回新对象;4个阶段。
ok,了解了构造函数
和普通函数
的区别之后,我们使用构造函数将工厂模式
的函数重写,并添加一个方法属性:
- function Student(name, age) {
- this.name = name;
- this.age = age;
- this.alertName = function(){
- alert(this.name)
- };
- }
- function Fruit(name, color) {
- this.name = name;
- this.color = color;
- this.alertName = function(){
- alert(this.name)
- };
- }
这样我们再分别创建Student和Fruit的对象:
- var v1 = new Student("easy", 20);
- var v2 = new Fruit("apple", "green");
这时我们再来用instanceof操作符来检测以上对象类型就可以区分出Student以及Fruit了:
- alert(v1 instanceof Student); //true
- alert(v2 instanceof Student); //false
- alert(v1 instanceof Fruit); //false
- alert(v2 instanceof Fruit); //true
- alert(v1 instanceof Object); //true 任何对象均继承自Object
- alert(v2 instanceof Object); //true 任何对象均继承自Object
这样我们就解决了工厂模式
无法区分对象类型的尴尬。那么使用构造方法来创建对象是否已经完美了呢?使用构造器函数通常在js中我们来创建对象。
我们会发现Student和Fruit对象中共有同样的方法,当我们进行调用的时候这无疑是内存的消耗。
我们完全可以在执行该函数的时候再这样做,办法是将对象方法移到构造函数外部:
- function Student(name, age) {
- this.name = name;
- this.age = age;
- this.alertName = alertName;
- }
- function alertName() {
- alert(this.name);
- }
- var stu1 = new Student("easy1", 20);
- var stu2 = new Student("easy2", 20);
在调用stu1.alertName()时,this对象才被绑定到stu1上。
我们通过将alertName()函数定义为全局函数,这样对象中的alertName属性则被设置为指向该全局函数的指针。由此stu1和stu2共享了该全局函数,解决了内存浪费的问题
但是,通过全局函数的方式解决对象内部共享的问题,终究不像一个好的解决方法。如果这样定义的全局函数多了,我们想要将自定义对象封装的初衷便几乎无法实现了。更好的方案是通过原型对象模式来解决。
4.原型的模式创建对象
原型链甚至原型继承,是整个JS中最难的一部分也是最不好理解的一部分,在这里由于我们课程定位的原因,如果对js有兴趣的同学,可以去查阅一下相关JS原型的一些知识点。更加有助于你以后前端JS的面试。
- //var arry = new Array()
- function Student() {
- // Student this指的就是当前对象 设置对象的属性
- this.name = 'easy';
- this.age = 20;
- }
- // 伪面向对象 多态
- Student.prototype.alertName = function(){
- console.log(this.name);
- };
- Student.prototype.showAge = function(){
- console.log(this.age);
- }
- var stu1 = new Student();
- var stu2 = new Student();
- console.log(stu1);
- stu1.alertName(); //easy
- stu2.alertName(); //easy
- stu1.showAge(); //20
- console.log(stu1.alertName == stu2.alertName); //true 二者共享同一函数
查看结果:
第4种方式和第1种方式中的红色部分,都要熟练掌握。其他方式,仅做了解。
三、定时器
在js中的定时器分两种:1、setTimeout() 2、setInterval()
这2种方式,都很常用的。setTimeout只能执行一次,它是异步的。
事件操作,是属于异步的。
举例:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title></title>
- </head>
- <body>
- <div id="app" style="width: 100px;height: 100px;border: 1px solid red;"></div>
- <script type="text/javascript">
- console.log(111);
- document.getElementById('app').onclick = function () {
- console.log(222);
- }
- console.log(333);
- </script>
- </body>
- </html>
查看console,当点击红框的时候,才输出222,说明事件是异步执行的。触发时,才执行。
1.setTimeOut()
只在指定时间后执行一次
- //定时器 异步运行
- function hello(){
- alert("hello");
- }
- //使用方法名字执行方法
- var t1 = window.setTimeout(hello,1000);
- var t2 = window.setTimeout("hello()",3000);//使用字符串执行方法
- window.clearTimeout(t1);//去掉定时器
访问网页,等待1秒后,弹框
举例:
- console.log(111);
- //一般是这种写法,funciton就是回调函数
- setTimeout(function () {
- console.log(222);
- },1000);
- console.log(333);
查看console,等待1秒后输出222
2.setInterval()
在指定时间为周期循环执行
- /实时刷新 时间单位为毫秒
- setInterval('refreshQuery()',8000);
- /* 刷新查询 */
- function refreshQuery(){
- console.log('每8秒调一次')
- }
两种方法根据不同的场景和业务需求择而取之,
对于这两个方法,需要注意的是如果要求在每隔一个固定的时间间隔后就精确地执行某动作,那么最好使用setInterval,而如果不想由于连续调用产生互相干扰的问题,尤其是每次函数的调用需要繁重的计算以及很长的处理时间,那么最好使用setTimeout
让一个div匀速运动
代码如下:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title></title>
- </head>
- <body>
- <div id="app" style="width: 100px;height: 100px;border: 1px solid red;"></div>
- <button id="move">移动</button>
- <script type="text/javascript">
- var oApp = document.getElementById('app'); //获取div对象
- var moveBtn = document.getElementById('move'); //获取button
- var count = 0; //初始步数
- var timer = null; //定义一个空对象
- moveBtn.onclick = function(){
- timer = setInterval(function(){
- //控制步距
- count+=3;
- //当移动到500px时,停止运动
- if (count>=500) {
- clearInterval(timer); //去掉定时器
- }
- console.log(count); //打印步数
- oApp.style.marginLeft = count + 'px';
- },30); //30表示30微秒
- }
- </script>
- </body>
- </html>
网页效果:
定时器有一个弊端,它会消耗内存
在某个时机,要清理定时器!
尽量少用定时器,常用的还是setTimeout
思考题,移动到某个位置,比如500,再弹回来
四、BOM
bom用的很少,仅做了解
BOM的介绍
JavaScript基础分为三个部分:
ECMAScript:JavaScript的语法标准。包括变量、表达式、运算符、函数、if语句、for语句等。
DOM:文档对象模型,操作网页上的元素的API。比如让盒子移动、变色、轮播图等。
BOM:浏览器对象模型,操作浏览器部分功能的API。比如让浏览器自动滚动。
什么是BOM
BOM:Browser Object Model,浏览器对象模型。
BOM的结构图:
从上图也可以看出:
window对象是BOM的顶层(核心)对象,所有对象都是通过它延伸出来的,也可以称为window的子对象。
DOM是BOM的一部分。
window对象:
window对象是JavaScript中的顶级对象。
全局变量、自定义函数也是window对象的属性和方法。
window对象下的属性和方法调用时,可以省略window。
下面讲一下 BOM 的常见内置方法和内置对象。
弹出系统对话框
比如说,alert(1)
是window.alert(1)
的简写,因为它是window的子方法。
系统对话框有三种:
- alert(); //不同浏览器中的外观是不一样的
- confirm(); //兼容不好
- prompt(); //不推荐使用
confirm举例
如果点击确定,查看console。输出true,否则为false
那么就可以进行相应的操作了。默认的页面无法修改,你认为它丑也没有办法。
一般用模态框来做,可以自定义。
打开窗口、关闭窗口
1、打开窗口:
- window.open(url,target);
参数解释:
url:要打开的地址。
target:新窗口的位置。可以是:
_blank
、_self
、_parent
父框架。
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title></title>
- </head>
- <body>
- <!--行间的js中的open() window不能省略-->
- <button onclick="window.open('https://www.luffycity.com/')">路飞学城</button>
- <button>打开百度</button>
- <!--强制关闭-->
- <button onclick="window.close()">关闭</button>
- <!--有提示框的关闭-->
- <button>关闭</button>
- </body>
- <script type="text/javascript">
- var oBtn = document.getElementsByTagName('button')[1]; //强制关闭的按钮
- var closeBtn = document.getElementsByTagName('button')[3]; //带提示框的关闭按钮
- oBtn.onclick = function(){
- //open('https://www.baidu.com')
- //打开空白页面
- open('about:blank',"_self")
- }
- closeBtn.onclick = function(){
- if(confirm("是否关闭?")){
- close();
- }
- }
- </script>
- </html>
默认是_blank,表示新窗口打开。
访问网页,点击按钮,就可以跳转网页了
阻止a标签跳转有2个方法
1.使用javascript:;
- <a href="javascript:;">百度</a>
2.使用js的preventDefault方法
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title></title>
- </head>
- <body>
- <a href="http://www.baidu.com" id="baidu">百度</a>
- </body>
- <script type="text/javascript">
- var baidu = document.getElementById('baidu');
- //绑定点击事件
- baidu.onclick = function (e) {
- //阻止a标签的默认跳转
- e.preventDefault();
- //跳转到淘宝页面
- window.open('http://www.taobao.com')
- }
- </script>
- </html>
访问网页,点击百度,就会跳转到指定页面,比如淘宝
location对象
location只做了解
window.location
可以简写成location。location相当于浏览器地址栏,可以将url解析成独立的片段。
location对象的属性
href:跳转
hash 返回url中#后面的内容,包含#
host 主机名,包括端口
hostname 主机名
pathname url中的路径部分
protocol 协议 一般是http、https
search 查询字符串
location.href属性举例:
举例1:点击盒子时,进行跳转。
- <body>
- <div>smyhvae</div>
- <script>
- var div = document.getElementsByTagName("div")[0];
- div.onclick = function () {
- location.href = "http://www.baidu.com"; //点击div时,跳转到指定链接
- // window.open("http://www.baidu.com","_blank"); //方式二
- }
- </script>
- </body>
举例2:5秒后自动跳转到百度。
有时候,当我们访问一个不存在的网页时,会提示5秒后自动跳转到指定页面,此时就可以用到location。举例:
- <script>
- setTimeout(function () {
- location.href = "http://www.baidu.com";
- }, 5000);
- </script>
如果使用file:///C:/Users/xiao/bom.html这种方式访问时,是无法获取host,hostname,pathname...这些属性的
使用Pycharm或者webstom,它自带有一个web服务器,那么就可以得到这些信息
- <!DOCTYPE html>
- <html>
- <head lang="en">
- <meta charset="UTF-8">
- <title></title>
- </head>
- <body>
- <script type="text/javascript">
- console.log(location.host);
- console.log(location.hostname);
- console.log(location.pathname);
- console.log(location.protocol);
- console.log(location.search);
- </script>
- </body>
- </html>
访问网页,查看console
location对象的方法
location.reload():重新加载
- setTimeout(function(){
- //3秒之后让网页整个刷新
- window.location.reload();
- },3000)
这个方法很少用,一般会用到局部刷新,后面的django课程会讲到
navigator对象
window.navigator 的一些属性可以获取客户端的一些信息。
userAgent:系统,浏览器)
platform:浏览器支持的系统,win/mac/linux
例子:
- console.log(navigator.userAgent);
- console.log(navigator.platform);
查看网页console
userAgent这个是很重要,爬虫会用到它,以及后面的B/S架构
查看请求头
history对象
1、后退:
history.back()
history.go(-1):0是刷新
2、前进:
history.forward()
history.go(1)
用的不多。因为浏览器中已经自带了这些功能的按钮
五、client、offset、scroll系列
1、client系列
代码如下:
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title></title>
- <style type="text/css">
- .box{
- width: 200px;
- height: 200px;
- position: absolute;
- border: 10px solid red;
- /*margin: 10px 0px 0px 0px;*/
- padding: 80px;
- }
- </style>
- </head>
- <body>
- <div class="box">
- 哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈
- </div>
- </body>
- <script type="text/javascript">
- /*
- * clientTop 内容区域到边框顶部的距离 ,说白了,就是边框的高度
- * clientLeft 内容区域到边框左部的距离,说白了就是边框的乱度
- * clientWidth 内容区域+左右padding 可视宽度
- * clientHeight 内容区域+ 上下padding 可视高度
- * */
- var oBox = document.getElementsByClassName('box')[0];
- console.log(oBox.clientTop);
- console.log(oBox.clientLeft);
- console.log(oBox.clientWidth);
- console.log(oBox.clientHeight);
- </script>
- </html>
这些属性是在dom操作的,client用的不是很多
内容区域是包含padding的,父相子绝无视padding
访问网页:
查看console
2.屏幕的可视区域
这个很少用
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title></title>
- </head>
- <body>
- </body>
- <script type="text/javascript">
- // 屏幕的可视区域
- window.onload = function(){
- // document.documentElement 获取的是html标签
- console.log(document.documentElement.clientWidth);
- console.log(document.documentElement.clientHeight);
- // 窗口大小发生变化时,会调用此方法
- window.onresize = function(){
- console.log(document.documentElement.clientWidth);
- console.log(document.documentElement.clientHeight);
- }
- }
- </script>
- </html>
查看console。将网页窗口方法,缩小时,console里面的数值,会发生变化。
3.offset系列
offset表示偏移,这个是重点,用的比较多。
代码如下,注释都挺清楚的
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title></title>
- <style type="text/css">
- *{
- padding: 0;
- margin: 0;
- }
- </style>
- </head>
- <body style="height: 2000px">
- <div>
- <div class="wrap" style=" width: 300px;height: 300px;background-color: green">
- <div id="box" style="width: 200px;height: 200px;border: 5px solid red;position: absolute;top:50px;left: 30px;">
- </div>
- </div>
- </div>
- </body>
- <script type="text/javascript">
- window.onload = function(){
- var box = document.getElementById('box')
- /*
- offsetWidth占位宽 内容+padding+border
- offsetHeight占位高
- * offsetTop: 如果盒子没有设置定位 到body的顶部的距离,如果盒子设置定位,那么是以父辈为基准的top值
- * offsetLeft: 如果盒子没有设置定位 到body的左部的距离,如果盒子设置定位,那么是以父辈为基准的left值
- * */
- console.log(box.offsetTop)
- console.log(box.offsetLeft)
- console.log(box.offsetWidth)
- console.log(box.offsetHeight)
- }
- </script>
- </html>
访问网页
查看console
4.scroll系列
scroll表示滚动,这个用的也比较多
代码如下:
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title></title>
- <style type="text/css">
- *{padding: 0;margin: 0;}
- </style>
- </head>
- <body style="width: 2000px;height: 2000px;">
- <div style="height: 200px;background-color: red;"></div>
- <div style="height: 200px;background-color: green;"></div>
- <div style="height: 200px;background-color: yellow;"></div>
- <div style="height: 200px;background-color: blue;"></div>
- <div style="height: 200px;background-color: gray;"></div>
- <div id = 'scroll' style="width: 200px;height: 200px;border: 1px solid red;overflow: auto;padding: 10px;margin: 5px 0px 0px 0px;">
- <p>路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城
- 路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城
- 路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城
- 路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城
- </p>
- </div>
- </body>
- <script type="text/javascript">
- window.onload = function(){
- //实施监听滚动事件
- window.onscroll = function(){
- console.log('上'+document.documentElement.scrollTop)
- console.log('左'+document.documentElement.scrollLeft)
- console.log('宽'+document.documentElement.scrollWidth)
- console.log('高'+document.documentElement.scrollHeight)
- }
- var s = document.getElementById('scroll');
- s.onscroll = function(){
- // scrollHeight : 内容的高度+padding 不包含边框
- console.log('上'+s.scrollTop)
- console.log('左'+s.scrollLeft)
- console.log('宽'+s.scrollWidth)
- console.log('高'+s.scrollHeight)
- }
- }
- </script>
- </html>
查看网页:
只要滚动窗口,console的数值,就会发生变化。小窗口的进度条,拉动,也会发生变化
今日作业,淘宝的滚动监听
当精度条,拉到指定位置时。出现搜索框,它的位置是固定的,并且覆盖页面内容。
需要用到scroll
思路:
实时监听当前页面的页面滚动事件,使用window.onscroll
获取滚动条位置,使用document.documentElement.scrollTop
当滚动条位置大于等于150时,设置搜索框对应的属性,让它能够固定,使用position: fixed加上z-index:999
代码如下:
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title></title>
- <style type="text/css">
- * {
- padding: 0;
- margin: 0;
- }
- ul {
- list-style: none;
- }
- .nav {
- width: 100%;
- height: 40px;
- background-color: purple;
- /*position: fixed;*/
- top: 0;
- left: 0;
- /*z-index: 99999;*/
- }
- .wrap {
- width: 960px;
- overflow: hidden;
- margin: 0px auto;
- background-color: purple;
- border-radius: 5px;
- }
- .wrap ul li {
- float: left;
- width: 160px;
- height: 20px;
- line-height: 40px;
- text-align: center;
- }
- .wrap ul li a {
- width: 160px;
- height: 40px;
- display: block;
- color: white;
- font-size: 14px;
- text-decoration: none;
- }
- .wrap ul li a:hover {
- background: yellow;
- color: green;
- text-decoration: underline;
- }
- .pass-text-input {
- height: 16px;
- padding: 11px 10px;
- margin-right: 10px;
- border: 1px solid #ddd;
- font-size: 14px;
- color: #666;
- }
- .text-input-length{
- width: 328px;
- }
- .pass-label {
- #display: block;
- #float: left;
- height: 42px;
- width: 65px;
- margin-right: 10px;
- line-height: 42px;
- font-size: 14px;
- color: #666;
- font-weight: 700;
- text-align: right;
- }
- /*默认样式*/
- .inp_default {
- text-align: center;background-color: #2ae0c8;z-index: 999;
- }
- /*居中样式*/
- .inp_center {
- margin-top: -50px;text-align: center;background-color: rgb(255,85,0);z-index: 999;position: fixed;width: 100%;
- }
- </style>
- </head>
- <body>
- <div id = 'scroll'>
- <div class="nav">
- <div class="wrap">
- <ul>
- <li>
- <a href="#">天猫</a>
- </li>
- <li>
- <a href="#">聚划算</a>
- </li>
- <li>
- <a href="#">天猫超市</a>
- </li>
- <li>
- <a href="#">淘抢购</a>
- </li>
- <li>
- <a href="#">电器城</a>
- </li>
- <li>
- <a href="#">司法拍卖</a>
- <li>
- </ul>
- </div>
- </div>
- <div style="text-align: center;width: 100%">
- <div id="search" class="inp_default">
- <p>
- <label class="pass-label left">宝贝</label>
- <input type="text" name="userName" class="pass-text-input text-input-length left" placeholder="请输入搜索文字">
- <label class="pass-label left">搜索</label>
- </p>
- </div>
- <div style="height: 10px"></div>
- <img src="data:images/zly.jpg" alt="">
- <img src="data:images/zly.jpg" alt="">
- <img src="data:images/zly.jpg" alt="">
- <img src="data:images/zly.jpg" alt="">
- <!--<p>哈哈哈哈哈哈哈哈</p>-->
- <img src="data:images/zly.jpg" alt="">
- <img src="data:images/zly.jpg" alt="">
- <img src="data:images/zly.jpg" alt="">
- <img src="data:images/zly.jpg" alt="">
- <img src="data:images/zly.jpg" alt="">
- <img src="data:images/zly.jpg" alt="">
- <img src="data:images/zly.jpg" alt="">
- <img src="data:images/zly.jpg" alt="">
- <img src="data:images/zly.jpg" alt="">
- </div>
- </div>
- </body>
- <script type="text/javascript">
- window.onload = function(){
- var search = document.getElementById('search'); //搜索框
- //实时监听当前页面的页面滚动事件
- window.onscroll = function(){
- console.log('上'+document.documentElement.scrollTop); //获取滚动条位置
- // console.log('左'+document.documentElement.scrollLeft);
- // console.log('宽'+document.documentElement.scrollWidth);
- // console.log('高'+document.documentElement.scrollHeight);
- //当滚动条位置大于等于150时
- if (document.documentElement.scrollTop >= 150){
- // alert('到了150');
- search.className = "inp_center"; //设置class属性
- }else {
- search.className = "inp_default"; //默认样式
- }
- }
- }
- </script>
- </html>
网页效果:
python 全栈开发,Day52(关于DOM操作的相关案例,JS中的面向对象,定时器,BOM,client、offset、scroll系列)的更多相关文章
- 前端JavaScript(3)-关于DOM操作的相关案例,JS中的面向对象、定时器、BOM、位置信息
小例子: 京东购物车 京东购物车效果: 实现原理: 用2个盒子,就可以完整效果. 先让上面的小盒子向下移动1px,此时就出现了压盖效果.小盒子设置z-index压盖大盒子,将小盒子的下边框去掉,就可以 ...
- python全栈开发day44-js、DOM、BOM
JS的三大部分 一.ECMAJavaScript基础语法: 1.javascript的引入方式 1) 行内式 <script> alert(1) </script> 2) 引入 ...
- python 全栈开发,Day101(redis操作,购物车,DRF解析器)
昨日内容回顾 1. django请求生命周期? - 当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端 请求头和请求体中会包含浏览器的动作(action),这个动作通常为get或者po ...
- python 全栈开发,Day8(文件操作)
一.文件操作流程 文件以什么编码存储的,就以什么编码打开 参数: 1.文件路径 2.编码方式,encode 3.执行动作(打开方式):只读,只写,追加,读写,写读... 打开一个已经存在的文件 f = ...
- python 全栈开发,Day116(可迭代对象,type创建动态类,偏函数,面向对象的封装,获取外键数据,组合搜索,领域驱动设计(DDD))
昨日内容回顾 1. 三个类 ChangeList,封装列表页面需要的所有数据. StarkConfig,生成URL和视图对应关系 + 默认配置 AdminSite,用于保存 数据库类 和 处理该类的对 ...
- Python 全栈开发【第0篇】:目录
Python 全栈开发[第0篇]:目录 第一阶段:Python 开发入门 Python 全栈开发[第一篇]:计算机原理&Linux系统入门 Python 全栈开发[第二篇]:Python基 ...
- Python全栈开发【面向对象进阶】
Python全栈开发[面向对象进阶] 本节内容: isinstance(obj,cls)和issubclass(sub,super) 反射 __setattr__,__delattr__,__geta ...
- Python全栈开发【面向对象】
Python全栈开发[面向对象] 本节内容: 三大编程范式 面向对象设计与面向对象编程 类和对象 静态属性.类方法.静态方法 类组合 继承 多态 封装 三大编程范式 三大编程范式: 1.面向过程编程 ...
- Python全栈开发【模块】
Python全栈开发[模块] 本节内容: 模块介绍 time random os sys json & picle shelve XML hashlib ConfigParser loggin ...
随机推荐
- ruby pluck用法,可以快速从数据库获取 对象的 指定字段的集合数组
可以快速从数据库获取 对象的 指定字段的集合数组 比如有一个users表,要等到user的id数组: select id from users where age > 20; 要实现在如上sql ...
- JAVA中初始化ArrayList的三种方式
下面讲一下ArrayList初始化的几种不同方式. 一.最常用的初始化方式. List<String> list1 = new ArrayList<String>(); lis ...
- jcaptcha和kaptcha验证码使用入门【转】
jcaptcha和kaptcha验证码使用入门 一.jcaptcha验证码使用 jcaptcha使用默认样式生成的验证码比较难以识别,所以需要自定义验证码的样式,包括,背景色.背景大小.字体.字体大小 ...
- tomcat中配置servlet.xml的JNDI或JDBC连接数据库【原】
tomcat中配置servlet.xml的JNDI或JDBC连接数据库 一. JNDI 1. tomcat环境 找到X:\xxx\......\apache-tomcat-6.0.39\conf\se ...
- 机器学习课程-第8周-聚类(Clustering)—K-Mean算法
1. 聚类(Clustering) 1.1 无监督学习: 简介 在一个典型的监督学习中,我们有一个有标签的训练集,我们的目标是找到能够区分正样本和负样本的决策边界,在这里的监督学习中,我们有一系列标签 ...
- 转- --python 3 编码
对Python3编码的整理!!! py编码终极版 说起python编码,真是句句心酸.算起来,反复折腾两个来月了.万幸的是,终于梳理清楚了.作为一个共产主义者,一定要分享给大家.如果你还在因为编码而头 ...
- ELF格式探析之三:sections
前文链接: ELF格式探析之一:Segment和Section ELF格式探析之二:文件头ELF Header详解 今天我们讲对目标文件(可重定位文件)和可执行文件都很重要的section. 我们在讲 ...
- caffe 中 python 数据层
caffe中大多数层用C++写成. 但是对于自己数据的输入要写对应的输入层,比如你要去图像中的一部分,不能用LMDB,或者你的label 需要特殊的标记. 这时候就需要用python 写一个输入层. ...
- MSSQL-SELECT&UPDATE动作要申请的锁
最近在学习[MySQL事务&锁]这块知识,一不留神和MSSQL乱窜了~.~ 文章最初是想查看MySQL vs MSSQL在下面环境产生的阻塞现象会话1开启事务更新数据尚未提交->会话2读 ...
- idea的起步配置
工欲善其事,必先利其器 1.安装 https://www.jetbrains.com/idea/download/#section=windows 可以选择不同平台的安装包,版本一般Ultimate, ...