个人自学前端10-JS3-DOM操作和表达式,操作符和表达式,逻辑运算符和三目运算符
DOM操作和表达式
document object model => 通过js操作页面上的元素
document => 文档 => html文档
一 DOM操作入门
DOM操作包含两部分基本操作:
1:获取标签(元素)(节点)
2:操作数标签(元素)(节点)
1.1 获取元素
html标签在DOM中用 js 标签对象来表示。(标签都是js对象)
js 标签对象有很多默认的属性,不同属性有不同作用。
获取方法:
// 通过id获取元素(只获取一个)
let oDiv = document.getElementById(元素id);
// 通过标签名获取元素(获取一堆)
let aDiv = document.getElementsByTagName(元素标签名);
// 通过类名获取元素(获取一堆)
let aDiv = document.getElementsByClassName(元素类名);
// 通过选择器获取元素(只获取一个)
let oDiv = document.querySelector(选择器);
// 通过选择器获取元素(获取一堆)
let aDiv = document.querySelectorAll(选择器);
如果标签不在页面中,则返回null。
1.2 操作元素
js 可以操作html标签的内容和属性。
js 不能操作html标签的样式,只能操作html标签的style属性。
js 获取到的任何关于html标签的数据,都是字符串!(html标签的内容,属性,样式都是字符串!)
1.2.1 操作元素内容
两个方法:
// 获取元素内容
console.log(oDiv.innerText);
console.log(oDiv.innerHTML);
// 设置元素内容
oDiv.innerText = 新的内容;
oDiv.innerHTML = 新的内容;
其中:
innerHTML可以获取html标签内容,并且可以实现插入新标签。
innerText只能获取和操作文本内容。
// 反引号支持换行
oDiv.innerHTML = `
<p>uuuuuu</p>
<p>ttttttttt</p>
`;
1.2.2 操作元素行间样式
html标签是一个 js 对象, html标签的style属性也是一个 js 对象。style对象是标签对象的一个属性。
// 获取行间width样式
console.log(oDiv.style.width)
// 设置width属性。
oDiv.style.width = '100px';
// 如果样式名带-,需要写成驼峰形式
oDiv.style.marginLeft = '100px';
js 只能获取行间样式和操作行间样式,不能获取和操作内部样式和外部样式。
js 只能获取最终样式。不能设置
// 获取优先级最高的那个width样式 (最终的width样式)
getComputedStyle(oDiv).width
1.2.3 操作元素属性
html标签的属性可以在对应的 js 对象中通过 js 对象属性获取。(html标签属性和 js 对象属性不要混为一谈)
因此,给 js 标签对象添加新属性,html标签并不会多出新的属性。
同样,删除 js 标签对象的属性,html标签并不会删除对应属性。
js 标签对象默认拥有的属性是html标签的全局属性,事件属性和可选属性。
因此通过 js 我们也可以操作html标签的全局属性,事件属性和可选属性。
// 获取对应的html标签属性。class属性需要写成className
console.log(oDiv.id);
console.log(oText.value);
console.log(oText.className);
// 设置元素的id属性
oDiv.id = 'wrap';
oText.value = '你好吗';
oText.className = 'active';
标签的布尔属性,用 js 获取,得到的就是布尔属性。例如checked,mutiple,disabled属性
// 获取复选框的checked属性,得到的值就是true或者false
console.log(oCheckbox.checked)// true或者false
// 通过设置checked属性可以控制复选框的勾选状态
oCheckbox.checked = true
// 禁用oBtn
oBtn.disabled = true
标签的自定义属性默认在对应 js 标签对象上没有,因此不能通过操作 js 标签对象来操作html标签的自定义属性。
可以通过标签对象的getAttribute方法来获取自定义属性。
可以通过标签对象的setAttribute方法来设置自定义属性。
// 获取abc自定义属性。
oDiv.getAttribute('abc');
// 把abc自定义属性设置为wwww。
oDiv.setAttribute('abc','wwww');
标签属性:
1:全局属性 所有标签都可以使用的属性。常见是id,class,style,title
2:可选属性 不同标签的可选属性不一样。例如img标签可以有width属性,div没有。
3:自定义属性,开发人员为了某种目的,自己添加的属性
4:事件属性。数据属性都以on开头。on+事件名,事件属性的属性值是js代码
1.2.4 添加事件
什么是事件?
特定情况下,发送的事情,例如下雨了,下课了。
事件发生后会有对应的事件现象。例如,下雨了,大家都会撑伞,下课了,大家都去吃饭。
标签也有对应的事件,例如,按钮被点击了。这里点击就是一个事件。
如果点击按钮,需要产生某些效果,则需要通过事件属性来添加代码实现需要的效果。
通过操作 js 标签对象的事件属性,可以给标签添加事件。事件需要实现的效果需要需要写在函数内。
// 给按钮添加点击事件,事件发生产生的效果写在函数内。
// 点击按钮,弹出100
oBtn.onclick = function(){
alert(1000)
}
// 或者
oBtn.onclick = show;
function show(){
alert(1000)
}
常见事件(注意事件没有驼峰):
onclick。(点击事件)
onmouseover,onmouseout。(鼠标移入移出事件)
onmouseenter,onmouseleave。(鼠标移入移出事件)
onblur,onfocus (失去获得焦点事件)
onchange (value改变事件)
oninput (正在输入事件)
onmousedown,onmouseup (鼠标按下松开事件)
onkeydown,onkeyup (键盘按下松开事件)
事件产生的效果,为什么要写在函数内?
我们知道,js的运行是发生在html文档的解析阶段的,而事件需要实现的效果是发生在html文档渲染之后的,
如何让某些代码在html文档在渲染之后才执行呢?通过函数就可以。
**函数可以决定某些代码什么时候执行,这是函数的一个显著特征。
二:操作符(运算符)
程序中需要对数据进行各种运算,以得到计算后的结果。
计算有很多种类型,不同计算方式需要使用不同的操作符。
注意,这里的计算不限于传统的数学计算,实际上数学运算只是编程运算中的一小部分。
常见运算符:
1:算术运算符
2:比较运算符
3:逻辑运算符
4:三目运算符(条件运算符,三元运算符)
5:其他运算符
操作数:用于计算的数据叫运算符的操作数。
根据操作数的不同个数,还可以把运算符分为:
1:单目运算符
2:双目运算符
3:三目运算符
大多数的运算符都是双目运算符,小部分是单目运算符,三目运算符只有一个。
三:表达式
编程本质上都是在处理数据和数据逻辑。
那程序是如何表示数据的?程序中的数据都是怎么获得的?
程序中的所有数据都是通过表达式获得的。表达式是程序中最基本的组成单元。
任何的数据,程序都是通过表达式来获取或者表示的。
表达式分类:
1:原始表达式
单个常量和单个变量。
如果是object类型的常量,一般叫直接量,也可以看作原始表达式。
对象的属性访问和数组的元素访问,也可以看作原始表达式。
2:计算表达式
操作数 + 操作符构成的表达式。
操作数本身是数据,因此操作数本身也可以通过任意的表达式来提供。
// 1+1 => 这是两个常量1和运算符 + 构成的表达式。
// 第一个操作数1同时也可以通过表达式0.5+0.5来提供,写成 (0.5+0.5)+1
3:函数调用表达式
函数调用也可以提供数据,构成函数调用表达式。
// Math.random() => 这是函数调用表达式,它和其他表达式一样提供一个结果,赋值给变量res
let res = Math.random();
表达式的返回值:
表达式经过计算得到的结果就是表达式的返回值。
表达式一定有返回值。
// 1+1 计算的结果是2,因此我们说表达式 1+1的返回值是2
// 以下代码的意义为:把1+1的返回值赋值给变量x。
let x = 1+1;
// 以下代码的意义为:把Math.random()的返回值赋值给变量res
let res = Math.random();
操作符和表达式
一:算术运算符
小学就学过的是:+,-,*,/,计算顺序也是先乘除,后加减。
1.1.1:取余(取模):%
取余运算符,求两个操作数的余数。
// 4/2 => 求商,得2
// 4%2 => 求余数,因为可以整除,余数为0,因此计算得0
// 2%4 => 求余得2.
// 3%5 => 求余得3.
// 0%5 => 求余得0.
// 结论:如果较小的数取余较大的数,结果是较小的数
1.1.2:++
自增。单目运算符。分为前自增和后自增。计算后变量的值+1。只能操作变量。是一种语法糖。
let x = 10;
// 前自增
++x;
// 后自增
x++;
// 不管是前自增还是后自增,x的值经过计算后都+1
前自增和后自增在进行赋值时会有区别。
let x = 10;
// 如果是后自增。y的值是10.x的值是11
let y = x++;
// 如果是前自增,y的值是11.x的值是11
let y = ++x;
// 为什么会这样?
//let y = x++;可以用完整的赋值逻辑表示如下:
// 先把x赋值给y
let y = x;
// 再把x加1
x = x + 1;
// y = ++x;可以用完整的赋值逻辑表示如下:
// 先把x加1
x = x + 1;
// 再把x赋值给y
let y = x;
总结:前置++,计算结果是+1之后的值。后置++,计算结果是+1之前的值。
难点:区分x++,++x和x的区别。
二:比较运算符
初中就学过的:>,<,>=,<=
布尔值:一种JavaScript的数据类型,表示真假,对错,有无。
比较运算符计算得到的结果都是布尔值。
1.2.1 值等 ==
判断两个数是否相等,用的是 == ,注意 = 是赋值,不是判断相等。
如果两个操作数都是object类型。则比较的是两个对象是否是同一个对象。
// 比较两个数字的值是否相等
let x = 10;
let y = 20;
console.log(x == y);//false
// 比较两个对象是否是同一个对象。
let obj1 = {};
let obj2 = {};
console.log(obj1 == obj2);//false
1.2.2 全等 ===
判断两个数的值和类型是否全等。值和数据类型必须都一致才会返回true
let x = 1;
let str = '1';
console.log(x == str);// true
// x的数据类型是number,str的数据类型是string,类型不一样。因此是false。
console.log(x === str);// false
1.2.3 值不等 !=
判断两个数据的值是否相等。
let x = 10;
let y = 20;
console.log(x != y);//true
1.2.4 值不等或者类型不等 !==
判断两个数据的值不等或者类型不等,只要有一个不等,都返回true,如果全部相等返回false
let x = 2;
let str = '2';
// 值等,因此是false
console.log(x != str);// false
// 值等,但是类型不等
console.log(x !== str);// true
let x = 2;
let y = 2;
// 值和类型都相等。
console.log(x !== y);// false
三:判断
判断不是表达式,是控制结构中的一种。让我们可以实现类似如果....否则....这样的程序逻辑。
语法:
if(条件){
条件为真需要做的事
}else{
条件为假需要做的事
}
其中条件可以由任何表达式提供。
当这个表达式的返回值是true时执行第一个代码块。
当返回值是false时,执行第二个代码块。
几种拓展的表现形式:
1:只有如果,没有否则
if(条件){
条件为真做的事情
}
// 这种写法可以省略{},但是极度不推荐
2:有很多的条件判断
if(条件1){
条件1为真做的事情
}else if(条件2){
条件2为真做的事情
}
.........
else{
所有条件都为假时做的事情。
}
// 这种写法,如果多个条件同时为真,则只执行第一个真条件匹配的代码段,其他的代码段不执行
3:switch判断
switch判断有时候可以简化多个 if.else if的判断书写。
// 类似以下的判断形势可以用switch代替
if(变量 == 值1){
相等时做的事情
}else if(变量 == 值2){
相等时做的事情
}
.........
else{
所有值都不等时做的事情。
}
// 以下写法,break不能省略,它可以防止多个值都为真时错误的执行多个语句
// default 的作用类似于最后一个else。
switch(变量){
case 值1:
变量等于值1时做的事情;
break;
case 值2:
变量等于值2时做的事情;
break;
........
default:
所有值都不等时做的事情。
}
四:隐式转换
1.1 转换现象
很多时候,操作数的数据类型是有规定的。
比如,算术运算符的操作数的数据类型必须是数字,因为不是数字无法计算。
但是,js在书写上却允许不是数字的数据进行算术运算。
因为js是弱类型的编程语言,对数据类型不敏感,在需要的时候会自动进行类型转换。
console.log('1' * 2 );//结果是2
// '1' * 2 => 第一个操作数是字符串 '1',不是数字,因此理论上不会进行相乘计算。
// 为了让以上运算正常执行,js自动把字符串 '1'转换成了数字1.实际进行的计算是 1*2
另外,比较运算符的操作数也应该是数字,如果不是,js会自动转换为数字在进行比较运算。
console.log('1' < 2);// 结果是true
// 理论上字符串 '1' 是不能和数字2进行比较大小的,为了让运算完成,js会自动把'1'转换成数字1以后再比较。
判断语句的判断条件的值应该是布尔值,如果不是,js会自动转换条件的值为布尔值,然后再判断
// 100是数字,不是布尔值,为了让判断执行,js会把100转换为布尔值true,然后再进行判断
if(100){
console.log('100是true')
}
100转换为布尔值为什么是true,为什么不是false?什么东西转换为布尔值是false?
重点: js的世界中,只有5种常量转换为布尔值是false,其余都是true;
这5个值是:NaN,0,'' (空字符串),undefined,null。
在js的世界中,隐式转换无处不在。再比如,alert(),括号内的值应该是字符串,如果不是,js会自动转换为字符串.
// window是对象,不是字符串,因此js自动把window转换成了字符串[Object object]
alert(window);// [Object object]
// 文本框获取的value是字符串,*1之后会变成数字100
let num = oText.value * 1 + 50;
1.2 显示转换
对应的数据类型的转换方法:
1:把任意值转换为number类型 Number (待转换的值)
2:把任意值转换为string类型 String (待转换的值)(还有很多)
3:把任意值转换为boolean类型 Boolean (待转换的值)
不存在把其他值转换为对象的方法。因为万物皆对象。
1.3 转换规律
1:算术运算符
默认会把不是数字的操作数隐式转换为number类型。
例外:
如果是 + 操作符,如果有一个操作数是字符串,则把另一个操作数隐式转换为字符串,
然后进行字符串拼接操作。
'1' + 1 => 结果是'11',而不是2
2:比较运算符
默认会把不是数字的操作数隐式转换为number类型。
例外:
如果是 == 操作符,如果比较的两个操作都是对象,则比较两个对象是不是同一个对象,而不会进行隐式转换。
3:判断条件
默认会把判断()内的值转换为布尔值。没有例外。
会转换为布尔值的5个常量:NaN,0,空字符串,undefined,null
1.4 编程经验
利用隐式转换转换字符串为数字。
'2'+3 因为js默认会把3转换为 '3',因此结果是'23',如果我们希望结果是5,则需要把 '2'转换为数字,再+3
可以这样做:'2'*1+3
这样先计算'2'*1,这样js会把'2'转换为2,乘1得2,再+3得5
利用隐式转换转换其他值为字符串。
true + 2 因为js默认会把true转换为数字1,因此结果是3,如果我们希望结果是true2,则需要把true转换为字符串
可以这样做:true+''+2
这样先计算true+'',js会把true隐式转换为'true',再+2,得'true2'
逻辑运算符和三目运算符
一:逻辑操作符
逻辑运算符用于实现:并且,或者和取反操作。
1.1:! 逻辑非
逻辑非操作符是单目运算符。!操作数
计算逻辑:操作数隐式转换为布尔值是true,返回false,否则返回true。
if(!条件){
条件为假做的事情
}
// 利用两个逻辑非可以是隐式转换任何值为布尔值
let x = !!y;
1.2:&& 逻辑与
逻辑与操作符是双目运算符。操作数1 && 操作数2
计算逻辑:第一个操作数隐式转换为布尔值是true,返回第二个操作数,否则返回第一个操作数。
用法:
//用于判断
if(条件1 && 条件2){
条件1和条件2成立需要做的事情
}
// 用于赋值
let x = y && z;
// 此用法相当于:
let x;
if(y){
x = z;
}else{
x = y;
}
// 用于代替简单的if判断
条件 && 条件为真做的事情
// 类似于:
if(条件){
条件为真做的事情
}
1.3:|| 逻辑或
逻辑或操作符是双目运算符。操作数1 || 操作数2
计算逻辑:第一个操作数隐式转换为布尔值是true,返回第一个操作数,否则返回第二个操作数。
用法:
// 用于判断
if(条件1 || 条件2){
条件1或者条件2成立需要做的事情
}
// 用于赋值
let x = y || z;
// 此用法相当于:
let x;
if(y){
x = y;
}else{
x = z;
}
// 用于代替简单if判断
!条件 || 条件为假做的事情
// 相当于:
if(!条件){
条件为假做的事情
}
二 条件运算符
唯一的一个三目运算符。也叫三元运算符。
语法:操作数1 ?操作数2 :操作数3
计算逻辑:第一个操作数隐式转换为布尔值是true,返回第二个操作数,否则返回第三个操作数。
用法:
// 用于赋值
let x = 条件 ? y : z;
// 类似于:
let x;
if(条件){
x = y
}else{
x = z
}
// 用于代替简单的if else
条件? 条件为真做的事情 :条件为假做的事情
if(条件){
条件为真做的事情
}else{
条件为假做的事情
}
// 用于代替if else if else语句(嵌套三目)
条件1 ?
条件1为真做的事情 :
条件2 ? 条件2为真做的事情 :条件2为假做的事情
// 类似于:
if(条件1){
条件1为真做的事情
}else if(条件2){
条件2为真做的事情
}else{
条件都不成立做的事情
}
三 运算符优先级
表达式都有返回值,因此计算表达式的操作数可以由任意的表达式来提供。
作为操作数的表达式的返回值就是实际进行运算的操作数。
因此计算表达式可以写得很复杂
// 这是用常量作为操作数
2 + 3
// 这是用变量做操作数
x + y
// 2*3的返回值与4进行算术加运算,这里运算符 + 的操作数是 6和4,相当于6*4
2*3 + 4;
// x*y的返回值与z*4的返回值进行算术加运算。
x*y + z*4
// 2*3的返回值与typeof 100的返回值进行比较运算。
2*3 < typeof 100
// 1*2的返回值与5-3的返回值进行逻辑与计算
1*2 && 5-3
//1<2的返回值和4+3的返回值和2<3的返回值进行三目运算
1<2 ? 4+3 : 2<3
// (2*3 + 4)的返回值和(1*2 && 5-3)的返回值和(x*y + delete oYm.name)的返回值进行三目运算
(2*3 + 4) ? (1*2 && 5-3) : (x*y + delete oYm.name)
当表达式内有很多操作数时,需要考虑操作符的优先级。
按操作数数目划分优先级
单目 > 双目 > 三目
按种类细分:
()> 自增自减 > 逻辑非 > 算术 > 比较 > 逻辑与逻辑或 > 三目 > 赋值 > ,
四 例题
// 01
typeof l == 'string'
? typeof m == 'number'
? m = n && l
: m += n || l
: l *= 2
// 01解
if (typeof l == 'string') {
if (typeof m == 'number') {
if (n) {
m = l;
} else {
m = n;
}
} else {
if (n) {
m += n;
} else {
m += l
}
}
} else {
l *= 2
}
// 02
res = (
typeof m == 'function'
? alert('m是函数')
: typeof m == 'number'
? m = 0
: m = 'default string'
)`
// 02解
if ( typeof m == 'function' ) {
res = alert('m是函数')
} else {
if (typeof m == 'number') {
// 把m=0的返回值赋值给res
res = m = 0
} else {
res = m = 'default string'
}
}
杂七杂八
一. 逻辑运算符代替if
1. || => 或者 => 第一个是真,返回第一个操作数,否则返回第二个
2. && => 与 => 第一个是真,返回第二个操作数,否则返回第一个
3. ! => 永远返回布尔值.取反
4. 数1?数2:数3 => 第一是true,返回第二个,否则返回第三个
5. && => 改写单个if
本文来自博客园,作者:暗鸦08,转载请注明原文链接:https://www.cnblogs.com/DarkCrow/p/14986290.html

浙公网安备 33010602011771号