Harmony鸿蒙开发0基础入门到精通Day05--JavaScript篇
this关键字的使用
1.绑定事件中,this指的就是事件源,谁点击就触发谁。
<button id="btn">点击我</button>
<script>const btn = document.getElementById('btn');btn.onclick = function() {// 这里的this指向触发事件的按钮(事件源)console.log(this); // 输出 <button id="btn">点击我</button>this.style.color = 'red'; // 直接操作当前按钮样式};
</script>
2.普通函数中,this值得就是window
function normalFunc() {// 普通函数中的this指向全局对象windowconsole.log(this); // 输出 window 对象console.log(this === window); // 输出 true
}
normalFunc(); // 直接调用普通函数
3.对象中调用函数时,this值得是当前的对象。
const person = {name: '张三',age: 20,sayHi: function() {// 对象方法中的this指向当前对象(person)console.log(this); // 输出 {name: '张三', age: 20, sayHi: ƒ}console.log(`我叫${this.name},今年${this.age}岁`); // 输出 "我叫张三,今年20岁"}
};
person.sayHi(); // 调用对象方法,this指向person
this关键字指向方式太多,要是在生产环境中,难以知晓是谁怎么办?
我们可以用下列函数中可以修改this关键字的走向。
call() 对象或【函数】.call(this需要指向的对象,this也随之改变,参数1,参数2,...)
apply() 对象或【函数】.apply(this需要指向的对象,this也随之改变,[参数1,参数2,...])
bind() 对象或【函数】.bind(this需要指向的对象),返回值为function对象,需要二次调用。
------------->let fun = 对象.bind(this需要指向的对象); fun(参数1,参数2,...)
call () 方法
const obj1 = { name: "obj1" };
const obj2 = { name: "obj2" };function showName() {console.log("当前this指向:", this);console.log("名字:", this.name);
}// 直接调用,this指向window(普通函数)
showName(); // 输出:window,undefined// 用call修改this为obj1,立即执行
showName.call(obj1); // 输出:obj1,"obj1"// 带参数的函数
function greet(greeting, punctuation) {console.log(`${greeting},我是${this.name}${punctuation}`);
}
greet.call(obj2, "你好", "!"); // 输出:"你好,我是obj2!"(this指向obj2)
apply () 方法
const user = { name: "小明" };function introduce(age, hobby) {console.log(`我叫${this.name},${age}岁,喜欢${hobby}`);
}// 用apply修改this为user,参数以数组形式传入
introduce.apply(user, [18, "编程"]); // 输出:"我叫小明,18岁,喜欢编程"// 场景:求数组最大值(利用Math.max的this无关性)
const numbers = [1, 3, 5, 2];
const max = Math.max.apply(null, numbers); // 等价于Math.max(1,3,5,2)
console.log(max); // 输出:5
bind () 方法
------》返回值是一个函数,但没有调用。
const btn = document.getElementById("btn");
const data = { id: 100, name: "测试数据" };// 定义一个需要访问data的函数
function handleClick() {console.log("当前数据:", this); // 希望this指向data
}// 直接绑定事件,this会指向按钮(事件源),不符合预期
btn.onclick = handleClick; // 输出:<button>...</button>// 用bind修改this为data,返回新函数绑定给事件
btn.onclick = handleClick.bind(data); // 输出:{id: 100, name: "测试数据"}// 提前绑定部分参数(柯里化)
function add(a, b) {return a + b;
}
const add5 = add.bind(null, 5); // 固定a=5,this无关用null
console.log(add5(3)); // 输出:8(等价于add(5,3))
DOM节点
节点类型:元素节点 属性节点 文本节点
firstChild() :第一个节点,包括空格,如果你有普通文本(没有套标签)就不是空白
firstElementChild:第一个元素节点,只包含子标签
attributes:拿到元素所有的属性节点,返回值是数组
nodeType
能够判断当前节点类型,返回值为number,元素节点1.属性节点2,文本节点3
nodeName
能够返回当前节点类型,文本节点#text,属性节点和元素节点就是你设置的属性名与元素名
nodeValue
能够返回当前的节点的节点值,例如文本节点空(也就是空白,如果你有文本就不是空白),元素节点是null,属性节点是属性值。
总结:

节点的创建
//增删改查
document.createElement('标签名');//创建元素节点
appendChild();添加标签,作为孩子到某个元素中,在末尾加,元素为空元素,也就是值为空,给元素设置样式,采用.style.属性名='属性值'就可以直接使用。
document.createTextNode("文本");//文本节点-----【注意:文本没有标签,则不能设置属性】
insertBefore(添加的元素,已有的元素);//插入到某个元素之前
cloneNode() ;复制 参数为布尔值,true是将当前元素以及子元素都会复制,false是只会复制当前元素,那个元素调用这个方法,就是克隆哪个元素
removeChild():删除指定子元素。
<div id="parent"><div class="existing">已有元素</div>
</div>
<div id="original" style="border: 1px solid #000; padding: 10px;">原始元素<span>子元素</span>
</div>
<div class="to-remove">要删除的元素</div><script>// 此处可放入上述JS代码依次执行
</script>
创建元素节点(增)
// 创建元素节点(如div)
const newDiv = document.createElement('div');
// 设置样式
newDiv.style.width = '100px';
newDiv.style.height = '100px';
newDiv.style.backgroundColor = 'pink';// 创建文本节点(无标签,不能设置样式)
const textNode = document.createTextNode('新内容');
// 将文本节点添加到元素中
newDiv.appendChild(textNode);// 将元素添加到body末尾
document.body.appendChild(newDiv);
插入元素(增)
// 已有父元素
const parent = document.getElementById('parent');
// 已有子元素(作为参考位置)
const existingChild = parent.querySelector('.existing');// 创建新元素
const insertDiv = document.createElement('div');
insertDiv.textContent = '插入的元素';
insertDiv.style.color = 'blue';// 插入到existingChild之前
parent.insertBefore(insertDiv, existingChild);
复制元素(改 / 克隆)
// 获取要复制的元素
const original = document.getElementById('original');// 复制(true:复制自身+所有子元素;false:仅复制自身)
const cloneWithChild = original.cloneNode(true);
const cloneWithoutChild = original.cloneNode(false);// 添加到页面
document.body.appendChild(cloneWithChild); // 带子元素的复制体
document.body.appendChild(cloneWithoutChild); // 仅自身的复制体
删除元素(删)
// 获取父元素和要删除的子元素
const parent = document.getElementById('parent');
const childToRemove = parent.querySelector('.to-remove');// 删除子元素(需通过父元素调用)
parent.removeChild(childToRemove);
margin塌陷:父元素嵌套子元素,子元素添加margin-top,那么父元素会跟随
子元素一起掉下来。解决:给父元素添加overflow:hidden
阴影 :box-shadow:x轴 y轴 模糊度 颜色
溢出显示滚动:overflow:scroll/auto ---->auto根据内容显示滚动条,否则不显示。
移动端适配主要单位:px % vh/vw(可视窗口宽高) em(根据父元素大小进行计算) rem(根据根元素(html)字体大小进行计算)
弹性布局
特点:子元素横向排列,需要给父元素添加弹性条件
display:flex
不会脱离文档流
失效属性:float,clear,vertical-align
容器属性子元素属性(项目属性)
容器属性添加给父元素
主轴(x轴)侧轴(y轴)
水平对齐方式:justify-content,值如下
flex-start 默认值,子元素靠主轴起始端对齐。
flex-end 子元素靠主轴结束端对齐。
center 子元素在主轴上居中对齐。
space-around(空白环绕) 子元素均匀分布,每个子元素两侧间距相等(首尾间距为中间间距的一半)。
space-bewteen 子元素均匀分布,首尾元素贴紧容器两端。
space-evenly 子元素均匀分布,所有间距(包括首尾与容器的间距)相等。
改变子元素的排列方向:flex-direction,值如下。
row(默认):主轴为水平方向,子元素从左到右排列。row-reverse:主轴为水平方向,子元素从右到左排列(反转 row 方向)。column:主轴为垂直方向,子元素从上到下排列。column-reverse:主轴为垂直方向,子元素从下到上排列(反转 column 方向)。
设置子元素换行:flex-wrap,值如下。
nowrap:不换行,子元素会被强制压缩(或溢出容器),保持在同一行。常用于子元素尺寸固定且总宽不超容器时。
wrap:允许换行,子元素超出容器宽度时,自动折到下一行(从上到下换行)。常用于响应式布局(如移动端卡片自动换行)。
wrap-reverse:允许换行,但折行方向相反(从下到上换行,较少用)。常用于特殊反向布局需求。
单行子元素垂直方向的对齐方式:align-items
flex-start
flex-end
center
只有这三个值!!!
多行子元素垂直方向的对齐方式,align-content
flex-start
flex-end
center
space-around(空白环绕)
space-bewteen
space-evenly
(取值和justify-content取值一样,但方向是垂直方向的)
复合属性:flex-flow : flex-wrap/wrap 方向【取值为column,row】
单个元素的对其属性:align-self
改变子元素排列顺序:order:数字值。//小于0往起始位置移动,大于0往末尾(结束位置)移动
设置所占比例:flex:属性值,除去固定空间,剩余空间都是自己的。
