动态改变 <link> 标签的 href 属性并不能让 CSS 即时生效,要动态改变外联 CSS 的路径,需要用到一些小技巧,有了这些技巧,就可以为 HTMLayout 增加“动态换肤”的功能了。
link[rel=”stylesheet”] 的 disabled 状态可以控制其样式表的有效性:将其设置为 true(禁用),所有由该 产生的样式会被移除;将其设置为 false(启用),则重新加载这些样式。(来源于:http://terrainformatica.com/forums/topic.php?id=964)
下面是一个例子,为了让大家更方便地测试,我处理了 HLN_LOAD_DATA 响应通知以模拟外联 CSS,真正的项目中不需要这么写。
代码示例:
import win.ui; /*DSG{{*/ var winform = ..win.form(text="动态改变外联 CSS 路径";right=654;bottom=422) winform.add() /*}}*/
import console;
import web.layout; var wbLayout = web.layout(winform);
var cssData = { ["/skins/1.css"] = /** html { background: #800; color: #fff } **/; ["/skins/2.css"] = /** html { background: #008 } button[type=checkbox] { padding: 4px 20px 4px 4px; background-position: 100% 50%; } **/; }
wbLayout.callback = function (message, wParam, lParam, vParam, notifyCode) { if (notifyCode === 0xB01/*_HLN_LOAD_DATA*/) { var nmld = web.layout.NMHL_LOAD_DATA(); raw.convert(lParam, nmld); var uri = string.fromUnicode(nmld.uri, 0, true); if (cssData[uri]) { var data = string.fromto(cssData[uri], 0, 65001); web.layout.DataReady(winform.hwnd, uri, data, #data); } return 0/*_LOAD_OK*/; } }
namespace web.layout.behavior { class alterCss { ctor (ltEle, layout) { } onButtonClick = function (ltTarget, ltEle, reason, behaviorParams) { with (layout.getEle("stylesheet")) { state.disabled = true; href = ltEle.state.checked ? "skins/2.css" : "skins/1.css"; state.disabled = false; } } } }
wbLayout.html = /** <head> <link #stylesheet rel="stylesheet" href="skins/1.css" /> </head> <body> <button type="checkbox" style="behavior: ~alter-css;">Alter external CSS</button> </body> **/
winform.show(); win.loopMessage();
|
另外,用 activate 函数也可以实现该效果:
namespace web.layout.behavior.alterCss { onButtonStateChanged = function (ltTarget, ltEle, reason, behaviorParams) { var ltSytle = ltEle.documentElement.querySelector("#stylesheet") ltSytle.href = ltEle.state.checked ? "skins/2.css" : "skins/1.css"; ltSytle.xcall("activate") } }
|