有一天,老板说要 UI 大整改,还好我有所准备。
之前就埋怨过,设定、cg 等页面用 TyranoScript 编写,看起来不好理解,而且页面层级还老分不清,还不如直接写 HTML 呢,今天就来分析一下怎么用 HTML 写一个新页面。
我们从已有的“非脚本”页面入手,例如默认的 Load 页面,全局搜索 displayLoad
就能找到,在 kag.menu.js 文件中。
this.kag.html("load", { array_save: array, novel: $.novel }, function (html_str) { var layer_menu = that.kag.layer.getMenuLayer(); var j_save = $(html_str); j_save.find(".save_list").css("font-family", that.kag.config.userFace); j_save.find(".save_display_area").each(function () { $(this).click(function (e) { var num = $(this).attr("data-num"); that.snap = null; that.loadGame(num); var layer_menu = that.kag.layer.getMenuLayer(); layer_menu.hide(); layer_menu.empty(); var layer_title = that.kag.layer.getTitleLayer(); layer_title.hide(); layer_title.empty(); if (that.kag.stat.visible_menu_button == true) $(".button_menu").show(); }); }); j_save.find(".button_smart").hide(); if ($.userenv() != "pc") { j_save.find(".button_smart").show(); j_save.find(".button_arrow_up").click(function () { var now = j_save.find(".area_save_list").scrollTop(); var pos = now - 160; layer_menu.find(".area_save_list").animate({ scrollTop: pos }, { queue: false }); }); j_save.find(".button_arrow_down").click(function () { var now = j_save.find(".area_save_list").scrollTop(); var pos = now + 160; j_save.find(".area_save_list").animate({ scrollTop: pos }, { queue: false }); }); } that.setMenu(j_save);});
新建页面的核心就是 kag.html
函数,此函数位于 kag.js:
{ html: function(html_file_name, data, callback) { var that = this data = data || {} if (this.cache_html[html_file_name]) { if (callback) { var tmpl = $.templates(this.cache_html[html_file_name]) var html = tmpl.render(data) callback($(html)) } } else { if (!this.kag.stat.sysview) { this.kag.stat.sysview = { save: './tyrano/html/save.html', load: './tyrano/html/load.html', backlog: './tyrano/html/backlog.html', menu: './tyrano/html/menu.html', } } var path_html = this.kag.stat.sysview[html_file_name] $.loadText(path_html, function(text_str) { var tmpl = $.templates(text_str) var html = tmpl.render(data) that.cache_html[html_file_name] = text_str if (callback) callback($(html)) }) } }}
html 函数的参数分别是:
- 文件名称
- 传入的数据
- 回调函数
观察 displayLoad 可知,加载 load 页面需要传入页面名称 load
,一个包含存档内容的对象,以及参数为 html 文件内容的回调函数。这里有一个槽点,callback 传入的 $(html)
根本不是所谓的 “str” 而是经过 jQuery 处理的对象。
回到在 html 函数中,$.loadText
使用 ajax 获取本地 html 文件;而 $.templates
和 tmpl.render
等函数均出自开源渲染引擎 jsrender。
在 load.html 中,我们可以看到模板的使用:
<div class="save_list"> {{for array_save}} <div class="save_display_area save_list_item" data-num="{{:num}}"> <span class="save_list_item_thumb"> {{if img_data != ""}} <img class="pic" src="{{:img_data}}" /> {{/if}} </span> <span class="save_list_item_thumb"> {{if img_data == ""}} <div class="pic">No data</div> {{/if}} </span>
<div class="save_list_item_area"> <div class="save_list_item_date">{{:save_date}}</div> <div class="save_list_item_text">{{:title}}</div> </div> </div> {{/for}}</div>
但是我不打算用 jsrender 作为模板引擎,因为我还要引入 Vue 顺便蹭一蹭 MVVM 的便捷。
于是我们可以改写一个更简单的 html 函数:
{ htmlPure: function(html_file_name, data, callback) { var that = this data = data || {} if (this.cache_html[html_file_name]) { if (callback) { callback(this.cache_html[html_file_name]) } } else { var path_html = this.kag.stat.sysview[html_file_name] $.loadText(path_html, function(text_str) { that.cache_html[html_file_name] = text_str if (callback) callback(text_str) }) } },}
htmlPure 函数去除了模板引擎渲染,直接将 html 字符串传入回调函数。(可以选择保留 jsrender,但是为了不和 Vue 的模板冲突,需要修改 Vue 的 delimiters)
在新增 htmlPure 函数后,还要新建一个创建新页面的标签,这里命名为 showExtendPage
:
tyrano.plugin.kag.tag.showExtendPage = { pm: {}, start: function (pm) { var that = this; this.kag.stat.is_skip = false; this.kag.htmlPure(pm.name, null, function (html_str) { var extendPage = $(html_str); var layer_extend = that.kag.layer.layer_extend; layer_extend[0].style.zIndex = pm.zindex || 9999999999; layer_extend[0].innerHTML = ""; layer_extend.fadeIn(); layer_extend.append(extendPage); }); this.kag.ftag.nextOrder(); },};
这就是使用自定义页面的思路,在把脚本文件更换为 html 文件后整个人得到了解放,不用思考脚本跳转的回调和层级清除问题,调用 showExtendPage 标签即可使页面淡入。