把样式置于DOM脚本之外
- style属性
我们可以这样设置前景色之类的属性:
element.style.color='red';
也可以使用下面的代码设置背景颜色:
element.style.backgroundColor='red';
将background-color转换为驼峰形式大小写形式的backgroundColor(删除连接字符串并将后续单词的首字母变成大写)是必须的,DOM2样式规范为CSSStyleDeclaration对象定义了相应的方法,比如setProperty()就使用固有的带连字符的CSS属性名称和值(但是ie不支持):
element.style.setProperty('background-color','red');
为了不针对环境,将setStyleById(),setStyleByClassName(),setStylsByTagName()方法添加到ADS库中。
/** *通过ID修改单个元素的样式 */function setStyleById(element, styles) { //取得对象的引用 if(!(element = $(element))) return false; //循环遍历styles对象并应用每个属性 for (property in styles) { if(!styles.hasOwnProperty(property)) continue; if(element.style.setProperty) { //DOM2样式规范方法 element.style.setProperty( uncamelize(property,'-'),styles[property],null); } else { //备用方法 element.style[camelize(property)] = styles[property]; } } return true;}window['ADS']['setStyle'] = setStyleById;window['ADS']['setStyleById'] = setStyleById;/** * 通过类名修改多个元素的 样式 */function setStylesByClassName(parent, tag, className, styles) { if(!(parent = $(parent))) return false; var elements = getElementsByClassName(className, tag, parent); for (var e = 0 ; e < elements.length ; e++) { setStyleById(elements[e], styles); } return true;}window['ADS']['setStylesByClassName'] = setStylesByClassName;/** * 通过标签名修改多个元素的样式 */function setStylesByTagName(tagname, styles, parent) { parent = $(parent) || document; var elements = parent.getElementsByTagName(tagname); for (var e = 0 ; e < elements.length ; e++) { setStyleById(elements[e], styles); }}window['ADS']['setStylesByTagName'] = setStylesByTagName;/**实例 ADS.setStylesByClassName( 'findclass', '*', document, {'background-color':'red'} ) 或者 ADS.setStylesByTagName('a',{'text-decoration':'underline'});*/
基于className切换样式
对于中小范围的表现变化,例如只影响少数元素的颜色、边框、背景和字体,可以通过切换className来避免在代码中苦苦寻找样式属性。
使用className切换方法可以维护适当的分离,并且为CSS设计者打开了使用样式表设计网站表现的大门。下面将操纵classname的方法添加到ADS库中
/*取得包含元素类名的数组*/function getClassNames(element) { if(!(element = $(element))) return false; //用一个空格替换多个空格,然后给予空格分割类名 return element.className.replace(/\s+/,' ').split(' ');};window['ADS']['getClassNames'] = getClassNames;/*检查元素是否存在某个类*/function hasClassName(element, className) { if(!(element = $(element))) return false; var classes = getClassNames(element); for (var i = 0; i < classes.length; i++) { //检测className是否匹配,如果是则返回true if (classes[i] === className) { return true; } } return false;};window['ADS']['hasClassName'] = hasClassName;/*为元素添加类*/function addClassName(element, className) { if(!(element = $(element))) return false; //将类名添加到当前className的末尾,如果没有className,则不包含空格 element.className += (element.className ? ' ' : '') + className; return true;};window['ADS']['addClassName'] = addClassName;/*从元素中删除类*/function removeClassName(element, className) { if(!(element = $(element))) return false; var classes = getClassNames(element); var length = classes.length //循环遍历数组删除匹配的项 //因为从数组中删除项会使数组变短,所以要反响循环 for (var i = length-1; i >= 0; i--) { if (classes[i] === className) { delete(classes[i]); } } element.className = classes.join(' '); return (length == classes.length ? false : true);};window['ADS']['removeClassName'] = removeClassName;/*方便的取得与一个元素关联的所有累var element=document.getElementById('example');var classes=ADS.getClassName(element);var class;for (var i = 0;class=class[i];i++){ //对每个类进行操作}或者在向元素添加类名之前检查是否存在该雷鸣,以便实现切换效果function toggleClassName(element,className){ if(!)ADS.hasClassName(element,className) { ADS.addClassName(element,className); } else { ADS.removeClassName(element,className); }}ADS.addEvent('toggleButton','click',function(){ toggleClassName(this,'active')});甚至还能通过使用适当的事件侦听器和hover类生成翻转效果var element=document.getElementById('example');ADS.addEvent(element,'mouseover',function(){ADS.addClassName(this,'hover');});ADS.addEvent(element,'mouseout',function(){ADS.removeClassName(this,'hover')});*/
- 切换样式表
- 可以使用<link>元素的rel属性定义备用的样式表,并在他们之间进行切换。
- 可以为body标签应用一个类,并根据这个类修改CSS选择符--实际上是以body标签做为跟元素的className切换
- 可以动态添加或移除样式表
- 使用备用样式表
如果你始终遵守表现与标记分离原则,那你一定熟悉<link>元素:<link type="text/css" href="style.css" media="screen"/>
<link>元素包含一下属性:(和我们本章开始介绍的CSSStyleSheets类似)
- type:text/css
- href:指定样式的位置
- media:限制样式设备类型
这些是常用的,另外还有
- ref:表示样式与文档之间的关系
- disable:表示样式是否起作用
- title:表示与样式表关联的标题
下面讲一个说一个实例,源代码在上一节的chapter5中,switcher/example.html中,在这个例子中公共CSS问津没有设置title属性,而friends of ED和Apress样式都有一个相应的样式表文件,标记中空列表元素:
是由styleSwitcher.js文件通过load事件处理程序,在备用的样式表文件及其title属性的基础上动态生成的:(其实这个例子看起来听神奇的。)
ADS.addEvent(window,'load',function(){ //取得所有link元素 var list=ADS.$('styleSwitcher'); var links=document.getElementsByTagName('link'); var titles=[]; for(var i=0;i元素 if (links[i].getAttribute("rel").indexOf("style")!=-1 &&links[i].getAttribute("title")) { //如果该样式表还未添加则想列表中添加一个新项 var title=links[i].getAttributes("title"); if (!titles[title]) { var a = document.createElement('a'); a.appendChild(document.createTextNode(title)); a.setAttribute('href'.'#'); a.setAttribute('title','Activate'+title); a.setAttribute('rel',title); ADS.addEvent(a,'click',function(){ //单击激活链接是激活锚的rel属性中的标题所表示的样式 setActiveStyleSheet(this.getAttribute('rel')); ADS.preventDefault(W3CEvent); }); var li = document.createElement('Li'); li.appendChild(a); list.appendChild(li); //将title数组中的这个标题项设置为true。一边在多样式使用相同的标题跳过 title[title]=true; } } }});
- 切换body元素的className
这种方法的知道思想和上面类似,只不过是body标签的className
/*公共样式*/body{}#container{}/*AdvancED DOM Scripting 样式*/body.ads{}body.ads h1{}body.ads h2{}/*friends of ED 样式*/body.foed{}body.foed h1{}body.foed h2{}/*其他样式*//*Apress样式*/body.apress{}body.apress h1{}body.apress h2{}
然后用本章前面的ADS库,你可以动态的勤换body标签的类名,而CSS规则会在相应的修改页面表现:
ADS.addEvent('ads-anchor','click',function(){ ADS.addClassName(document.body,'asd');});ADS.addEvent('foed-anchor','click',function(){ ADS.addClassName(document.body,'foed');});ADS.addEvent('apress-anchor','click',function(){ ADS.addClassName(document.body,'apress');});
- 动态载入和移除样式
相当直观,使用这种技术索要做的就是通过document.createElement()及适当的属性<link>
/*添加新样式表*/function addStyleSheet(url,media){ media=media||'screen'; var link=document.creatElement('LINK'); link.settAttribute('rel','stylesheet'); link.settAttribute('tyle','text/css'); link.settAttribute('href','url'); link.settAttribute('media','media'); document.getElementsByTagName('head')[0].appendChild(link);}window['ADS']['addStyleSheet']=addStyleSheet/*移除样式表*/function removeStyleSheet(url,media){ var styles=getStyleSheets(url,media); for (var i = 0;i
- 修改CSS规则
在ADS库中添加方法,他能帮助你从document.styleSheets列表中查找带有适当的href和media属性的样式表:
/*通过URL取得包含所有样式表的数组*/function getStyleSheets(url,media) { var sheets = []; for(var i = 0 ; i < document.styleSheets.length ; i++) { if (url && document.styleSheets[i].href.indexOf(url) == -1) { continue; } if(media) { //规范化media字符串 media = media.replace(/,\s*/,','); var sheetMedia; if(document.styleSheets[i].media.mediaText) { //DOM方法 sheetMedia = document.styleSheets[i].media.mediaText.replace(/,\s*/,','); //Safari会添加额外的都和和空格 sheetMedia = sheetMedia.replace(/,\s*$/,''); } else { // MSIE sheetMedia = document.styleSheets[i].media.replace(/,\s*/,','); } // 如果media不匹配则跳过 if (media != sheetMedia) { continue; } } sheets.push(document.styleSheets[i]); } return sheets;}window['ADS']['getStyleSheets'] = getStyleSheets;
现在找到目标样式表了,但是还需要想库中添加ADS.editCSSRule()和ADS.addCSSRule()方法才能修改其中的样式规则:
/** * 编辑一条样式表规则 */function editCSSRule(selector,styles,url,media) { var styleSheets = (typeof url == 'array' ? url : getStyleSheets(url,media)); for ( i = 0; i < styleSheets.length; i++ ) { //取得规则表 // DOM2样式规范方法是 styleSheets[i].cssRules // MSIE规范方法是styleSheets[i].rules var rules = styleSheets[i].cssRules || styleSheets[i].rules; if (!rules) { continue; } // 由于MSIE默认使用大小写故转换为大写形式 // 如果你使用的是区分大小写的id,则可能导致冲突 selector = selector.toUpperCase(); for(var j = 0; j < rules.length; j++) { // 检查是否匹配 if(rules[j].selectorText.toUpperCase() == selector) { for (property in styles) { if(!styles.hasOwnProperty(property)) { continue; } // 设置新的样式属性 rules[j].style[camelize(property)] = styles[property]; } } } }}window['ADS']['editCSSRule'] = editCSSRule;/*ADS.editCSSRule('a',{'background-color':'yellow'});*//** * 增加一条CSS样式 */function addCSSRule(selector, styles, index, url, media) { var declaration = ''; // 根据style参数构建声明字符串 for (property in styles) { if(!styles.hasOwnProperty(property)) { continue; } declaration += property + ':' + styles[property] + '; '; } var styleSheets = (typeof url == 'array' ? url : getStyleSheets(url,media)); var newIndex; for(var i = 0 ; i < styleSheets.length ; i++) { // 添加规则 if(styleSheets[i].insertRule) { // DOM2样式规范的方法 // index = length 是列表的结尾 newIndex = (index >= 0 ? index : styleSheets[i].cssRules.length); styleSheets[i].insertRule(selector + ' { ' + declaration + ' } ', newIndex); } else if(styleSheets[i].addRule) { // MS的方法 // index = -1 是列表的结尾 newIndex = (index >= 0 ? index : -1); styleSheets[i].addRule(selector, declaration, newIndex); } }}window['ADS']['addCSSRule'] = addCSSRule;/**ADS.addCSSRule('a[href]:after',{ 'content':'"("attr(href)")"'; 'font-size':'40%', 'color':'#16009b'});*/
- 访问计算样式
DOM2样式规范在document.defaultView中包含了一个名叫getComputedStyle()的方法,就是为了访问计算样式而设计的。该方法返回一个制度的CSSStyleDeclaration对象。
在取得给定元素的计算样式之后,可以通过与操作元素的style属性一样的方式来取得信息
var element=ADS.$('example');var styles=document.defaultView.getComputedStyle(element);
取得background-color值需要下面这样简单:
var color=styles.getProperty('background-color');
我们在库中添加如下代码:
/*取得一个元素的计算样式*/function getStyle(element,property){ if (!element=$(element)||!property) return false; //检测元素style属性的的值 var value=element.style[camelize(property)]; if(!value) { //计算取得样式的值 if (document.defaultView&&document.defaultView.getComputedStyle) { //DOM var css=document.defaultView.getComputedStyle(element,null); value=css?css.getPropertyValue(property):null; } else if (element.currentStyle) { MSIE的方法 value=element.currentStyle[camelize(property)]; } } //返回空字符串而不是auto这样就不必检查auto值了 return value=='auto'?'':value;}window['ADS']['getStyle']=getStyle;window['ADS']['getStyleById']=getStyle;