摘要:而現代瀏覽器會直接返回它的值,我們的目標就是在下也返回值。通過可以對元素的樣式進行讀寫,實際上操作的是標簽上的屬性的值。因此不能直接對其賦值,不然就把整個屬性的值給覆蓋掉了。我們采用累加的方式來修改屬性。
上一篇博文介紹了getComputedStyle方法,接下來,我們就來實現一個簡易版的小插件,能夠在不借助jQuery的情況下實現css屬性的獲取和設置。
作者:Icarus
原文鏈接:手把手帶你用原生js實現css屬性的set和get
首先創建一個 css-tool.js 文件,一開始他是這個樣子的:
;(function (window,undefined) { "use strict"; var cssTool = function () { return new cssTool.prototype.init(); } cssTool.prototype = { init: function() { console.log("init success"); return this; }, } cssTool.prototype.init.prototype = cssTool.prototype; // 暴露接口 window.cssTool = cssTool; })(window);
全局作用域可以看作是一棟公寓樓,我們創建一個立即執行的匿名函數,相當于是公寓樓中的一間公寓,我們在屋子里做的事情就都是隱秘的,也就是起到隔離作用域的作用,避免和外部變量產生沖突。把 window 作為參數拿到屋子里來,以后就不用再重復去外面找 window 來用。最前面的分號是為了保證在文件合并壓縮后產生語法錯誤。 undefined 在老版本瀏覽器中不被支持,因此考慮到兼容性添加一個形參。
我們創建了一個叫 cssTool 的私有方法,相當于我們在屋子里找了一個小房間來放 get 和 set 等方法。接下來我們在原型上新增一個 init 方法,用于初始化。之后我們仿照 jQuery 的方式,將init的 prototype 指向 cssTool 的 prototype ,這樣我們在用init作為構造函數創造實例時,可以使插件擁有兩種調用方式:
var ct = new cssTool()構建 cssTool 實例
直接調用cssTool(),一樣返回 cssTool 實例
get方法 通用方式 現代瀏覽器和IE9+window.getComputedStyle(elem,null).getPropertyValue(attr)IE678
elem.currentStyle.getAttribute(camelCase(attr))兼容處理 駝峰命名法轉換-camelCase
對 currentStyle 來說,在IE6瀏覽器中他很專一,只喜歡以駝峰命名法命名的變量,而IE78中就有點朝三暮四,駝峰命名法和中間帶"-"的都照單全收,為了兼容和操作的簡便,我們統一轉換為駝峰命名法。
/** * 駝峰命名法轉換,IE678使用 * font-size --> fontSize * @param {String} attr * @param {String} match 匹配到的字符串,如-c * @param {String} originText (w)是一個捕獲,這里是捕獲到的字符,如c * @return 返回駝峰命名方式的css屬性名 */ function camelCase (attr){ return attr.replace(/-(w)/g, function (match,originText) { return originText.toUpperCase(); }); }透明度獲取-getFilter
IE678的透明度是通過 filter:alpha(opacity=0) 來設置的,我們利用正則表達式匹配到此時透明度的值,由于此時得到的是0-100之間的數值,所以需要換算為我們常見的0-1的形式。
/** * IE678下獲取透明度的值 * @param elem 獲取值的 dom * @return {Number} 透明度的值,默認為1 * IE678下設置透明度 filter: alpha(opacity=0) 取值為0-100 */ function getFilter(elem) { var _filter = elem.currentStyle.getAttribute("filter").match(/alpha(opacity=(.*))/i); var value = parseFloat(_filter[1]); if(!isNaN(value)){ // 轉化為0-1 return value ? value/100 : 0; } return 1; }float 值的獲取
上一篇博客中提到,由于 float 是 ECMAScript 的一個保留字。所以在各瀏覽器中都會有代替的寫法,比如說在現代瀏覽器中為 cssFloat,而在 IE678 中為 styleFloat 。經測試,在現代瀏覽器中直接使用 getPropertyValue("float") 也可以獲取到 float 的值。而 IE678 則不行,所以針對 float ,需要簡單的hack。
width | height 樣式的獲取對于一個沒有設定高寬的元素而言,在 IE678 下直接獲取得到的值是 auto 。而現代瀏覽器會直接返回它的 px 值,我們的目標就是在 IE 下也返回 px 值。
// 直接獲取外部樣式表未設置的 width 和 height 返回值為 auto // 為了獲取精確的 px 值,使用 getBoundingClientRect 方法 // getBoundingClientRect 可以獲得元素四個點相對于文檔視圖左上角 // 的 top、left、bottom、right值,進行簡單計算即可 var condition = attr === "width" || attr === "height" && elem.currentStyle[attr] === "auto"; if(condition){ var clientRect = elem.getBoundingClientRect(); return (attr === "width" ? clientRect.right - clientRect.left : clientRect.bottom - clientRect.top ) + "px"; }set方法
set 方法相較于 get 方法要簡便的多,因為我們有 cssText 這個跨越 IE6+ 和現代瀏覽器的神器。
通過elem.style.cssText可以對元素的樣式進行讀寫,實際上操作的是 html 標簽上的 style 屬性的值。因此不能直接對其賦值,不然就把整個 style 屬性的值給覆蓋掉了。我們采用累加的方式來修改屬性。
另外,在IE瀏覽器還有個小坑,如果 cssText 不為空,返回值最后一個分號會被刪掉,因此我們需要在累加的屬性前加上一個分號。
/** * 設置元素css樣式值 * @param elem 設置值的dom元素 * @param {String} attr 設置樣式名稱,如font-size * @param {String} value 設置樣式的值,如16px */ set: function (elem, attr, value){ // IE78 設置透明度需特殊處理 if(attr === "opacity"){ // 針對 IE7 的 hack // filter 濾鏡要求 hasLFooout=true 才能執行 // IE瀏覽器且 hasLFooout=false 時執行 if(!!elem.currentStyle && !elem.currentStyle.hasLFooout){ elem.style.zoom = 1; attr = "filter"; value = "alpha(opacity=" + value * 100 + ")"; } } // 通用方式 elem.style.cssText += ";" + (attr + ":" + value) + ";"; }補充 簡單解釋new操作符的作用
var Foo = function() { return new Foo.prototype.init(); } Foo.prototype = { init: function() { this.age = 18; return this; }, age: 20 } console.log(Foo().age); // 18 console.log(Foo.prototype.age); // 20
var Foo = function() { return Foo.prototype.init(); } Foo.prototype = { init: function() { this.age = 18; return this; }, age: 20 } console.log(Foo().age); // 18 console.log(Foo.prototype.age); // 18
使用 new 操作符時,是把 init 當成構造函數來調用,在 init 內部會創建一個隱式對象并用 this 指向它,此時的 this.age=18 表示在這個隱式對象上增加一個 age 屬性,最后 return this 不是必需的,構造函數默認會返回 this。此時Foo.prototype.age不受影響。
當不使用 new 操作符時,相當于一個?普通對象上的函數調用,this 指向了 init 所屬的對象,即 Foo.prototype,this.age=18相當于對 Foo.prototype.age 賦值,和使用 new 操作符是有本質區別的。
到這里,教程也就要告一段落了。一個 jQuery 中常見的 css() 方法背后涵蓋了非常多的知識點,跨瀏覽器的兼容性也是我們此次討論的重點,這次只是實現了一個非常簡易的 css 操作插件。學問尚淺,如果有不清楚或者有錯誤的地方,歡迎各位留言或者提issue來幫助我改進這個小插件。
最后,完整的項目地址:https://github.com/xdlrt/css-...
求一波star~
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/81402.html
摘要:而現代瀏覽器會直接返回它的值,我們的目標就是在下也返回值。通過可以對元素的樣式進行讀寫,實際上操作的是標簽上的屬性的值。因此不能直接對其賦值,不然就把整個屬性的值給覆蓋掉了。我們采用累加的方式來修改屬性。 上一篇博文介紹了getComputedStyle方法,接下來,我們就來實現一個簡易版的小插件,能夠在不借助jQuery的情況下實現css屬性的獲取和設置。 作者:Icarus原文鏈接...
摘要:哈哈,我理解,架構就是骨架,如下圖所示譯年月個有趣的和庫前端掘金我們創辦的使命是讓你及時的了解開發中最新最酷的趨勢。 翻譯 | 上手 Webpack ? 這篇就夠了! - 掘金譯者:小 boy (滬江前端開發工程師) 本文原創,轉載請注明作者及出處。 原文地址:https://www.smashingmagazine.... JavaSrip... 讀 Zepto 源碼之代碼結構 - ...
摘要:模塊化是隨著前端技術的發展,前端代碼爆炸式增長后,工程化所采取的必然措施。目前模塊化的思想分為和。特別指出,事件不等同于異步,回調也不等同于異步。將會討論安全的類型檢測惰性載入函數凍結對象定時器等話題。 Vue.js 前后端同構方案之準備篇——代碼優化 目前 Vue.js 的火爆不亞于當初的 React,本人對寫代碼有潔癖,代碼也是藝術。此篇是準備篇,工欲善其事,必先利其器。我們先在代...
摘要:插件開發前端掘金作者原文地址譯者插件是為應用添加全局功能的一種強大而且簡單的方式。提供了與使用掌控異步前端掘金教你使用在行代碼內優雅的實現文件分片斷點續傳。 Vue.js 插件開發 - 前端 - 掘金作者:Joshua Bemenderfer原文地址: creating-custom-plugins譯者:jeneser Vue.js插件是為應用添加全局功能的一種強大而且簡單的方式。插....
閱讀 3267·2021-11-18 10:02
閱讀 3443·2021-10-11 10:58
閱讀 3376·2021-09-24 09:47
閱讀 1120·2021-09-22 15:21
閱讀 3915·2021-09-10 11:10
閱讀 3277·2021-09-03 10:28
閱讀 1749·2019-08-30 15:45
閱讀 2137·2019-08-30 14:22