Python自动化开发学习15-JavaScript和DOM

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python自动化开发学习15-JavaScript和DOM相关的知识,希望对你有一定的参考价值。

初识JavaScript

JavaScript(后面都简写为js)是一门独立的语言。浏览器本身就具有js解释器。

js的存在形式

和css类似,js代码要放在<script>标签中。
同样和css类似,还可以写在一个js文件中,比如文件名就叫 commons.js ,然后在head中引入 &lt;script src="commons.js"&gt;&lt;/script&gt; ,src的值就是js的文件路径。
<script type="text/javascript"> 和 <script> 是一样的,或者说script默认就是js。看到这么写全的情况要认识。
<script>标签存放的位置
上面两种情况都用的是 <script> 标签。而这个标签可以放在head中,也可以放在body中。解释器是从上到下顺序执行的,所以放在越上面就越早执行。这就有一个问题,如果script先执行,那么执行完成script代码后才会导入网页内容。这样用户体验会比较差。而且用户只有先看到网页的内容才有可能会需要用到script的代码。所以建议把<script>标签放到最后,也就是body的内部的最下面。这样就是先显示网页的内容,然后再导入js的动态内容。

hellow world

语法:alert(message) 会显示一个带有消息和确定按钮的警告框。
举例如下,顺便看一下上面提到的代码的执行顺序:

<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script>
        alert("Hello 1")
    </script>
</head>
<body>
<h1>什么时候出现这里的内容</h1>
<script>
    alert("Hello 2")
</script>
</body>

在head里写了一个alert,在body的下面也写了一个alert。打开网页后,会先弹出上面的消息,然后显示网页的内容,最后再弹出最下面的消息。

注释

js代码的注释的语法如下:
单行注释:// 你的代码
多行注释:/* 你的代码 */

<body>
<h1>什么时候出现这里的内容</h1>
<script>
    // alert("Hello 1")
    alert("Hello 2")
    /*
    这里的内容也不会执行
    alert("Hello 3")
    */
</script>
</body>

JavaScript 语句

js可以通过换行或者是分号来区分单独的语句。所以对于单行语句,行尾有没有分号都一样。但是建议加上分号,这样我们的js在编辑完成上线时,可以去掉语句间的缩进和换行(即变成很长的一行代码),节省空间。保证用户端的访问的流畅。

学习JavaScript

变量

变量直接赋值就可以是使用:

<script>
    a = "hello"
    alert(a)
</script>

但是在函数中的变量就存在全局变量和局部变量的区别。需要先用var声明变量,这个变量才是局部变量,否则就是全局变量。建议都先加上var声明为局部变量。

<script>
    function func() {
        // 局部变量
        var a = ‘A‘;
        // 全局变量
        b = ‘B‘
    }
</script>

用控制台调试js代码

除了写一个html文件来调试代码外,也可以用浏览器自带的控制台来调试,用起来就类似一个IDE。
先用 about:blank 来打开一个空白页,然后F12进入开发调试工具,找到控制台(Console)标签就可以在这里直接写代码了。
另外使用js命令 console.log() 可以直接向你的控制台输出信息:

<body>
<script>
    console.log("你好!")
</script>
</body>

打开这样的一个页面,应该是空白的,去控制台看一下有没有一条消息。

定义函数(function)

使用function来定义函数,后面跟函数名,然后是一个"{}"大括号。大括号js的代码块,大括号内部就是这个函数的代码。

<script>
    // 定义一个函数,函数名 fun
    function fun() {
        alert("你好!")
    }
    // 调用执行函数
    fun();
</script>

数据类型

js中的数据类型分为原始类型和对象类型:

  • 原始类型
    • 数字
    • 字符串
    • 布尔值
  • 对象类型
    • 数组
    • 字典

另外还有2个特别的值:

  • null,它表示一个特殊值,常用来描述“空值”。
  • undefined,是一个特殊值,表示变量未定义。

数字(Number)

字符串转数字的方法:
parseInt() :转为整形,不成功则NaN。
parseFloat() :转为浮点数,不成功则NaN。

> parseInt(‘123‘)
< 123
> parseInt(‘123.123‘)
< 123
> parseInt(‘abc‘)
< NaN
> parseFloat(‘321‘)
< 321
> parseFloat(‘321.123‘)
< 321.123
>

一些常量:
Math.E :常量e,自然对数的底数。
Math.PI :圆周率。

一些静态函数:
Math.sin() :计算正弦值
Math.asin() :计算反正弦值,根据值计算出弧度
Math.cos() :计算余弦值
Math.acos() :计算反余弦值,根据值计算出弧度
Math.tan() :计算正切值
Math.atan() :计算反正切值,根据值计算出弧度
Math.abs() :计算绝对值
Math.round() :返回一个整数,4舍5入。
Math.ceil() :返回一个整数,浮点数向上取整。
Math.floor() :返回一个整数,浮点数向下取整。

> Math.ceil(1.234)
< 2
> Math.ceil(-1.234)
< -1
> Math.floor(1.234)
< 1
> Math.floor(-1.234)
< -2
>

Math.random() :生成随机数
Math.sqrt() :计算平方根

字符串(String)

字符串是由字符组成的数组,但在JavaScript中字符串是不可变的:可以访问字符串任意位置的文本,但是JavaScript并未提供修改已知字符串内容的方法。
常用方法:
str.length :获取字符串的长度
str.trim() :移除字符串两边的空白,也可以指定只移除左边(trimLeft)或右边(trimRight)。

> str = ‘  abc  ‘
< "  abc  "
> str.length // 字符串长度
< 7
> str.trim() // 移除空白
< "abc"
> str.trimLeft() // 移除左边的空白
< "abc  "
> str.trimRight() // 移除右边的空白
< "  abc"
>

str.concat() :字符串拼接

> str = ‘aaa‘
< "aaa"
> str.concat(‘bbb‘)
< "aaabbb"
> str.concat(‘ ‘,‘bbb‘,‘ ‘,‘ccc‘,‘ ‘,111)  // 可以拼接多个字符串,数字也能处理
< "aaa bbb ccc 111"
>

str.charAt() :返回字符串中的第n个字符
str.substring() :根据索引获取子序列,字符串切割。
str.slice() :字符串切片,其实和上面的subsring差不多。不过如果第一个参数大于第二个参数,这里会返回空字符串,而substring会自动调整两个参数的位置。

> str = ‘abcdefg‘
< "abcdefg"
> str.charAt(0)  // 下标是0的字符
< "a"
> str.charAt(2)  // 下标是2的字符
< "c"
> str.substring(2) // 返回下标2到末尾的字符串
< "cdefg"
> str.substring(2,5) // 返回下标2,到下标5(不包括)之前的字符串
< "cde"
> str.slice(2,5)  // 结果和substring一样
< "cde"
> str.substring(5,2)  // 会自动调整参数位置
< "cde"
> str.slice(5,2)  // 返回空字符串
< ""
>

到这里可以先暂停一下,看一下下一个小标题定时器和跑马灯示例
str.indexOf() :获取子序列的下标
str.lastIndexOf() :获取子序列的下标,从后往前找。

> str = ‘sonmething for nothing!‘
< "sonmething for nothing!"
> str.indexOf(‘thing‘)
< 5
> str.indexOf(‘thing‘,6) // 从下标6的位置开始查找
< 17
> str.lastIndexOf(‘thing‘,16)  // 从下标16的位置开始往前查找
< 5
>

str.toLowerCase() :转为小写字母
str.toLocaleUpperCase() :转为大写字母

> str = "Any Way"
< "Any Way"
> str.toLowerCase()
< "any way"
> str.toLocaleUpperCase()
< "ANY WAY"
>

str.split() :把字符串分割成数组。第一个参数,指定进行分隔的字符串或正则表达式。第二个参数,指定返回数组的最大长度。

> str = ‘What are you doing?‘
< "What are you doing?"
> str.split()  // 没有参数的话,就没有分隔,但是变成了一个数组
< [object Array]: ["What are you doing?"]
> str.split(‘ ‘)  // 按空格进行分隔
< [object Array]: ["What", "are", "you", "doing?"]
> str.split(‘ ‘,2)  // 指定返回数组的最大长度,多余的就丢弃了
< [object Array]: ["What", "are"]
> str.split(‘‘)  // 如果按字符串进行分隔,就是分隔每个字符
< [object Array]: ["W", "h", "a", "t", " ", "a", "r", "e", " ", "y", "o", "u", " ", "d", "o", "i", "n", "g", "?"]
>

最后还有3个方法,先放这里留个空,之后讲正则表达式的时候还会再遇到
str.search() :检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串。
str.match() :在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。
str.replace() :在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。

布尔值(Boolean)

js里的布尔值分别是 ‘true‘ 和 ‘false‘ ,都是小写的。
比较运算符:

  • == :等于。值相等,类型可以不一样
  • != :不等于。只比较值
  • === :全等。值和类型都相等
  • !== :不等于。比较值和类型
  • &lt;&gt;&lt;=&gt;= :小于、大于、小于等于、大于等于

逻辑运算符:

  • && :and,与
  • || :or,或
  • ! :not,非

数组(Array)

常用方法:
arr.length :数组的大小
arr.push() :向数组的末尾添加一个或多个元素,并返回新的长度
arr.pop() :删除并返回数组的最后一个元素
arr.unshift() :向数组的开头添加一个或更多元素,并返回新的长度
arr.shift() :删除并返回数组的第一个元素

> arr = [11,22,33,44]
< [object Array]: [11, 22, 33, 44]
> arr.length
< 4
> arr.push(55,66)  // 添加2个元素到末尾
< 6
> arr.pop()  // 取出最后一个元素
< 66
> arr.unshift(‘a‘,‘b‘)  // 在头部插入2个元素
< 7
> arr.shift()  // 取出第一个元素
< "a"
> arr  // 现在数组的成员
< [object Array]: ["b", 11, 22, 33, 44, 55]
>

arr.splice() :在数组中添加/删除元素,然后返回被删除的元素。
语法: arrayObject.splice(index,howmany,item1,.....,itemX)
index :必需。整数,规定起始元素的位置,使用负数可从数组结尾处规定位置。
howmany :必需。要删除的元素数量。如果设置为 0,则不删除元素。
item :可选。向数组添加的新元素。

> arr = [11,22,33,44]
< [object Array]: [11, 22, 33, 44]
> arr.splice(1,2,‘a‘,‘b‘,‘c‘)  // 从下标1的位置,删除2个元素,并且在这个位置插入新的元素
< [object Array]: [22, 33]
> arr  // 操作后的数组
< [object Array]: [11, "a", "b", "c", 44]
>

arr.slice() :切片
arr.reverse() :反转
arr.join() :把数组中的所有元素拼接为一个字符串。参数可选,指定要使用的分隔符。如果省略参数,则使用逗号作为分隔符。
arr.concat() :连接两个或多个数组。参数可以是具体的值,也可以是数组对象。可以是任意多个。
arr.sort() :对数组的元素进行排序

字典

字典没有太多内容,直接看定义和取值的例子:

> dic = {‘k1‘:‘v1‘,‘k2‘:‘v2‘,‘k3‘:‘v3‘}
< [object Object]: {k1: "v1", k2: "v2", k3: "v3"}
> dic[‘k1‘]
< "v1"
>

定时器

使用setInterval可以创建一个定时器,第一个参数是要执行的代码(一般是一个函数),第二个参数是间隔时间(ms)。
下面是一个每个一段时间弹框的例子:

<script>
    // 创建一个定时器
    // 第一个参数可以是一个函数,第二个参数是间隔时间(ms)
    setInterval("alert(‘Hellow‘)", 2000)
</script>

跑马灯示例

运用定时器和上面的字符串的内容来实现一个字符串滚动显示的效果:

<body>
<div id="welcome">欢迎公司领导莅临指导。 </div>
<script>
    function func() {
        // 根据id来获取到标签
        var tag = document.getElementById(‘welcome‘);
        // 获取标签内部的内容
        var content = tag.innerText;
        var f = content.charAt(0);
        var l = content.substring(1, content.length);
        // 重新拼接成新的字符串
        var new_content = l.concat(f);
        // 给标签内容重新赋值,赋值后页面显示就会有变化
        tag.innerText = new_content;
    }
    setInterval("func()", 500)
</script>
</body>

JavaScript 语句

for/in 循环

遍历的是索引,不是值。遍历一个数组,遍历的就是数组的下标:

> arr = [‘a‘,‘b‘,‘c‘,‘d‘]
< [object Array]: ["a", "b", "c", "d"]
> for (i in arr){
      console.log(i)  // 这个是下标不是值
      console.log(arr[i])  // 这样才能取到值
  }
    0
    a
    1
    b
    2
    c
    3
    d
< undefined
>

遍历一个字典,就是遍历字典的key:

> dic = {‘k1‘:‘v1‘,‘k2‘:‘v2‘,‘k3‘:‘v3‘}
< [object Object]: {k1: "v1", k2: "v2", k3: "v3"}
> for (k in dic){
      console.log(k);
      console.log(dic[k]);
  }
    k1
    v1
    k2
    k3
    v3
< undefined
>

for 循环

这种for循环是用的比较多的。但是这种循环驾驭不了字典的key,所以遍历不了字典。遇到字典的情况还是得用for/in。

for (语句 1; 语句 2; 语句 3)
  {
  被执行的代码块
  }

语句1:在循环(代码块)开始前执行
语句2:定义运行循环(代码块)的条件
语句3:在循环(代码块)已被执行之后执行

> for (var i=0; i<5; i++){
      console.log(i)
  }
    0
    1
    2
    3
    4
< undefined
>

if 语句

语法:

if (条件 1)
  {
  当条件 1 为 true 时执行的代码
  }
else if (条件 2)
  {
  当条件 2 为 true 时执行的代码
  }
else
  {
  当条件 1 和 条件 2 都不为 true 时执行的代码
  }

js的基础先会这么多,下一节在补充其他的内容

DOM

文档对象模型 DOM(Document Object Model)是一种用于HTML和XML文档的编程接口。它给文档提供了一种结构化的表示方法,可以改变文档的内容和呈现方式。我们最为关心的是,DOM把网页和脚本以及其他的编程语言联系了起来。DOM属于浏览器,而不是JavaScript语言规范里的规定的核心内容。

查找

首先,要先通过查找的方法获取到对象。

直接查找

document.getElementById() :根据ID获取一个标签
document.getElementsByName() :根据name属性获取标签集合
document.getElementsByClassName() :根据class属性获取标签集合
document.getElementsByTagName() :根据标签名获取标签集合
根据ID获取到的是唯一的值,返回的是对象。其他的方法获取到的值可能是多个,返回的都是包含每一个对象的数组。
我们可以通过获取对象的innerText属性,来获取到标签中的文本内容。也可以通过修改这个属性,来修改页面的内容。
举例:

<body>
<div id="i1" class="c1">我是i1</div>
<span>a</span>
<span>b</span>
<span>c</span>
<span>d</span>
<script>
    i1 = document.getElementById(‘i1‘);
    alert(i1.innerText);  // 弹框显示i1的信息
    t1 = document.getElementsByTagName(‘span‘);
    // 修改span标签中的内容
    for (var i=0; i<t1.length;i++){
        t1[i].innerText = i;
    }
</script>
</body>

间接查找

parentElement :父标签
children :所有子标签集合,这个是数组
firstElementChild :第一个子标签
lastElementChild :最后一个子标签
nextElementtSibling :下一个兄弟标签
previousElementSibling :上一个兄弟标签

<body>
<div>我是父标签
    <div id="i1">我是i1
        <div>我是子标签1</div>
        <div>我是子标签2</div>
    </div>
</div>
<div>(空)</div>
<script>
    i1 = document.getElementById(‘i1‘);  // 先获取到i1标签的对象
    // 子标签集合第一个元素的,下一个兄弟标签的,文本内容
    alert(i1.children[0].nextElementSibling.innerText);
    // 修改父标签的下一个兄弟标签的内容
    i1.parentElement.nextElementSibling.innerText = "我是父标签的兄弟";
</script>
</body>

操作

之前我们已经对innerText属性进行过操作了。能做的还有很多

操作内容

innerText :开始和结束标签之间的文本内容
innerHTML :开始和结束标签之间的 HTML 内容
value :元素的值

操作对象的class属性

className :获取所有类名
classList.add :添加一个类名
classList.remove :删除一个类名

<body>
<div id="i1">我是i1</div>
<script>
    d1 = document.getElementById(‘i1‘);
    d1.className = ‘i1 i2 i3‘;
    alert(d1.className);
    d1.classList.remove(‘i2‘);
    d1.classList.add(‘i4‘);
    alert(d1.className);
</script>
</body>

后面示例中的模态对话框有应用场景的例子。操作起来比直接修改style方便。

事件

下面2个事件,后面的示例中会用到:

  • onclick :事件会在对象被点击时发生。
  • onmouseover :事件会在鼠标指针移动到指定的对象上时发生。

后面的示例中有例子。这里直接跳到后面看示例就好。
下面关于事件的内容还未学习,应该是下次要讲的补充内容了。

事件句柄 (Event Handlers)

属性 此事件发生在何时...
onabort 图像的加载被中断。
onblur 元素失去焦点。
onchange 域的内容被改变。
onclick 当用户点击某个对象时调用的事件句柄。
ondblclick 当用户双击某个对象时调用的事件句柄。
onerror 在加载文档或图像时发生错误。
onfocus 元素获得焦点。
onkeydown 某个键盘按键被按下。
onkeypress 某个键盘按键被按下并松开。
onkeyup 某个键盘按键被松开。
onload 一张页面或一幅图像完成加载。
onmousedown 鼠标按钮被按下。
onmousemove 鼠标被移动。
onmouseout 鼠标从某元素移开。
onmouseover 鼠标移到某元素之上。
onmouseup 鼠标按键被松开。
onreset 重置按钮被点击。
onresize 窗口或框架被重新调整大小。
onselect 文本被选中。
onsubmit 确认按钮被点击。
onunload 用户退出页面。

对于事件需要注意的要点:

  • this :当前正在操作的标签
  • event :封装了当前事件的内容
  • 事件链以及跳出

示例

模态对话框

这里的思路是,单独定义个hide的class,样式里定义隐藏属性(display: none;)。只要有标签加上hide这个class,就会被隐藏。我们之后只需要进行标签的class的add和remove的操作,就实现了样式的变化。
实现的方法有很多,直接把display写在class的样式里,然后修改样式的属性也是可以的。

<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        /*遮罩层样式*/
        .c1{
            position: fixed;
            top: 0;
            bottom: 0;
            right: 0;
            left: 0;
            background-color: black;
            opacity: 0.6;
            z-index: 5;
        }
        /*弹出框样式*/
        .c2{
            width: 500px;
            height: 400px;
            background-color: pink;
            position: fixed;
            left: 50%;
            margin-left: -250px;
            margin-top: 100px;
            z-index: 10;
        }
        /*显示/隐藏 遮罩层和弹出框*/
        .hide{
            display: none;
        }
    </style>
</head>
<body>
<div>
    点击
    <input type="button" value="按钮" onclick="ShowModel()" />
    弹出对话框
</div>
<!--遮罩层-->
<div class="c1 hide" id="i1"></div>
<!--弹出框-->
<div class="c2 hide" id="i2">
    <div style="padding: 100px 50px">
        <p>
            <label for="username">用户名:</label>
            <input type="text" id="username" />
        </p>
        <p>
            <label for="password">密码:</label>
            <input type="password" id="password" />
        </p>
        <p>
            <input type="button" value="确定" onclick="HideModel()" />
            <input type="button" value="取消" onclick="HideModel()" />
        </p>
    </div>
</div>
<script>
    function ShowModel() {
        document.getElementById(‘i1‘).classList.remove(‘hide‘)
        document.getElementById(‘i2‘).classList.remove(‘hide‘)
    }
    function HideModel() {
        document.getElementById(‘i1‘).classList.add(‘hide‘)
        document.getElementById(‘i2‘).classList.add(‘hide‘)
    }
</script>
</body>

全选、取消、反选

操作选择框:对于单选框(type="radio")和复选框(type="checkbox"),可以通过checked属性获取它当前的状态,true为选中,false未选中。也可以通过赋值来改变它的状态。

<body>
<div>
    <input type="button" value="全选" onclick="ChooseAll()">
    <input type="button" value="取消" onclick="CancelAll()">
    <input type="button" value="反选" onclick="Reverse()">
</div>
<div>
    <table border="3">
        <thead>
        <tr>
            <th>choice</th>
            <th>name</th>
            <th>age</th>
        </tr>
        </thead>
        <tbody id="tb">
        <tr>
            <td><input type="checkbox" title="choose the student"></td>
            <td>Adam</td>
            <td>23</td>
        </tr>
        <tr>
            <td><input type="checkbox" title="choose the student"></td>
            <td>Bob</td>
            <td>24</td>
        </tr>
        <tr>
            <td><input type="checkbox" title="choose the student"></td>
            <td>Clark</td>
            <td>25</td>
        </tr>
        </tbody>
    </table>
</div>
<script>
    function ChooseAll() {
        var tbody = document.getElementById(‘tb‘);
        var tr_list = tbody.children;
        for (var i=0; i<tr_list.length; i++){
            var checkbox = tr_list[i].firstElementChild.firstElementChild;
            checkbox.checked = true;
        }
    }
    function CancelAll() {
        var tbody = document.getElementById(‘tb‘);
        var tr_list = tbody.children;
        for (var i=0; i<tr_list.length; i++){
            var checkbox = tr_list[i].firstElementChild.firstElementChild;
            checkbox.checked = false;
        }
    }
    function Reverse() {
        var tbody = document.getElementById(‘tb‘);
        var tr_list = tbody.children;
        for (var i=0; i<tr_list.length; i++){
            var checkbox = tr_list[i].firstElementChild.firstElementChild;
            checkbox.checked = !checkbox.checked;
        }
    }
</script>
</body>

后台管理左侧菜单

这里采用了鼠标悬停事件(onmousemove),会展开当前菜单。子菜单的隐藏依旧是通过操作class属性实现的。

<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .hide{
            display: none;
        }
        .item .header{
            height: 35px;
            background-color: blue;
            color: white;
            line-height: 35px;
        }
    </style>
</head>
<body>
<div style="height: 48px"></div>
<div style="width: 300px">
    <div class="item">
        <div class="header" onmousemove="ShowMenu(this)">菜单1</div>
        <div class="content hide">
            <div>内容1-1</div>
            <div>内容1-2</div>
            <div>内容1-3</div>
        </div>
    </div>
    <div class="item">
        <div class="header" onmousemove="ShowMenu(this)">菜单2</div>
        <div class="content hide">
            <div>内容2-1</div>
            <div>内容2-2</div>
            <div>内容2-3</div>
        </div>
    </div>
    <div class="item">
        <div class="header" onmousemove="ShowMenu(this)">菜单3</div>
        <div class="content hide">
            <div>内容3-1</div>
            <div>内容3-2</div>
            <div>内容3-3</div>
        </div>
    </div>
</div>
<script>
    function ShowMenu(x){
        var content_list = document.getElementsByClassName(‘content‘);
        for (var i=0; i<content_list.length; i++){
            content_list[i].classList.add(‘hide‘)
        }
        x.nextElementSibling.classList.remove(‘hide‘)
    }
</script>
</body>

作业

电子商务网站页面(动态)(仿京东),要做4个页面

主页

主要是实现中间的那个部分,四分格的商品展示的样式。还要做返回顶部的功能
技术分享图片

登陆

要做出右边有图标的input框
技术分享图片

注册

红色的星号(*)表示必填项
技术分享图片

购物车

左边有菜单:类似后台管理的左侧菜单
右边有表格:表格要有全选、反选。还能用模态框添加内容

以上是关于Python自动化开发学习15-JavaScript和DOM的主要内容,如果未能解决你的问题,请参考以下文章

Python自动化开发学习2

Python自动化开发学习1

Python自动化开发学习2

Python自动化开发学习12-堡垒机开发

Python自动化开发学习1

Python自动化开发学习-Tornado