JavaScript 封装实践:动态样式表管理器

在面向对象编程中,封装是一种重要的概念,它允许一个对象将私有和公有成员组织在单一名称下。所有面向对象的编程语言都支持封装,JavaScript作为其中之一,也不例外。本文将展示如何在JavaScript中通过创建一个名为CssManager的简单对象来实现封装,该对象有助于动态地添加、移除或交换样式表。

计划

将按照以下步骤实现:

  • 创建一个名为Managers的命名空间,用于包装对象。
  • 创建一个名为CssManager的单例对象。
  • 为对象添加公有方法,用于添加、移除和交换样式表。
  • 创建私有成员。

代码实现

首先,将创建一个名为Managers的命名空间,它将包装对象。在JavaScript中,创建一个命名空间就像创建一个对象字面量一样简单。

var Managers = {};

现在,可以将所有与Managers相关的类和对象包装在一个单一的命名空间中。

接下来,将创建一个名为CssManager的单例对象。

Managers.CssManager = {};

在这对花括号之间的代码形成了对象的一部分。

然后,将为对象添加公有方法,用于添加、移除和交换样式表。在JavaScript中,对象的行为很像关联数组,即键值对数组。键是属性或方法。

创建一个名为addStyleSheet的方法,它接受两个参数:样式表元素ID和引用URL。

Managers.CssManager = { addStyleSheet: function(id, url) { // id - link's id, url - link's href } };

在addStyleSheet()方法中,将执行以下操作:动态创建一个链接元素,设置其属性,然后将其添加到头部区域。

Managers.CssManager = { addStyleSheet: function(id, url) { var newStyleSheet = document.createElement("link"); newStyleSheet.setAttribute("rel", "stylesheet"); newStyleSheet.setAttribute("type", "text/css"); newStyleSheet.setAttribute("id", id); newStyleSheet.setAttribute("href", url); document.getElementsByTagName("head")[0].appendChild(newStyleSheet); } };

接下来,将添加另外两个方法。

Managers.CssManager = { addStyleSheet: function(id, url) { var newStyleSheet = document.createElement("link"); newStyleSheet.setAttribute("rel", "stylesheet"); newStyleSheet.setAttribute("type", "text/css"); newStyleSheet.setAttribute("id", id); newStyleSheet.setAttribute("href", url); document.getElementsByTagName("head")[0].appendChild(newStyleSheet); }, removeStyleSheet: function(id) { var currentStyleSheet = document.getElementById(id); if (currentStyleSheet) { currentStyleSheet.parentNode.removeChild(currentStyleSheet); } }, swapStyleSheet: function(id, url) { this.removeStyleSheet(id); this.addStyleSheet(id, url); } };

在removeStyleSheet()方法中,查询特定的样式表元素(链接),并将其完全从DOM中移除。而在swapStyleSheet()方法中,调用另外两个方法来用新的样式表替换现有的样式表。

创建私有成员

到目前为止,创建的所有方法都是公有的。为了本文的需要,想添加两个私有成员。第一个是一个变量,它引用document对象。

var doc = document;

第二个是一个方法,它一次设置链接元素的多个属性,而不是多次调用setAttribute()。

var setAttributes = function(attributes) { // ... };

与其他语言不同,不能轻易地在JavaScript中将成员标记为公有或私有。要创建私有成员,必须使用闭包。闭包有助于创建一个私有空间。这里不会看到闭包是什么,但让看看它们如何帮助创建私有成员。

让修改CssManager来应用一个闭包:

Managers.CssManager = (function() { /* private space */ return { // Public members addStyleSheet: function(id, url) { var newStyleSheet = doc.createElement("link"); setAttributes(newStyleSheet, { rel: "stylesheet", type: "text/css", id: id, href: url }); doc.getElementsByTagName("head")[0].appendChild(newStyleSheet); }, removeStyleSheet: function(id) { var currentStyleSheet = doc.getElementById(id); if (currentStyleSheet) { currentStyleSheet.parentNode.removeChild(currentStyleSheet); } }, swapStyleSheet: function(id, url) { this.removeStyleSheet(id); this.addStyleSheet(id, url); } }; })();

所做的是创建一个看起来像自执行匿名函数的闭包,它返回之前添加的公有方法。结尾的一对括号使代码自动执行。return语句返回的所有成员都是公有的,而之前的成员则是私有的。

现在,让在私有空间中添加两个新成员:

Managers.CssManager = (function() { var doc = document; var setAttributes = function(element, attributes) { for (var attribute in attributes) { element[attribute] = attributes[attribute]; } }; return { // Public members addStyleSheet: function(id, url) { var newStyleSheet = doc.createElement("link"); setAttributes(newStyleSheet, { rel: "stylesheet", type: "text/css", id: id, href: url }); doc.getElementsByTagName("head")[0].appendChild(newStyleSheet); }, removeStyleSheet: function(id) { var currentStyleSheet = doc.getElementById(id); if (currentStyleSheet) { currentStyleSheet.parentNode.removeChild(currentStyleSheet); } }, swapStyleSheet: function(id, url) { this.removeStyleSheet(id); this.addStyleSheet(id, url); } }; })();

CssManager已经准备好了!如果想动态地向页面添加一个样式表,调用addStyleSheet方法,传递一个唯一的ID和外部CSS文件的HREF,如下所示:

Managers.CssManager.addStyleSheet("myStyleSheet", "Default.css");

同样,甚至可以移除它或用一个新的替换它:

Managers.CssManager.removeStyleSheet("myStyleSheet"); Managers.CssManager.swapStyleSheet("myStyleSheet", "Advanced.css");
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485