document.stylesheet 相关

在查看mdn的一个知识的时候,有这么一段代码

const borderBtn = document.querySelector(".border");
const bgColorBtn = document.querySelector(".bgcolor");
const colorBtn = document.querySelector(".color");
const box = document.querySelector(".box");

function random(min, max) {
  const num = Math.floor(Math.random() * (max - min)) + min;
  return num;
}

function randomColor() {
  return rgb(${random(0, 255)} ${random(0, 255)} ${random(0, 255)});
}

const stylesheet = document.styleSheets[1];
const boxParaRule = [...stylesheet.cssRules].find(
  (r) => r.selectorText === ".box p",
);

疑问:stylesheet.cssRules在浏览器查看,好像本来就是Array,怎么不直接用find,而需要先解构,再进行find呢?

其实细究就会发现:错误之处在于stylesheet.cssRules 是一个 CSSRuleList 对象,它类似于数组,但并不是一个真正的数组。
因此也就无法直接使用数组方法,比如 find,在 CSSRuleList 上。通过解构操作符 [...],你可以将这个对象转换为一个真正的数组,然后就可以使用 find 方法了。

如果直接在 CSSRuleList 上使用 find,会报错,因为 CSSRuleList 并没有 find 方法。

const boxParaRule = [...stylesheet.cssRules].find(
  (r) => r.selectorText === ".box p",
);

而这里的 [...stylesheet.cssRules]CSSRuleList 转换为数组,就可以使用数组的 find 方法了。

其实可以通过以下两种方式来处理 CSSRuleList

  1. 使用解构转换为数组:

    const boxParaRule = [...stylesheet.cssRules].find(
      (r) => r.selectorText === ".box p",
    );
    
  2. 使用 Array.from 方法:

    const boxParaRule = Array.from(stylesheet.cssRules).find(
      (r) => r.selectorText === ".box p",
    );
    

两种方式的效果是一样的,都是将 CSSRuleList 转换为数组,然后使用数组的 find 方法找到符合条件的规则。

那么问题又来了:我怎么在浏览器控制台判断一个东西它是数组还是只是类数组呢?

要在浏览器控制台判断一个对象是数组还是类数组,可以通过以下方法:

  1. 查看对象的构造函数

    • 数组的构造函数是 Array,类数组对象的构造函数通常是 Object
  2. 检查对象的 length 属性

    • 类数组对象通常具有 length 属性,但它们没有数组的方法(例如 mapfilter 等)。
  3. 使用 Array.isArray 方法

    • 这是一个内置方法,可以准确判断一个对象是否为数组。

下面是一些具体的方法来判断:

使用 constructor 属性

const cssRules = document.styleSheets[0].cssRules;
console.log(cssRules.constructor); // 输出 CSSRuleList
console.log(cssRules.constructor === Array); // false
console.log(cssRules.constructor === Object); // true

使用 Array.isArray 方法

const cssRules = document.styleSheets[0].cssRules;
console.log(Array.isArray(cssRules)); // false

检查 length 属性并尝试调用数组方法

const cssRules = document.styleSheets[0].cssRules;
console.log(cssRules.length); // 输出 length

try {
  cssRules.map((rule) => console.log(rule)); // 会报错,因为 CSSRuleList 没有 map 方法
} catch (e) {
  console.log("cssRules does not have map method");
}

将类数组对象转换为数组

使用 Array.from 或解构操作符 [...object] 可以将类数组对象转换为数组。

const cssRules = document.styleSheets[0].cssRules;
const arrayCssRules = Array.from(cssRules); // 或者使用 [...cssRules]
console.log(Array.isArray(arrayCssRules)); // true

例子

以下是一个综合例子,展示了如何判断 cssRules 是否为数组或类数组:

const cssRules = document.styleSheets[0].cssRules;

// 使用 constructor 属性
console.log("Constructor:", cssRules.constructor);
console.log("Is Array:", cssRules.constructor === Array);

// 使用 Array.isArray 方法
console.log("Array.isArray:", Array.isArray(cssRules));

// 检查 length 属性并尝试调用数组方法
console.log("Length:", cssRules.length);
try {
  cssRules.map((rule) => console.log(rule));
} catch (e) {
  console.log("cssRules does not have map method");
}

// 将类数组对象转换为数组并检查
const arrayCssRules = Array.from(cssRules);
console.log("Converted to Array:", Array.isArray(arrayCssRules));

通过以上方法,你可以在浏览器控制台中轻松判断一个对象是数组还是类数组。

如果在console直接查看一般也可以看到prototype的信息:

类数组

数组

posted @ 2024-07-11 20:49  胡安  阅读(7)  评论(0编辑  收藏  举报