<!DOCTYPE html> <html> <head> <title>工具提示(享元模式)</title> <meta charset="utf-8"> <script src="Library.js"></script> </head> <body> <a id="link-id1" href="">1111111</a><a id="link-id2" href="">222222</a> <script> /** * 示例:工具提示对象 * * 在HS对象需要创建HTML内容这种情况下,享元模式特别有用。那种会生成DOM元素的对象如果数目众多的话,会占用过多内存,使网页陷入泥沼。采用享元模式后,只需创建少许这种对象即可,所有需要这种对象的地方都可以共享它们。工具提示就是一个典型的例子。 */ // 未经优化的Tooltip类 // Tooltip class, un-optimized var Tooltip = function (targetElement, text) { this.target = targetElement; this.text = text; this.delayTimeout = null; this.delay = 500; this.element = document.createElement('div'); this.element.style.display = 'none'; this.element.style.position = 'absolute'; this.element.className = 'tooltip'; document.body.appendChild(this.element); this.element.innerHTML = this.text; var that = this; addEvent(this.target, 'mouseover', function (e) { that.startDelay(e); }); addEvent(this.target, 'mouseout', function (e) { that.hide(); }); }; Tooltip.prototype = { startDelay: function (e) { if (this.delayTimeout === null) { var that = this, x = e.clientX, y = e.clientY; this.delayTimeout = setTimeout(function () { that.show(x, y); }, this.delay); } }, show: function (x, y) { clearTimeout(this.delayTimeout); this.delayTimeout = null; this.element.style.left = x + 'px'; this.element.style.top = (y + 20) + 'px'; this.element.style.display = 'block'; }, hide: function () { clearTimeout(this.delayTimeout); this.delayTimeout = null; this.element.style.display = 'none'; } }; var link1 = $('link-id1'), link2 = $('link-id2'); var tt = new Tooltip(link1, 'Lorem ipsum....'); // 作为享元的Tooltip /* 把Tooltip类转化为享元需要做三件事:把外在数据从Tooltip对象中删除;创建一个用来实例化Tooltip的工厂;创建一个用来保存外在数据的管理器。在这个例子,我们可以用一个单体同时扮演工厂和管理器的角色。此外,由于外在数据可以作为事件侦听器一部分保存,因此没有必要使用一个中心数据库。 */ // TooltipManager singleton, a flyweight factory and manager var TooltipManager = (function () { var storedInstance = null; // Tooltip class, as aflyweight var Tooltip = function () { this.delayTimeout = null; this.delay = 500; this.element = document.createElement('div'); this.element.style.display = 'none'; this.element.style.position = 'absolute'; this.element.className = 'tooltip'; document.body.appendChild(this.element); }; Tooltip.prototype = { startDelay: function (e, text) { if (this.delayTimeout === null) { var that = this, x = e.clientX, y = e.clientY; this.delayTimeout = setTimeout(function () { that.show(x, y, text); }, this.delay); } }, show: function (x, y, text) { clearTimeout(this.delayTimeout); this.delayTimeout = null; this.element.innerHTML = text; this.element.style.left = x + 'px'; this.element.style.top = (y + 20) + 'px'; this.element.style.display = 'block'; }, hide: function () { clearTimeout(this.delayTimeout); this.delayTimeout = null; this.element.style.display = 'none'; } }; return { addTooltip: function (targetElement, text) { // Get the tooltip object var tt = this.getTooltip(); // Attach the events addEvent(targetElement, 'mouseover', function (e) { tt.startDelay(e, text); }); addEvent(targetElement, 'mouseout', function (e) { tt.hide(); }); }, getTooltip: function () { if (storedInstance === null) { storedInstance = new Tooltip(); } return storedInstance; } }; })(); // Tooltip usage TooltipManager.addTooltip($('link-id2'),'fuck your ass'); /* 上面的Tooltip类删除了原来的构造函数的所有参数以及注册事件处理器的代码。而startDelay和show方法则各增加了一个新的参数,这样一来,要显示的文字就可以作为外在数据传给他们。 这个单体有两个方法,分别体现了他的两种角色,getTooltip是工厂方法,它与你之前见到过的其他享元的生成方法差不多。addTooltip则是管理器方法,它先获取一个Tooltip对象,然后后分别把两个匿名函数注册为目标元素的mouseover和mouseout事件侦听器。这个例子用不着创建中心数据库,因为那两个匿名函数中生成的闭包已经保存了外在数据。 */ /* 现在生成的DOM元素已减至一个。这很重要,假如你想为工具提示添加阴影或iframe垫片等特性,那么每个Tooltip对象需要生成5-10个DOM元素。要是不把它实现为享元的话,网页将被成百上千个工具提示压垮。此外,享元模式的应用还减少了对箱内部保存的数据。 */ </script> </body> </html>
本文参考链接:https://www.cnblogs.com/webFrontDev/archive/2013/03/24/2978523.html