如何使用JavaScript获得聚焦的HTML元素样式?

时间:2020-01-27 10:33:40

标签: javascript html css focus puppeteer

当元素被聚焦时,我想获得元素的计算样式。我正在使用puppeteer,我想比较聚焦前的CSS和聚焦后的CSS。我可以使用element.focus()成功地关注某个元素,并可以通过检查活动元素(document.activeElement)来确认它的焦点。但是,此元素的计算样式(getComputedStyle()与焦点之前的样式相同,这不是我期望的。

有没有办法在获得焦点之后获取元素的CSS?

为清楚起见,我正在编写一个JavaScript工具,该工具可以刮擦任何网站,以检查所关注元素的轮廓或边框是否与页面背景形成足够的对比(以使其符合可访问性准则{{3 }}。为此,我需要能够在元素处于焦点状态时获得轮廓/边框的颜色。通常,焦点轮廓将在CSS中的:focus { ... }下定义,因此这是我希望为任何元素检索的内容。

2 个答案:

答案 0 :(得分:0)

您需要注意脚本中代码的顺序。如果您在getComputedStyle()之前更改样式,则会得到更改。

例如:

document.querySelector("input").addEventListener("focus", (e) => {
  console.log(window.getComputedStyle(e.target, null).color);
  e.target.style.color = "red";
  console.log(window.getComputedStyle(e.target, null).color);
  e.target.style.color = "blue";
})
<input type="text" style="color: blue;">

答案 1 :(得分:0)

getComputedStyle返回实况CSSStyleDeclaration时,您必须手动记录CSS样式,以使CSS保持聚焦。

这是一个可行的示例:

let allInputs = document.querySelectorAll('input')
let beforeFocusStyles = Array.from(allInputs).reduce(function(final, elem) {
  final[elem.dataset.identifier] = (function() {
    let liveStyle = window.getComputedStyle(elem)
    let value = {}
    for (let key in liveStyle) {
      value[key] = liveStyle[key]
    }
    return value
  })()
  return final
}, {})

Array.from(allInputs).forEach(elem => {
  elem.onfocus = function() {
    let afterFocusStyle = window.getComputedStyle(elem)
    let differenceInStyle = (function() {
      let beforeFocusStyle = beforeFocusStyles[elem.dataset.identifier]
      let differences = []
      for (let key in afterFocusStyle) {
        if (beforeFocusStyle[key] !== afterFocusStyle[key]) {
          differences.push([key, beforeFocusStyle[key], afterFocusStyle[key]])
        }
      }
      return differences
    })()

    differenceInStyle.forEach(difference => {
      console.log(difference[0], difference[1], difference[2])
    })
  }
})
.type1 {
  outline: 1px solid black;
  border: none;
}

.type1:focus {
  outline: 2px solid red;
  border: none;
}

.type2 {
  outline: 1px solid blue;
  border: none;
}

.type2:focus {
  outline: 2px solid green;
  border: none;
}
<input type="text" class="type1" data-identifier="1">
<input type="text" class="type2" data-identifier="2">