Javascript 使用样式捕获当前dom时缺少样式元素
我试图使用Selenium捕获当前有效的dom样式。其想法是创建一个引擎,可以捕获它在不同点处理的网页的状态(主要用于测试目的)。因此,我希望有一个跨平台的解决方案(不包括IE),这就是为什么我选择纯javascrit解决方案的原因。因此,我最终要做的是使用Javascript 使用样式捕获当前dom时缺少样式元素,javascript,css,dom,Javascript,Css,Dom,我试图使用Selenium捕获当前有效的dom样式。其想法是创建一个引擎,可以捕获它在不同点处理的网页的状态(主要用于测试目的)。因此,我希望有一个跨平台的解决方案(不包括IE),这就是为什么我选择纯javascrit解决方案的原因。因此,我最终要做的是使用Webdriver.executeScript从Selenium调用一个脚本,它允许我提取dom,并在特定点内联所有样式。对于脚本,我从另一个答案中得到了很大的启发,我在网站上找到了这个答案,但是我找不到返回的链接 虽然解决方案可以正常工作,
Webdriver.executeScript
从Selenium调用一个脚本,它允许我提取dom,并在特定点内联所有样式。对于脚本,我从另一个答案中得到了很大的启发,我在网站上找到了这个答案,但是我找不到返回的链接
虽然解决方案可以正常工作,但仍然存在一些问题,主要是填充和字体。代码如下:
const getCurrentDom = (function () {
let defaultStylesByTagName = {};
const noStyleTags = {"BASE":true,"HEAD":true,"HTML":true,"META":true,"NOFRAME":true,"NOSCRIPT":true,"PARAM":true,"SCRIPT":true,"STYLE":true,"TITLE":true};
const ignoreTags = new Set(['SCRIPT', 'STYLE', 'LINK']);
const tagNames = ["A","ABBR","ADDRESS","AREA","ARTICLE","ASIDE","AUDIO","B","BASE","BDI","BDO","BLOCKQUOTE","BODY","BR","BUTTON","CANVAS","CAPTION","CENTER","CITE","CODE","COL","COLGROUP","COMMAND","DATALIST","DD","DEL","DETAILS","DFN","DIV","DL","DT","EM","EMBED","FIELDSET","FIGCAPTION","FIGURE","FONT","FOOTER","FORM","H1","H2","H3","H4","H5","H6","HEAD","HEADER","HGROUP","HR","HTML","I","IFRAME","IMG","INPUT","INS","KBD","KEYGEN","LABEL","LEGEND","LI","LINK","MAP","MARK","MATH","MENU","META","METER","NAV","NOBR","NOSCRIPT","OBJECT","OL","OPTION","OPTGROUP","OUTPUT","P","PARAM","PRE","PROGRESS","Q","RP","RT","RUBY","S","SAMP","SCRIPT","SECTION","SELECT","SMALL","SOURCE","SPAN","STRONG","STYLE","SUB","SUMMARY","SUP","SVG","TABLE","TBODY","TD","TEXTAREA","TFOOT","TH","THEAD","TIME","TITLE","TR","TRACK","U","UL","VAR","VIDEO","WBR"];
for (let i = 0; i < tagNames.length; i++) {
if(!noStyleTags[tagNames[i]]) {
defaultStylesByTagName[tagNames[i]] = computeDefaultStyleByTagName(tagNames[i]);
}
}
function computeDefaultStyleByTagName(tagName) {
let defaultStyle = {};
const element = document.body.appendChild(document.createElement(tagName));
const computedStyle = getComputedStyle(element);
for (let i = 0; i < computedStyle.length; i++) {
defaultStyle[computedStyle[i]] = computedStyle[computedStyle[i]];
}
document.body.removeChild(element);
return defaultStyle;
}
function hasTagName(node, tagName){
if(node.tagName === undefined){
return false;
}
return node.tagName.toUpperCase() === tagName.toUpperCase();
}
function getDefaultStyleByTagName(tagName) {
tagName = tagName.toUpperCase();
if (!defaultStylesByTagName[tagName]) {
defaultStylesByTagName[tagName] = computeDefaultStyleByTagName(tagName);
}
return defaultStylesByTagName[tagName];
}
function isIgnored(node){
if(node === undefined){
return true;
}
if(node.tagName === undefined){
return false;
}
return ignoreTags.has(node.tagName.toUpperCase());
}
function isComputeStyle(node){
if(node.tagName === undefined){
return false;
}
return node instanceof Element && !noStyleTags[node.tagName.toUpperCase()];
}
function computeImageNode(node){
let img = document.createElement("img");
if(node.alt != ""){
img.alt = node.alt;
}
if(node.id != ""){
img.id = node.id;
}
img.width = node.width;
img.height = node.height;
img.class = node.class;
console.log(img.outerHTML);
return img;
}
function deepCloneWithStyles (node) {
if(hasTagName(node, "img")){
return computeImageNode(node);
}
const clone = node.cloneNode(false);
if (isComputeStyle(node)) {
const defaultStyle = getDefaultStyleByTagName(node.tagName);
const computedStyle = getComputedStyle(node);
updateStyle(clone, computedStyle, defaultStyle);
clone.style.font = node.style.font;
}
updateStyle(clone, node.style, {});
for (let child of node.childNodes){
if(!isIgnored(child)){
clone.appendChild(deepCloneWithStyles(child));
}
}
return clone;
}
function updateStyle(node, styles, defaultStyle){
if(styles === undefined){
return;
}
for (let i = 0, l = styles.length; i < l; ++i) {
const cssPropName = styles[i];
if(defaultStyle !== undefined && styles[cssPropName] === defaultStyle[cssPropName]){
continue;
}
if (styles[cssPropName] !== null && styles[cssPropName] !== "") {
node.style[cssPropName] = styles[cssPropName];
}
}
}
return function computeDom() {
let node = document.documentElement;
return deepCloneWithStyles(node).outerHTML;
}
})();
const getCurrentDom=(函数(){
让defaultStylesByTagName={};
const noStyleTags={“BASE”:true,“HEAD”:true,“HTML”:true,“META”:true,“NOFRAME”:true,“NOSCRIPT”:true,“PARAM”:true,“SCRIPT”:true,“STYLE”:true,“TITLE”:true};
const ignoreTags=新集合(['SCRIPT','STYLE','LINK']);
const标记名=[“A”、“ABBR”、“ADDRESS”、“AREA”、“ARTICLE”、“side”、“AUDIO”、“B”、“BASE”、“BDI”、“BDO”、“BLOCKQUOTE”、“BODY”、“BR”、“BUTTON”、“CANVAS”、“CAPTION”、“CENTER”、“CITE”、“CODE”、“COL”、“COLGROUP”、“COMMAND”、“DATALIST”、“DD”、“DEL”、“DETAILS”、“DFN”、“DIV”、“DL”、“DT”、“EM”、“EMBED”、“FIELDSET”、“FIGCAPTION”、“FIGCAPTION”、“fig”、“FONT”、“FOOTER”、“FORM”、“H1”、“H2”、“H3”、“H4”、“H5”、“H6”“头”、“头”、“HGROUP”、“HR”、“HTML”、“I”、“IFRAME”、“IMG”、“INPUT”、“INS”、“KBD”、“KEYGEN”、“LABEL”、“legen”、“LI”、“LINK”、“MAP”、“MARK”、“MATH”、“MENU”、“META”、“METER”、“NAV”、“NOBR”、“NOSCRIPT”、“OBJECT”、“OL”、“OPTION”、“OPTION”、“opt”、“OPTGROUP”、“OUTPUT”、“P”、“PARAM”、“PRE”、“PROGRESS”、“Q”、“RP”、“RT”、“RUBY”、“S”、“SAMP”、“SCRIPT”、“SECTION”、“SELECT”、“SMALL”、“SOURCE”、“SPAN”、“STRONG”,“样式”、“子”、“摘要”、“SUP”、“SVG”、“表格”、“TBODY”、“TD”、“TEXTAREA”、“TFOOT”、“TH”、“THEAD”、“TIME”、“TITLE”、“TR”、“TRACK”、“U”、“UL”、“VAR”、“VIDEO”、“WBR”];
for(设i=0;i
如上所述,问题在于,在处理页边距/填充时,此函数生成的dom的行为似乎有点古怪,字体似乎总是设置为Times New Roman。下面是stackOverflow的一个页面示例:
和使用脚本生成的dom的相同页面:
事实上,没有渲染图像是出于设计,因为我只想保留一个包含所有内容的文件(因此我只保留大小)。但是,正如您在左侧链接上看到的,左侧有一个巨大的填充,在原始图像中不存在,问问题按钮中的空白也是如此