❤️ Author: 老九
☕️ 个人博客:老九的CSDN博客
个人名言:不可控之事 乐观面对
系列专栏:
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Documenttitle>
<script>
function talksAbout(node, string) {
if (node.nodeType == document.ELEMENT_NODE) {
for (var child of node.childNodes) {
if (talksAbout(child, string)) {
return true;
}
}
} else if (node.nodeType == document.TEXT_NODE) {
return node.nodeValue.includes(string);
}
return false;
}
script>
head>
<body>
<div>bbbdiv>
<script>
document.body.firstChild.nextSibling.nextSibling.nextSibling.textContent =
"ccc";
script>
<strong>cccstrong>
<input type="text" />
ccc
body>
html>
调试小技巧:如果想在控制台找到一个函数,先在console中输入这个函数,然后点击一下这个函数输出的东西,就可以自动跳转到当前函数了
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Documenttitle>
head>
<body>
<p>
the cat
<img src="cat.jpg" alt="Cat" />
is run after the
<img src="hat.jpg" alt="Hat" />
p>
<button onclick="replaceImages()">Replacebutton>
<script>
function replaceImages() {
var imgs = document.getElementsByTagName("img");
for (var i = 0; i < imgs.length; i++) {
var img = imgs[i];
var textNode = document.createTextNode(img.alt);
img.parentNode.replaceChild(textNode, img);
}
}
script>
body>
html>
介绍稀疏数组,当数组里面存在下标不存在的数组,就叫做稀疏数组
当我们创建 a = new Array(100000000)的时候,如果一个数组项存一个整数,一个整数占4个字节,那就要占4亿个字节,先除一个1024变成k,再除1024变成兆(M),最后算出来占381兆左右,但是在js中是不会占用这么多空间的,js会把它想成一个对象,以一个对象的形式存储,这个对象就有一个length属性。
因此我们可以得出一个结论,一个对象也可以看作是一个数组,称为类数组。
那么如果想让类数组获得数组本身的一些方法的话,我们可以通过Array.prototype.reverse.call(obj),实现this的转移,或者直接将obj._ proto _ = Array.prototype,直接将数组的原型属性赋给obj的原型上面,使得类数组获得数组的自有方法。
上面那个必须是类数组对象,才能使用reverse()
function elt(tagName, ...children) {
var node = document.createElement(tagName);
for (var child of children) {
//如果child是文本结点,需要判断把字符串转化成文本节点
if (typeof child === "string") {
child = document.createTextNode(child);
}
node.appendChild(child);
}
return node;
}
function elt(tagName, attrs = {}, ...children) {
var node = document.createElement(tagName);
if (attrs) {
for (var key in attrs) {
debugger;
var val = attrs[key];
node.setAttribute(key, val);
}
}
for (var child of children) {
if (typeof child === "string") {
child = document.createTextNode(child);
}
node.appendChild(child);
}
return node;
}
parentNode和parentElement的区别
1.获取根节点的区别:parentNode 可以获取根节点,而 parentElement 获取不到根节点。如果当前节点的父节点是文档的根节点(即 Document 对象),那么 parentNode 返回该根节点,而 parentElement 返回 null。
2.获取父节点类型的区别:parentNode 可以获取任何类型的父节点,包括元素节点、文本节点、注释节点等,而 parentElement 只能获取元素节点类型的父节点,如果当前节点的父节点不是元素节点,则 parentElement 返回 null。
el.firstElementChild/lastElementChild
el.nextElementSibiling/previousElementSibiling
el.childNodes/children
function traverseDOM(node, action = console.log) {
if (node.nodeType == document.ELEMENT_NODE) {
action(node);
for (var child of node.children) {
traverseDOM(child, action);
}
}
}
function traverse(root) {
if (root) {
console.log(root);
traverse(root.left);
traverse(root.right);
}
}
function getElementsByTagName(node, tagName) {
var result = [];
for (var child of node.children) {
if (child.tagName == tagName) {
result.push(child);
}
result.push(...getElementsByTagName(child, tagName));
}
return result;
}
function getElementsByTagName2(node, tagName) {
var result = [];
traverseDOM(node, (it) => {
if (it.tagName == tagName) {
result.push(it);
}
});
if (result[0] == node) {
result.shift();
}
return result;
}
function getElementById(id, node = document.documentElement) {
if (node.id === id) {
return node;
} else {
for (var child of node.children) {
var result = getElementById(id, child);
if (result) {
return result;
}
}
return null;
}
}
function getElementById2(id) {
var result = null;
traverseDOM(document.documentElement, (it) => {
if (it.id === id) {
result = it;
}
});
return result;
}
通过$0.offsetWidth和$0.offsetHeight可以获取结点的宽高,包含边框及以内的区域
页面的滚动位置:scrollX,scrollY,我们可以通过window.scrollX/scrollY/scrollTo/scrollBy(0,150):每次都向下滚动150px
补充:色块是不受行高的影响的,只是受最初行高和字号影响的。
//one比two慢很多
//添加一下就要读,读就会很久
function one() {
var target = document.getElementById("one");
while (target.offsetWidth < 2000) {
target.append("x");
}
}
function two() {
var target = document.getElementById("two");
target.append("xxxxxxxxxx");
var total = 2000 / (target.offsetWidth / 10);
for (var i = 10; i < total; i++) {
target.append("x");
}
}
下面这段代码可以实现点击按钮获得按钮里面的值
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Documenttitle>
head>
<body>
<button>1button><button>2button><button>3button><button>4button
><button>5button><button>6button><button>7button><button>8button
><button>9button><button>10button><button>11button><button>12button
><button>13button><button>14button><button>15button><button>16button
><button>17button><button>18button><button>19button
><button>20button>
<script>
var buttons = document.querySelectorAll("button");
for (var button of buttons) {
button.addEventListener("click", function (e) {
console.log(this.textContent);
});
}
script>
body>
html>
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Documenttitle>
head>
<body>
<div>
<button title="foo" class="bar baz">1button>
<button title="fod" class="bar baz">2button>
<button title="fod" class="bar baa">3button>
<button>4button><button>5button><button>6button><button>7button
><button>8button><button>9button><button>10button><button>11button
><button>12button><button>13button><button>14button
><button>15button><button>16button><button>17button
><button>18button><button>19button><button>20button>
div>
<script>
var div = document.querySelector("div");
div.addEventListener("click", function (e) {\
//下面这个if我们可以替换成if(e.target.matches('button.bar[title="fod"]')
//matches函数判断当前DOM节点是否能完全匹配对应的CSS选择器,如果匹配成功,返回true,反之则返回false
if (
e.target.tagName === "BUTTON" &&
e.target.classList.contains("bar")
) {
console.log(e.target.textContent);
}
});
script>
body>
html>
被动事件和主动事件是与浏览器滚动行为相关的两种事件类型。被动事件的处理不会阻止浏览器的默认滚动行为,而主动事件的处理可能会阻止浏览器的默认滚动行为。
具体来说,被动事件是指那些不会调用preventDefault()方法来阻止默认滚动行为的事件。这些事件在处理时,浏览器会立即执行默认的滚动行为,而不需要等待JavaScript代码的处理。这种行为可以提高页面滚动的流畅度和响应速度,因为浏览器可以在事件处理程序之前就开始处理滚动事件。一般来说,被动事件的处理速度比主动事件更快,因为它不需要等待JavaScript代码的执行。
主动事件则是指那些可能会调用preventDefault()方法来阻止默认滚动行为的事件。这些事件在处理时,如果事件处理程序调用了preventDefault()方法,浏览器就会停止执行默认的滚动行为,从而实现自定义的滚动行为。主动事件常常用于实现一些特殊的滚动效果,比如平滑滚动和惯性滚动等。
总的来说,被动事件和主动事件的区别在于它们处理滚动事件的方式。被动事件处理时不会阻止默认滚动行为,而主动事件可能会阻止默认滚动行为。在实际开发中,需要根据具体的需求选择合适的事件类型来处理滚动事件,以实现更好的用户体验。
addEventListener前面没有点什么什么,说明是全局的,整个页面的滚动。
max是最大可滚动到的高度,document.body.scrollHeight是页面可滚动高度,innerHeight是窗口的可视高度
如果事件处理函数根本不会调用preventDefault(),那么还让浏览器等待事件处理函数运行完毕才执行默认行为,事件的发生和事件默认行为的执行之间就会有一延迟,延迟时间为事件处理函数的运行时间;而如果这个时间比较久,则用户就会感受到明显的延迟,但是如果我们可以让浏览器知道时间处理函数不会调用preventDefault(),则浏览器就不用等待函数的运行完才执行默认行为,那么用户就不会感受到延迟。
鼠标滚动页面窗口,CSS的2D,3D相关的动画等不涉及布局计算的操作,可以跟页面内的死循环同时执行
所以页面的滚动从技术上可以跟时间处理函数同时执行,但是我们要告诉浏览器,我们的事件处理函数不会阻止默认行为,浏览器不用等函数运行完才知道,通过addEventListener的第三个参数,其中对象中capture是是否捕获事件,passive是是否是被动事件(事件处理函数是在默认事件发生之后执行的,是被动事件就不会调用preventDefault()) ,once表示是否是单次事件绑定,如果是,执行一次就删掉
如果passive是false,那么它是主动事件,我们在函数中调用了e.preventDefault(),但浏览器不知道我们是否调用了preventDefault,我们需要运行完函数才能执行页面滚动操作,如果我们在函数里写了一个1秒钟才能执行完的函数,那么滚动就会有卡顿。
如果passive是true,那么就告诉浏览器它是被动事件,不会调用e.preventDefault(),有死循环也不会卡顿。
如果事件处理程序不需要调用preventDefault()方法来阻止事件的默认行为,可以将passive属性设置为true,这样可以让浏览器在事件处理程序之前立即进行滚动处理,从而提高页面滚动的流畅度和响应速度。
————————————————————————
♥♥♥码字不易,大家的支持就是我坚持下去的动力♥♥♥
版权声明:本文为CSDN博主「亚太地区百大最帅面孔第101名」的原创文章