文章插圖

文章插圖
本內容是《Web前端開發之Javascript視頻》的課件,請配合大師哥《Javascript》視頻課程學習 。
JavaScript也可以針對CSS進行編程,也就是所謂的腳本化CSS;通過腳本化CSS,同樣可以達到一系列的視覺效果;
在HTML中定義樣式的方式有3種:通過<link>元素包含外部樣式表文件、使用<style>元素定義嵌入式樣式、以及使用style特性定義特定元素的內聯樣式;
DOM2級樣式模塊圍繞這3種應用樣式的機制提供了一套API,可以檢測瀏覽器支持DOM2級定義的CSS能力;
var supportsDOM2CSS = document.implementation.hasFeature("CSS","2.0");var supportsDOM2CSS2 = document.implementation.hasFeature("CSS2","2.0");腳本化內聯樣式:腳本化CSS最簡單直接的方式就是更改文檔元素的style屬性;任何支持style特性的HTML元素在Javascript中都有一個對應的style屬性,這個style屬性比較特殊,它不是字符串,而是一個CSSStyleDeclaration對象,包含著通過HTML的style特性指定的所有樣式信息,但不包含從外部樣式表或嵌入樣式表經層疊而來的樣式;
var mydiv = document.getElementById("mydiv");console.log(mydiv.style);// CSSStyleDeclarationmydiv.style.fontSize = "24px";mydiv.style.color = "purple";style屬性作為CSSStyleDeclaration對象,其就代表了內聯樣式,其保存了所有的樣式屬性,但如果元素沒有設置style特性或沒有使用腳本設置該特性,style中的樣式屬性值均為空字符串;只要取得一個有效的DOM元素的引用,就可以隨時使用Javascript為其設置樣式;
var myDiv = document.getElementById("myDiv");myDiv.style.backgroundColor = "red";myDiv.style.width = "100px";myDiv.style.height = "200px";myDiv.style.border = "1px solid black";以這種方式改變樣式時,元素的外觀會自動被更新;通過style對象,同樣可以取得style特性中指定的樣式;
var mydiv = document.getElementById("mydiv");console.log(mydiv.style.backgroundColor);console.log(mydiv.style.width);console.log(mydiv.style.height);腳本化的CSS屬性的名稱和值:在style特性中指定的任何CSS屬性都將表現為這個style對象的相應屬性;對于使用短劃線的CSS屬性名,必須將其轉換成駝峰大小寫形式,才能通過js來訪問,如:
CSS屬性 JS屬性background-imagestyle.backgroundImagecolor style.colordisplay style.displayfont-family style.fontFamily
多數情況下,都可以通過簡單地轉換屬性名的格式來實現轉換,但是,當一個CSS屬性名在Javascript中如果是保留字或關鍵字時,在其前加”css”前綴,例如float屬性,由于float是JS中的保留字,因此不能被用作屬性名,其值應為cssFloat;低版本IE支持styleFloat;
mydiv.style.backgroundColor = "purple";mydiv.style.borderRightStyle = "solid";mydiv.style.borderRightColor = "green";mydiv.style.cssFloat = "left";mydiv.style.styleFloat = "left";通過CSSStyleDeclaration對象設置style屬性值時,值都應該是字符串,都應該放到引號內,并且不帶分號;在標準模式下,所有度量值都必須指定一個度量單位;在混合模式下,可以省略單位;
mydiv.style.width = 300;// 錯誤,但在混雜模式下默認為300pxmydiv.style.width = "300";// 錯誤,但在混雜模式下默認為300px通過計算得來的值,也要在最后加上單位;var x = 10, leftMargin=20, leftBorder=10;mydiv.style.left = (x + leftMargin + leftBorder) + "px";帶單位唯一不好的地方就是,如果要獲取這個值,參與其他的數學運算,因為其是字符串,所以不能直接使用,必須轉換為數值才能參與運算,例如使用parseInt()或parseFloat()等方法進行轉換;var rect = mydiv.getBoundingClientRect();console.log(rect);var borderWidth = parseFloat(mydiv.style.width);console.log(borderWidth);一些CSS屬性是復合屬性,比如:margin就是margin-top、margin-right、margin-bottom、margin-left的復合屬性;CSSStyleDeclaration對象也有與之對應的復合屬性;mydiv.style.margin = "20px 30px 40px 50px";mydiv.style.marginTop = "50px";mydiv.style.marginLeft = "50px";當設置復合屬性margin時,其會自動計算其所對應的相關聯的屬性;即然style是元素的特性,那么也可以通過setAttribute()、getAttribute()等方法來設置style特性;
mydiv.setAttribute("style","width: 300px; height:200px; background-color: purple;");console.log(mydiv.style);console.log(mydiv.getAttribute("style"));style對象的屬性和方法:style對象中還定義一些屬性和方法,這些屬性和方法在提供元素的style特性值的同時,也可以修改樣式;
cssText:能夠訪問到style特性中的CSS代碼;
length:應用給元素的CSS屬性的數量;
parentRule:表示CSS信息的CSSRule對象;
getPropertyCSSValue(propertyName):返回包含給定的屬性的值CSSValue對象;已廢棄;
getPropertyPriority(propertyName);如果給定的屬性使用了!important設置,則返回important;否則返回空字符串;
getPropertyValue(propertyName):返回給定的屬性的值;
item(index):返回給定位置的CSS屬性的名;
removeProperty(propertyName):從樣式中刪除給定的屬性;
setProperty(propertyName,value,priority):為給定的屬性設置為屬性值,并加上優先權標志(”important”或一個空字符串);
cssText屬性:返回瀏覽器對style特性中CSS代碼的內部表示,在寫入模式下,賦給cssText的值會重寫整個style特性的值;
mydiv.style.cssText = "width: 300px; height:200px; background-color: purple;";console.log(mydiv.style.cssText);console.log(mydiv.getAttribute("style"));設置cssText屬性的目的就是為元素快速應用多個CSS特性,可以一次性應用所有的變化;item()方法和length屬性:設計length屬性的目的,就是將其與item()方法配套使用,以便迭代元素中定義的CSS屬性名;在使用length和item()時,style對象實際上是一個集合,可以使用方括號來代替item()來取得給定位置的css屬性名;
console.log(mydiv.style.length);for(var i=0; i<mydiv.style.length; i++){// console.log(mydiv.style.item(i));console.log(mydiv.style[i]);}getPropertyValue(propertyName)方法:取得給定的屬性的值;console.log(mydiv.style.getPropertyValue("background-color"));for(var i=0; i<mydiv.style.length; i++){var prop = mydiv.style[i];// 取得屬性名var value = http://www.mnbkw.com/jxjc/190824/mydiv.style.getPropertyValue(prop);// 取得屬性值console.log(prop +":" + value);}getPropertyCSSValue(propertyName)方法:該方法會返回一個包含兩個屬性的CSSValue對象,這兩個屬性分別是:cssText和cssValueType,其中cssText屬性的值與getPropertyValue()方法返回的值相同,而cssValueType屬性則是一個數值常量,表示值的類型:0表示繼承的值,1表示基本的值,2表示值列表,3表示自定義的值;var value = http://www.mnbkw.com/jxjc/190824/mydiv.style.getPropertyCSSValue("background-color");console.log(value);console.log(value.cssText);console.log(value.cssValueType);這個方法已經被廢棄了,幾乎所有的瀏覽器都不支持;getPropertyPriority(propertyName);如果給定的屬性使用了!important設置,則返回important;否則返回空字符串;
console.log(mydiv.style.getPropertyPriority("background-color")); // importantsetProperty(propertyName,value,priority):為給定的屬性設置為屬性值,并加上優先權標志,priority 為可選(”important”或一個空字符串);mydiv.style.setProperty("background-color","purple","important");removeProperty(propertyName)方法:可以從元素的樣式中移除某個CSS屬性,移除一個屬性,意味著該屬性將應用默認的樣式(從其他樣式表經層疊而來);mydiv.style.removeProperty("background-color");parentRule:只讀,表示CSS信息的CSSRule對象;var rule = mydiv.style.parentRule;console.log(rule);// null計算的樣式:雖然style對象能夠提供style特性所有樣式信息,但它不包含那些從其他樣式表層疊而來并影響到當前元素的實際樣式信息;所以,需要使用計算樣式;
計算樣式是一組屬性值,它由瀏覽器通過把內聯樣式結合所有鏈接樣式表中所有可應用的樣式規則后導出(計算)得到的,也就是一組在呈現元素時實際使用的屬性;
getComputedStyle()方法:
該方法是window對象的方法,可以通過window.getComputedStyle(),或者document.defaultView.getComputedStyle()方法調用,而document.defaultView的返回值就是window;
該方法接受兩個參數:要取得計算樣式的元素和一個偽元素字符串(如::after);如果不需要偽元素,第二個參數可以為null或一個空字符串;該方法返回一個CSSStyleDeclaration對象,與style屬性的類型相同,區別在于它是只讀的,其中包含當前元素的所有計算的樣式;
<style>#mydiv{background-color: purple; width: 100px; height: 100px;}</style><div id="mydiv" style="background: pink; border: 1px solid black;">mydiv</div><script>var mydiv = document.getElementById("mydiv");var computedStyle = document.defaultView.getComputedStyle(mydiv,null);console.log(computedStyle);console.log(computedStyle.backgroundColor);console.log(computedStyle.width);console.log(computedStyle.height);console.log(computedStyle.border);</script>注:以上border屬性可能不會返回實際的border規則(如IE和Firefox返回空字符串),原因是不同瀏覽中解釋復合屬性的方式不同,因為設置這種屬性實際上會涉及很多其他屬性,例如:border,實際上調協了四個邊的邊框寬度、顏色等,因此border不會返回,但computedStyle.borderleftWidth會返回值;console.log(computedStyle.borderLeftWidth);console.log(computedStyle.borderLeftColor);另外,不同瀏覽器表示值的方式可能會有所區別;計算后的樣式也包含屬于瀏覽器內部樣式表的樣式信息,因此任何具有默認值的CSS屬性都會表現在計算后的樣式中;如visibility屬性都有一個默認值,有些瀏覽器設置為visible,而有些設置為inherit;
計算樣式的CSSStyleDeclaration對象和表示內聯樣式的對象之間有一些重要的區別:
計算樣式的屬性是只讀的;
計算樣式的值是絕對值,類似百分比和點之類的相對的單位將全部轉換為絕對值;所有指定尺寸,例如外邊距大小和字體大小等屬性都有一個以像素為度量單位的值;相關顏色的屬性將以”rgb(#,#,#)”或”rgba(#,#,#,#)”的格式返回;
不計算復合屬性,它們只基于最基礎的屬性,例如,不要查詢margin屬性,應該使用marginLeft或marginTop等;
計算樣式的cssText屬性未定義(也就是該屬性返回空字符串);
計算樣式和內聯樣式可以同時使用;
// 用指定的因子縮放元素e的文本尺寸function scale(e, factor){// 用計算樣式查詢當前文本的尺寸var size = parseInt(window.getComputedStyle(e,"").fontSize);// 用內聯樣式來放大尺寸e.style.fontSize = factor * size + "px";}// 用指定的因子修改元素的背景顏色// factors > 1 顏色變淺,factors < 1顏色變暗function scaleColor(e, factor){var color = window.getComputedStyle(e,"").backgroundColor;var components = color.match(/[\d\.]+/g); // 解析r、g、b分量for(var i=0; i<3; i++){// 循環r,g,bvar x = Number(components[i]) * factor;// 縮放每個值x = Math.round(Math.min(Math.max(x, 0), 255)); // 設置邊界并取整components[i] = String(x);}if(components.length == 3)// rgb()顏色e.style.backgroundColor = "rgb(" + components.join() + ")";else// rgba()顏色e.style.backgroundColor = "rgba(" + components.join() + ")";}var mydiv = document.getElementById("mydiv");scale(mydiv, 1.5);scaleColor(mydiv, .5);低版本的IE不支持getComputedStyle()方法,但它有一種類似的概念;在IE中,具有style屬性的元素還有一個currentStyle屬性,該屬性是CSSStyleDeclaration的實例,包含當前元素全部計算后的樣式,但只有IE支持;var computedStyle = mydiv.currentStyle;console.log(computedStyle.backgroundColor);console.log(computedStyle.width);console.log(computedStyle.height);console.log(computedStyle.borderLeftWidth);兼容函數:function getStyle(obj, attr){if(window.getComputedStyle)return getComputedStyle(obj, null)[attr];elsereturn obj.currentStyle[attr];}var mydiv = document.getElementById("mydiv");var backgroundColor = getStyle(mydiv, "background-color");console.log(backgroundColor);// rgb(245, 222, 179)// 或者function getCss(obj, css){return (document.defaultView.getComputedStyle ?document.defaultView.getComputedStyle(obj,null) :obj.currentStyle)[css];}var borderTopWidth = getCss(mydiv, "border-top-width");console.log(borderTopWidth); // 1px封裝一下函數,用來獲取CSS屬性值,如:function getComputedStyles(elem,prop) {var cs = window.getComputedStyle(elem,null);if (prop) {console.log(prop+" : "+cs.getPropertyValue(prop));return;}var len = cs.length;for (var i=0;i<len;i++) {var style = cs[i];console.log(style+" : "+cs.getPropertyValue(style));}}getComputedStyles(mydiv);// 查詢所有getComputedStyles(mydiv,"background-color");// 只查詢一個屬性與偽元素一起使用:getComputedStyle可以從偽元素中提取樣式信息(例如:::after, ::before, ::marker, ::line-marker);<style>#mydiv::after{content: "大師哥王唯";}</style><div id="mydiv"></div><script>var mydiv = document.getElementById("mydiv");var computedStyle = document.defaultView.getComputedStyle(mydiv,":after");console.log(computedStyle.content);<script>使用計算樣式是可以獲取元素的幾何尺寸和位置的,但是其獲得的結果并不一定是我們所期望的,此時可以使用getBoundingClientRect(),其返回的值是與呈現的效果是一致的;console.log(computedStyle.left);// autoconsole.log(computedStyle.top);// autoconsole.log(computedStyle.width);// 300px// left:8 top:8 width:302,包括了bordervar rect = mydiv.getBoundingClientRect();console.log(rect);腳本化CSS類:也可以腳本化元素的class屬性,改變元素的class就改變了應用于元素的一組樣式表選擇器,它能在同一時刻改變多個CSS屬性;
className屬性:
與元素的class特性對應,即為元素指定的CSS類;由于class是ECMAScript保留字,所以在Javascript中使用className;
在操作類名時,需要通過className屬性添加、刪除和替換類名;
var mydiv = document.getElementById("mydiv");mydiv.className = "container"; // 設置mydiv.className = ""; // 刪除mydiv.className = "other"; // 替換// 或if(mydiv.className == ""){mydiv.className = "container";}元素可以設置多個CSS類,其className中保存的是擁有多個類名的字符串,因此即使只修改字符串一部分,都會覆蓋之前的值,所以每次都必須設置整個字符串的值;var mydiv = document.getElementById("mydiv");console.log(mydiv.className);// db user disablemydiv.className = "container";console.log(mydiv.className); // container如果要從class中只刪除一個類名,需要把多個類名拆開,刪除不想要的那個,然后再把其他類名拼成一個新字符串,如:// 如,刪除user類// 首先,取得類名字符串并拆分成數組var mydiv = document.getElementById("mydiv");var classNames = mydiv.className.split(/\s+/);// 找到要刪的類名var pos = -1, i, len;for(i=0, len = classNames.length; i<len; i++){if(classNames[i] == "user"){pos = i;break;}}// 刪除類名classNames.splice(i,1);// 把剩下的類名拼成字符串并重新設置mydiv.className = classNames.join(" ");如果要添加類名,是可以直接通過拼接字符串完成,但在拼接之前,必須要通過檢測確定不會多次添加相同的類名;Element.classList屬性:
HTML5新增了一種操作類名的方式,可以讓操作更簡單也更安全,即classList屬性,其是一個DOMTokenList對象,其是只讀的類數組對象,與其他DOM集合類似,它也有一個表示自己包含多少個元素的length屬性,而要取得每個元素可以使用item()方法,也可以使用方括號語法,此外,這個新類型還定義如下的方法:
add(value):將給定的字符串值添加到列表中,如果值存在,就不添加;contains(value):表示列表中是否存在給定的值,如果存在返回true,否則,返回false;remove(value):從列表中刪除給定的字符串;toggle(value):如果列表中已經存在給定的值,刪除它,否則,添加它;
console.log(mydiv.classList);// DOMTokenListmydiv.classList.add("container");mydiv.classList.remove("container");使用classList,可以確保其他類名不受此次修改的影響,可以極大地減少類似的基本操作的復雜性;mydiv.classList.toggle("user");// 切換user類// 確定元素中是否包含既定的類名if(mydiv.classList.contains("bd") && !mydiv.classList.contains("disabled")){// To Do }// 迭代類名for(var i=0,len=mydiv.classList.length; i<len; i++){// To Doconsole.log(mydiv.classList[i]);}有了classList屬性,除非需要全部刪除所有類名,或者完全重寫元素的class屬性,否則也就用不到className了;需要確定的一點,classList這個DOMTokenList對象,它是實時的,如果className屬性改變了,它也會及時更新,同樣的,classList改變了,className屬性也會及時更新;
IE9以下的瀏覽器不支持classList屬性,可以自定義一個CSSClassList類,模擬DOMTokenList對象的方法;
function classList(e){// 以下兩行先注釋,否則后面的toArray默認調用的是DOMTokenList對象的的toArray,而它并不存在// 或者擴展內置的DOMTokenList的toArray// if(e.classList) return e.classList;// 如果e.classList存在,則返回它// else return new CSSClassList(e);// 否則,說偽造一個return new CSSClassList(e);}// CSSClassList是一個模擬DOMTokenList的對象function CSSClassList(e) { this.e = e;}// 如果e.className包含類名c則返回true,否則返回falseCSSClassList.prototype.contains = function(c){// 檢查c是否是合法的類名if(c.length === 0 || c.indexOf(" ") != -1)throw new Error("Invalid class name: '" + c + "'");// 首先是常規檢查var classes = this.e.className;if(!classes) return false;// e不含類名if(classes === c) return true; // e有一個完全匹配的類名// 否則,把c自身看做一個單詞,利用正則表達式搜索creturn classes.search("\\b" + c + "\\b") != -1;};// 如果c不存在,將c添加到e.className中CSSClassList.prototype.add = function(c){if(this.contains(c)) return;// 如果存在,什么也不做var classes = this.e.className;if(classes && classes[classes.length - 1] != " ")c = " " + c;// 如果需要加一個空格this.e.className += c; // 將c添加到className中};// 將在e.className中出現的所有c都刪除CSSClassList.prototype.remove = function(c){if(c.length === 0 || c.indexOf(" ") != -1)throw new Error("Invalid class name: '" + c + "'");// 將所有作為單詞的c和多余的尾隨空格全部刪除var pattern = new RegExp("\\b" + c + "\\b\\s*", "g");this.e.className = this.e.className.replace(pattern, "");};// 如果c不存在,將c添加到e.className中,并返回true// 否則,將e.className中出現的所有c都刪除,并返回falseCSSClassList.prototype.toggle = function(c){if(this.contains(c)){ // 如果e.className包含類名cthsi.remove();// 刪除它return false;}else{this.add(c); // 添加return true;}};// 返回e.className本身CSSClassList.prototype.toString = function(){return this.e.className;};// 返回在e.className中的類名CSSClassList.prototype.toArray = function(){return this.e.className.match(/\b\w+\b/g) || [];};// 應用var mydiv = document.getElementById("mydiv");var ccl = classList(mydiv);console.log(ccl);console.log(ccl.contains("newsdiv"));// trueccl.add("topDiv");ccl.remove("newsdiv");ccl.toggle("newsdiv");console.log(ccl.toString());console.log(ccl.toArray());腳本化樣式表:在腳本化樣式表時,會使用到兩種類型的對象:
第一類是元素對象,包括通過<link>元素包含的樣式表和在<style>元素中定義的樣式表,這兩個元素本身是常規的文檔元素,分別是由HTMLLinkElement和HTMLStyleElement類型表示,它們都可以修改元素的特性,如果它們有id,可以通過getEleementById()來獲取它們;
// var mylink = document.getElementById("mylink");var mylink = document.getElementsByTagName("link")[0];console.log(mylink);var mystyle = document.getElementsByTagName("style")[0];console.log(mystyle);所有瀏覽器都會包含<style>元素和rel特性被設置為stylesheet的<link>元素引入的樣式表;第二類是CSSStyleSheet類型,表示樣式表本身;通過document.styleSheets屬性會返回一個只讀的類數組StyleSheetList對象集合,該集合具有length屬性和item()方法,集合內保存著CSSStyleSheet對象,表示與文檔關聯在一起的樣式表;
var styleList = document.styleSheets;console.log(styleList);// StyleSheetListconsole.log(styleList.length);// 3console.log(styleList[0]);// CSSStyleSheet// 遍歷var sheet = null;for(var i=0, len=document.styleSheets.length; i<len; i++){sheet = document.styleSheets[i];console.log(sheet.href);}可以直接通過HTMLLinkElement(<link>)或HTMLStyleElement(<style>)元素的sheet屬性獲取CSSStyleSheet對象;低版本的IE不支持sheet,但提供了一個同樣作用的styleSheet屬性;var mylink = document.getElementById("mylink");var mylink = document.getElementsByTagName("link")[0];console.log(mylink.sheet);// CSSStyleSheetconsole.log(mylink.styleSheet); // 在低版本的IE中返回CSSStyleSheetvar mystyle = document.getElementsByTagName("style")[0];console.log(mystyle.sheet);// CSSStyleSheetconsole.log(mystyle.styleSheet);// 在低版本的IE中返回CSSStyleSheet兼容處理:function getStyleSheet(element){return element.sheet || element.styleSheet;}var link = document.getElementsByTagName("link")[0];var sheet = getStyleSheet(link);console.log(sheet.href);在使用之前,檢測瀏覽器是否支持DOM2級樣式表;var supportsDOM2StyleSheet = document.implementation.hasFeature("StyleSheets","2.0");CSSStyleSheet對象:接口代表一個 CSS 樣式表,并允許檢查和編輯樣式表中的規則列表;其繼承自StyleSheet接口,后者可以作為一個基礎接口來定義非CSS樣式表;從接口繼承的屬性如下:
disabled:表示樣式表是否被禁用的布爾值,R/W,將這個值設置為true可以禁用樣式表;
var styleList = document.styleSheets;var ss = styleList[2];console.log(ss.disabled);ss.disabled = true;// 元素的樣式失效// 封裝一個小函數,用來開啟或關閉樣式表// 如果傳遞一個數字,將其當做document.styleSheets對象中一個索引// 如果傳遞一個字符串,將其當作CSS選擇器并傳遞給document.querySelectorAll()function disableStyleSheet(ss){if(typeof ss === "number")document.styleSheets[ss].disabled = true;else{var sheets = document.querySelectorAll(ss);for(var i=0; i<sheets.length; i++)sheets[i].disabled = true;}}disableStyleSheet(0);disableStyleSheet("style");disableStyleSheet("link");href:如果樣式表是通過<link>包含的,則是樣式表的URL,否則null;media:當前樣式表支持的所有媒體類型的MediaList類數組集合;與所有DOM集合一樣,這個集合也有一個length屬性和一個item()方法;如果集合為空,表示樣式表適用于所有媒體;
<style media="screen and (min-width: 500px),tv and (max-width: 1000px)">.container{width:300px;height:200px;background-color: salmon;}</style><script>var styleList = document.styleSheets;var ss = styleList[2];console.log(ss.media);// MediaListconsole.log(ss.media.length); // 2console.log(ss.media[0]);// screen and (min-width:500px)console.log(ss.media.item(1)); // tv and (max-width:1000px)MediaList對象還擁有mediaText屬性,返回元素media特性的值;console.log(ss.media.mediaText);MediaList對象擁有appendMedium(medium)和deleteMedium()方法,分別用作添加和刪除媒介;ss.media.appendMedium("print");ss.media.deleteMedium("tv and (max-width:1000px)");一般來說,很少去操作media屬性;ownerNode:指向擁有當前樣式表的節點的指針,樣式表可能是在HTML中通過<link>或<style>引入的,[email protected],該屬性值為null,低版本IE不支持該屬性;
console.log(styleList[0].ownerNode); // linkconsole.log(styleList[1].ownerNode); // styleparentStyleSheet:[email protected],該屬性是一個指向導入它的樣式表的指針;// styleList[1]獲取的是一個<style>[email protected](styleList[1].cssRules[0]); console.log(styleList[1].cssRules[0].parentStyleSheet);// CSSStyleSheettitle:ownerNode中title屬性的值;type:表示樣式表類型的字符串,對CSS樣式表而言,是”text/css”;
注:除了disabled屬性之外,其他屬性都是只讀的;
操作樣式表規則:
除了以上所有這些屬性,CSSStyleSheet類型還定義了用來查詢、插入和刪除樣式表規則的API;
cssRules:返回樣式表中包含的所有樣式規則的CSSRuleList類型的實時集合,該集合中的元素為CSSStyleRule對象;低版本的IE不支持,但有個類似的rules屬性;
var ss = styleList[1];console.log(ss);console.log(ss.cssRules);console.log(ss.rules);// 是IE專用console.log(ss.cssRules[0]);// CSSStyleRuleownerRule:[email protected],該屬性就是一個指針,返回表示導入的規則的CSSImportRule對象,否則為null,低版本的IE不支持;insertRule(rule, index):創建(插入)規則,向CSSRules集合中指定的位置插入rule字符串,該方法接受兩個參數:規則文本和表示在哪里插入規則的索引;
var sheet = document.styleSheets[1];sheet.insertRule("body{background-color:silver}",0);console.log(sheet.cssRules);低版本的IE支持一個類似的addRule(selector, style, index)方法,接受兩個必選和一個可選參數:選擇器和CSS樣式信息,一個可選參數:插入規則的位置;document.styleSheets[1].addRule("h1","font-size:3em;color:red;",2);console.log(document.styleSheets[1].cssRules);這個方法所有瀏覽器也都支持;跨瀏覽器方式:
var sheet = document.styleSheets[0];function insertRule(sheet, selectorText, cssText, position){if(sheet.insertRule){sheet.insertRule(selectorText + "{" + cssText + "}", position);}else{sheet.addRule(selectorText, cssText, position);}}insertRule(sheet, "body", "background-color:silver", 0);deleteRule(index):刪除cssRules集合(樣式表)中指定位置的規則;低版本的IE不支持,但支持一個類似的removeRule()方法,這個方法所有瀏覽器也都支持;document.styleSheets[1].deleteRule(0);document.styleSheets[1].removeRule(0);console.log(document.styleSheets[1].cssRules);跨瀏覽器方式:var sheet = document.styleSheets[0];function deleteRule(sheet, index){if(sheet.deleteRule){sheet.deleteRule(index);}else{sheet.removeRule(index);}}deleteRule(sheet,0);CSSStyleRule規則對象:CSSStyleRule對象表示樣式表中的每一條規則;繼承自CSSRule接口,實際上CSSRule是專供其他類型繼承的基類,其中最常見的是CSSStyleRule類型,表示樣式信息;
var sheet = document.styleSheets[2];var rules = sheet.cssRules || sheet.rules;var rule = rules[0];console.log(rule); // CSSStyleRuleCSSRule接口屬性:cssText:返回整條規則對應的文本;低版本的IE不支持parentRule:只讀,如果當前規則是導入的規則,這個屬性引用的就是導入規則,否則為null;或此規則是 @media 塊中的樣式規則, 則其父規則將是該 CSSMediaRule;IE不支持parentStyleSheet:當前規則所屬的樣式表,低版本的IE不支持;type:表示規則類型的常量值,對于樣式規則,值為1;IE不支持;
這些常量被定義在CSSRule接口中,值為:
常量值接口
CSSRule.STYLE_RULE1CSSStyleRuleCSSRule.IMPORT_RULE3CSSImportRuleCSSRule.MEDIA_RULE4CSSMediaRuleCSSRule.FONT_FACE_RULE5CSSFontFaceRuleCSSRule.PAGE_RULE6CSSPageRuleCSSRule.KEYFRAMES_RULE7CSSKeyframesRuleCSSRule.KEYFRAME_RULE8CSSKeyframeRule9 保留供將來使用CSSRule.NAMESPACE_RULE10CSSNamespaceRuleCSSRule.COUNTER_STYLE_RULE11CSSCounterStyleRuleCSSRule.SUPPORTS_RULE12CSSSupportsRuleCSSRule.DOCUMENT_RULE13CSSDocumentRuleCSSRule.FONT_FEATURE_VALUES_RULE14CSSRule.VIEWPORT_RULE15CSSViewportRuleCSSRule.REGION_STYLE_RULE16CSSRegionStyleRuleCSSRule.UNKNOWN_RULE0CSSUnknownRuleCSSRule.CHARSET_RULE2CSSCharsetRule
CSSStyleRule對象屬性:
selectorText:只讀,返回當前規則的選擇器;style:只讀,返回一個CSSStyleDeclaration對象,可以通過它設置和取得規則中特定的樣式值;styleMap:一個StylePropertyMap對象;
console.log(rule.cssText);// 定義規則的字符串console.log(rule.parentRule);console.log(rule.parentStyleSheet); // CSSStyleSheetconsole.log(rule.selectorText);// 選擇器console.log(rule.style);// CSSStyleDeclarationconsole.log(rule.styleMap);// StylePropertyMapconsole.log(rule.type);// 1最常用的是cssText、selectorText和style這三個屬性;cssText屬性與style.cssText屬性類似,但并不相同,前者包含選擇器和圍繞樣式信息的花括號,后者只包含樣式信息;cssText是只讀的,style.cssText是可寫的;console.log(rule.cssText);// .container{color:white}console.log(rule.style.cssText); // color:whiterule.style.cssText = "background-color:purple";console.log(rule.cssText);// .container{background-color:purple;}console.log(rule.style.cssText); // background-color:purplerule.style.cssText += "color:white;";大多數情況下,僅使用style屬性就可以滿足所有操作樣式規則的需求了;這個對象就像每個元素上的style屬性一樣,可以通過它讀取和修改規則中的樣式信息;console.log(rule.style.width);console.log(rule.style.height);rule.style.backgroundColor = "lightgray";console.log(rule.style.cssText);CSSStyleRule對象的style屬性,使用方式和內聯style對象的使用方式是一致的,但要注意,一個是規則對象的style屬性對象,一個是內聯style對象;// 遍歷樣式表的規則var ss = document.styleSheets[0];// 第一個樣式表var rules = ss.cssRules ? ss.cssRules : ss.rules;// 樣式表規則for(var i=0; i<rules.length; i++){var rule = rules[i];if(!rule.selectorText) continue;// [email protected]var selector = rule.selectorText;// 選擇器var ruleText = rule.style.cssText; // 文本形式的樣式// 如果規則應用在h1元素上,也將其應用到h2元素上// 注意,僅當選擇器在字面上為h1時這才起作用if(selector == "h1"){if(ss.insertRule)ss.insertRule("h2 {" + ruleText + "}", rules.length);else if(ss.addRule)ss.addRule("h2", ruleText, rules.length);}// 如果規則設置了text-decoration屬性,則將其刪除if(rule.style.textDecoration){if(ss.deleteRule)ss.deleteRule(i);else if(ss.removeRule)ss.removeRule(i);i--; // 調整循環索引,因為以上的規則i+1現在即為規則i}}創建新樣式表:可以創建一個新樣式表并將其添加到文檔中;使用DOM技術,創建一個<style>元素,并將其插入到文檔的頭部,然后再用其innerHTML屬性來設置樣式表內容;在低版本的IE中,CSSStyleSheet對象通過非標準方法document.createStyleSheet()來創建,其樣式文本用cssText屬性值為指定;
// 創建一個新樣式表// 對文檔添加一個樣式表,用指定的樣式填充它// style參數可能是字符串或對象,如果它是字符串,就把它作為樣式表的文本// 如果它是對象,將每個定義樣式規則的每個屬性添加到樣式表中// 屬性名即為選擇器,其值即為對應的樣式function addStyles(styles){var styleElt, styleeSheet;// 先創建一個新樣式表if(document.createStyleSheet)// 如果是IEstyleSheet = document.createStyleSheet();else{var head = document.getElementsByTagName("head")[0];styleElt = document.createElement("style"); // 新的<style>元素head.appendChild(styleElt);// 這個新樣式表應該是最后一個styleSheet = document.styleSheets[document.styleSheets.length - 1];}// 向其中插入樣式if(typeof styles === "string"){if(styleElt)styleElt.innerHTML = styles;elsestyleSheet.cssText = styles;// IE}else{// 參數是規則對象var i = 0;for(selector in styles){if(styleSheet.insertRule){var rule = selector + "{" + styles[selector] + "}";styleSheet.insertRule(rule, i++);}else{styleSheet.addRule(selector, styles[selector], i++);}}}}// 應用var styles = "h2 {font-size: 2em; color: red;}";addStyles(styles);var rule = document.styleSheets[1].cssRules[0];addStyles(rule);CSS動畫:腳本化CSS的最常見的用途之一就是產生視覺動畫效果;其原理是使用setTimeout()或setInterval()重復調用函數來修改元素的內聯樣式,以達到產生視覺差的動畫效果;【js獲取方法名 js通過類名獲取子元素】
// 將e轉化為相對定位的元素,使之左右震動// 第一個參數可以是元素對象也可以是元素的id// 第二個參數是回調函數,將以e為參數,將在動畫結束時調用// 第三個參數指定e震動的距離,默認是5px// 第四個參數指定震動多久,默認是500msfunction shake(e, oncomplete, distance, time){if(typeof e === "string") e = document.getElementById(e);if(!time) time = 500;if(!distance) distance = 5;var originalStyle = e.style.cssText;// 保存e的原始stylee.style.position = "relative";// 使e相對定位var start = (new Date()).getTime();// 動畫的開始時間animate();// 開始動畫// 函數檢檢查消耗的時間,并更新e的位置// 如果動畫完成,它將e還原為原始狀態// 否則,它更新e的位置,安排它自身重新運行function animate(){var now = (new Date()).getTime();// 得到當前時間var elapsed = now - start;// 從開始以來消耗了多長時間var fraction = elapsed / time; // 是總時間的幾分之幾if(fraction < 1){// 如果動畫未完成// 作為動畫完成比例的函數,計算e的位置// 使用正弦函數將完成比例乘以4pi,所以它來回往復兩次var x = distance * Math.sin(fraction * 4 * Math.PI);e.style.left = x + "px";// 在25ms后或在總時間的最后嘗試再次運行函數// 目的是為了產生每秒40幀的動畫setTimeout(animate, Math.min(25, time - elapsed));}else{e.style.cssText = originalStyle;// 恢復原始樣式if(oncomplete)// 調用回調函數oncomplete(e);}}}// 應用var mydiv = document.getElementById("mydiv");shake(mydiv,function(e){console.log(e.style)},5,500);// 以毫秒級的時間將e從完全不透明談出到完全透明// 在調用函數時假設e是完全不透明// oncomplete是一個可選的函數,以e為參數,它將在動畫結束時調用// 如果不指定time,默認為500msfunction fadeOut(e, oncomplete, time){if(typeof e === "string") e = document.getElementById(e);if(!time) time = 500;// 使用Math.sqrt作為一個簡單的緩動函數來創建動畫// 非線性,由快到慢var ease = Math.sqrt;var start = (new Date()).getTime();// 動畫的開始時間animate();// 開始動畫function animate(){var elapsed = (new Date()).getTime() - start; // 消耗時間var fraction = elapsed / time;// 總時間的幾分之幾if(fraction < 1){// 如果動畫未完成var opacity = 1 - ease(fraction); // 計算元素的不透明度e.style.opacity = String(opacity);// 設計不透明度setTimeout(animate, Math.min(25, time - elapsed));}else{e.style.opacity = "0";// 完全透明if(oncomplete)oncomplete(e);}}}fadeOut(mydiv,null,500);
- 讓男人對你動真心的有效方法 讓男人心動的方法
- word目錄的制作方法 word2010制作目錄的詳細步驟
- mac恢復出廠設置方法 mac系統恢復出廠設置教程
- 如何長壽 中醫世家的長壽秘方一般人不知
- matlab快捷鍵大全 matlab怎么設置快捷方式
- js函數定義的三種方式區別 js函數怎么定義
- 項鏈生銹用什么方法洗亮
- 蘋果手機黑屏怎么解決方法 蘋果手機突然黑屏了怎么辦
- js數組的遍歷可以用哪幾種方法? js遍歷數組
- ip電話交換機配置 交換機ip設置方法
