使用 Javascript 将样式动态添加到样式表,但我收到“无法读取未定义的属性'长度'”错误
Using Javascript to dynamically add styles to stylesheet but I get a "Cannot read property 'length' of undefined" error
我目前正在尝试制作自己的polyfill,这将允许Internet Explorer等旧浏览器使用传统的css选择器读取和执行媒体查询。流程如下所示:
- 遍历文档中找到的每个样式表
- 在样式表中运行每个样式规则,搜索媒体查询
- 定义我们的目标设备尺寸,然后应用适当的"id"
- 将带有选择器的 css 行动态添加到现有样式表中
这个想法是,polyfill 将搜索媒体查询,然后将父"id"应用于与设备大小对应的正文,例如:
#tablet .wrap { ... }
#mobile .wrap { ... }
#desktop .wrap { ... }
到目前为止,javascript看起来像这样:
var styleSheets = document.styleSheets;
var debug = false;
var ruleParts = mediaPart = rules = compiledSel = className = '';
var dimS = dimB = 0;
var idList = Array('smallMobile','mobile','tablet','smallDesktop','desktop');
// run through each stylesheet
for( i = 0; i < styleSheets.length; i++ ) {
// If uncommented will show each stylesheets rules contained therein
if( debug ) {
console.log( styleSheets[i].cssRules );
}
// run through each rule declaration
for( a = 0; a < styleSheets[i].rules.length; a++ ) {
if( styleSheets[i].rules[a].type == 4 ) {
mediaPart = styleSheets[i].rules[a].media[0].split(' and ');
dimS = parseInt( mediaPart[0].replace(/[():A-Za-z$-]/g, "") );
dimB = parseInt( mediaPart[1].replace(/[():A-Za-z$-]/g, "") );
if( dimS > 0 && dimB < 418 ) {
className = idList[0];
} else if( dimS > 419 && dimB < 767 ) {
className = idList[1];
} else if( dimS > 768 && dimB < 1024 ) {
className = idList[2];
} else if( dimS > 1025 && dimB < 1201 ) {
className = idList[3];
} else {
className = idList[4];
}
if( styleSheets[i].rules[a].cssRules.length > 1 ) {
for( b = 0; b < styleSheets[i].rules[a].cssRules.length; b++ ) {
ruleParts = styleSheets[i].rules[a].cssRules[b].cssText.split('{');
rules = ruleParts[1].split('}');
addCSSRule( styleSheets[i], '#'+ className +' '+ ruleParts[0], rules[0], 1 );
/*
* Investigate why the .insertRule() and addRule() are failing specifically what is causing them to break
*
*/
}
} else {
}
}
}
}
function addCSSRule(sheet, selector, rules, index) {
if(sheet.insertRule) {
sheet.insertRule(selector + "{" + rules + "}", index);
} else {
sheet.addRule(selector, rules, index);
}
}
现在一切都按照我想要的方式工作,甚至将 css 规则添加到样式表中,但是我收到此错误,我不完全确定在什么时候:
Uncaught TypeError: Cannot read property 'length' of undefined
如果我删除对此行的函数调用,则不会收到错误:
addCSSRule( styleSheets[i], '#'+ className +' '+ ruleParts[0], rules[0], 1 );
所以我不确定在函数调用和读取.length
期间发生了什么
我的 html 看起来像这样:
<!DOCTYPE html>
<head>
<title>Style Manipulation VIA Javascript</title>
<link rel="stylesheet" href="css/test.css" />
<link rel="stylesheet" href="css/typo.css" />
</head>
<body>
<div class="wrap">
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus</p>
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus</p>
</div>
总的来说,我需要弄清楚为什么无法读取属性长度以及addCSSRule
函数调用中导致错误的原因。
styleSheets 对象的 IE 和 W3C 实现之间存在显着差异,希望以下内容足以解释性以帮助:
function getStyleRules() {
var rule, rules;
var sheet, sheets = document.styleSheets;
var ruleCssText = ['Rules:','',]
for (var i=0, iLen=sheets.length; i<iLen; i++) {
sheet = sheets[i];
// Get the rules using:
//
// W3C model IE model
rules = sheet.cssRules || sheet.rules;
for (var j=0, jLen=rules.length; j<jLen; j++) {
rule = rules[j];
// The selector is available here in both models,
// but uppercase in IE so set to lower case
alert('Selector: ' + rule.selectorText.toLowerCase());
// Getting the actual rule text
// W3C model - selector and rule
if (rule.cssText) {
ruleCssText.push(rule.cssText);
// IE model - rule only, doesn't include selector
} else if (rule.style) {
ruleCssText.push(rule.style.cssText.toLowerCase());
}
}
alert(ruleCssText.join(''n'));
}
}
有关于 IE 模型的 MSDN 的文档,但我不确定它是否仍然涵盖较旧的 IE 或仅涵盖可能同时使用这两种模型的较新版本:样式工作表对象、规则对象
这里有一些 Opera 文档:动态样式 - 使用 JavaScript 操作 CSS
这里还有一些信息:样式表对象,CSS 规则对象。
与所有网络资源一样,请以严重的怀疑态度对待它,寻找其他来源并在尽可能多的浏览器(尤其是旧浏览器)中进行测试,测试,测试。
运行代码:
> TypeError: styleSheets[i].rules is undefined
>
> for( a = 0; a < styleSheets[i].rules.length; a++ ) {
在这里,您混合了IE(规则)和W3C(cssRules)模型。最好只获取一次规则对象:-
var sheetRules = styleSheets[i].rules || styleSheets[i].cssRules;
for( a = 0; a < sheetRules.length; a++ ) {
然后你有:
if ( sheetRules[a].type == 4 ) {
但是 IE 模型没有为 rules 对象实现类型属性(即使 MSDN 文档说它实现了,但这是针对 IE 9 及更高版本实现的 W3C 模型)。
然后:
> mediaPart = sheetRules[a].media[0].split(' and ');
请注意,介质是工作表的属性,而不是规则的属性,因此:
// Perhaps mediaParts (plural)?
mediaPart = styleSheets[i].media;
令人讨厌的是,IE 模型具有带有字符串类型的媒体属性,但它是空的。您可以使用以下命令获取其文本:
styleSheets[0].cssText.replace(/'s+/g,' ').match(/@media.+}[^{]+}/)
.
> // TypeError: mediaPart[1] is undefined
> dimB = parseInt( mediaPart[1].replace(/[():A-Za-z$-]/g, "") );
在这里,您似乎期望"和"在规则中。您尚未提供规则示例,但如果它们如下所示:
@media screen, print { ... }
然后,媒体是媒体规则的列表:media[0]
是屏幕,media[1]
是打印,因此您需要循环访问媒体规则。
无论如何,现在就足够了。
- 为什么“;未定义的“;在JavaScript中结束循环
- 要求未定义JS回调参数
- 如何检查管道中未定义的项目
- TypeError:无法读取属性'推'未定义的JavaScript
- $window.ga在AngularJS事件中未定义
- 未捕获的TypeError无法读取未定义的属性socialsharing
- 为什么grunt contrib connect的中间件选项的第三个参数是未定义的
- 无法获取属性'selectedIndex'的未定义引用或null引用
- 如何消除代码中的未定义和其他问题
- 未定义的样式
- 在js中访问元素时不透明度和样式未定义,但在css中定义
- Microsoft JScript运行时错误:无法获取属性'的值;样式':对象为null或未定义
- IE错误:无法设置属性'的值;样式':对象为null或未定义
- 我一直收到未捕获的引用错误:未定义下拉菜单和未捕获的类型错误:无法读取 null 的属性“样式”
- 使用 Javascript 将样式动态添加到样式表,但我收到“无法读取未定义的属性'长度'”错误
- 无法读取未定义的属性“样式”
- 样式.在元素正确定义时显示未定义
- MGWT ScrollPanel.scrollTo(0, y) 导致无法读取未定义的属性“样式”
- 是对HTMLElement#样式的未定义属性的赋值的返回值,保证与赋值相同
- Div样式未定义(Javascript)