One day, the boss said that there would be a major UI overhaul, but luckily I was prepared.
I have complained before that using TyranoScript to write pages such as settings and cg is not easy to understand, and it's hard to distinguish the page hierarchy. It would be better to directly write HTML. Today, let's analyze how to create a new page using HTML.
Let's start with an existing "non-script" page, such as the default Load page, which can be found by searching for displayLoad
in the kag.menu.js file.
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)
})
The core of creating a new page is the kag.html
function, which is located in 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))
})
}
}
}
The parameters of the html function are:
- File name
- Passed data
- Callback function
By observing displayLoad
, we can see that loading the load page requires passing the page name "load", an object containing save data, and a callback function with the html file content as a parameter. There is a flaw here, the $(html) passed to the callback is not the html_ "str" written in the parameter, but an object processed by jQuery.
Returning to the html function, $.loadText
is used to retrieve the local html file using ajax, while $.templates
and tmpl.render
functions are from the open-source rendering engine jsrender.
In load.html, we can see the use of templates:
<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>
But I don't plan to use jsrender as a template engine because I also want to introduce Vue and take advantage of MVVM convenience.
So we can rewrite a simpler html function:
{
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)
})
}
},
}
The htmlPure function removes the template engine rendering and directly passes the html string to the callback function. (You can choose to keep jsrender, but in order to avoid conflicts with Vue templates, you need to modify Vue's delimiters)
After adding the htmlPure function, we also need to create a new tag for creating a new page, which is named 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()
},
}
This is the idea of using a custom page. After replacing the script file with an html file, I feel liberated. I don't have to think about callback for script jumps and clearing layers. Just call the showExtendPage tag to fade in the page.