var getUrlParam = function(name) {
var reg = new RegExp("(^|&|#|/?)" + name + "=([^&]*)(&|$)", "i");
var r = window.location.href.substr(1).match(reg);
if (r != null) {
var result = unescape(r[2]);
if (result.indexOf('#') > 0) {
result = result.slice(0, result.indexOf('#'));
};
return result;
}
return null;
};
var type = getUrlParam('type');
function addCssByLink(url){
var doc=document;
var link=doc.createElement("link");
link.setAttribute("rel", "stylesheet");
link.setAttribute("type", "text/css");
link.setAttribute("href", url);
var heads = doc.getElementsByTagName("head");
if(heads.length)
heads[0].appendChild(link);
else
doc.documentElement.appendChild(link);
}
//方法一:动态生成link标签
// addCssByLink('css/' + type + '.css');
function setStyleSheet(url) {
var doc=document;
var link = doc.getElementById('css');
if (link){
link.setAttribute("href", url);
}else {
addCssByLink(url);
}
}
//方法二:动态设置href的值。
setStyleSheet('css/' + type + '.css')
'use strict'
var fs = require('fs')
var path = require('path')
var url=require("url");
var querystring=require("querystring");
// Define global Vue for server-side app.js
global.Vue = require('vue')
// Get the HTML layout
var layout = '<!DOCTYPE html>\
<html>\
<head>\
<title>My Vue App</title>\
<link href="#" rel="stylesheet" type="text/css" />\
<script src="/assets/vue.js"></script>\
</head>\
<body>\
<div class="app" id="app"></div>\
<div class="app">test</div>\
<div class="app">test</div>\
<div class="app">test</div>\
<div class="app">test</div>\
<div class="app">test</div>\
<div class="app">test</div>\
<div class="app">test</div>\
<div class="app">test</div>\
<div class="app">test</div>\
<script src="/assets/app.js"></script>\
<script>app.$mount(\'#app\')</script>\
</body>\
</html>'
// Create a renderer
var renderer = require('vue-server-renderer').createRenderer()
// Create an express server
var express = require('express')
var server = express()
// Serve files from the assets directory
server.use('/assets', express.static(
path.resolve(__dirname, 'assets')
))
// Handle all GET requests
server.get('/assets/index', function (request, response) {
// Render our Vue app to a string
renderer.renderToString(
// Create an app instance
require('./assets/app')(),
// Handle the rendered result
function (error, html) {
// If an error occurred while rendering...
if (error) {
// Log the error in the console
console.error(error)
// Tell the client something went wrong
return response
.status(500)
.send('Server Error')
}
var str=url.parse(request.url,true).query;
var arg = querystring.parse(url.parse(request.url).query);
var type = arg.type || 'classic';
//这里根据参数等信息动态替换link
var data = layout.replace('<div id="app"></div>', html)
.replace('<link href="#" rel="stylesheet" type="text/css" />','<link href="/assets/css/'+ type +'.css" rel="stylesheet" type="text/css" />');
// Send the layout with the rendered app's HTML
response.send(data)
}
)
})
// Listen on port 5000
server.listen(5000, function (error) {
if (error) throw error
console.log('Server is running at localhost:5000')
})
根据业务场景动态换肤办法
实现根绝业务场景,比如:不同渠道(pc,微信)等,动态整体换肤功能,主要有两种方法。
使用JS动态设置样式表(客户端换肤)
这种方法主要是在浏览器渲染过程中,根据参数(可能来自请求参数,或者浏览器嗅探)动态设置样式表。
主体代码,大致如下:
这种方法,确确实实实现了根据不同参数换肤的功能。但是,这种方法会存在闪烁问题。
闪烁问题,主要是因为再次请求、重绘和大量图片等问题造成的。
而且,对于多页应用(非SPA)需要在每一个页面中都执行这段代码,以确保每一个页面都正确显示。
服务端动态设置样式表
这种方式,就是在服务端返回页面时,动态设置html中link标签的属性。
比如,常见的JSP页面可以这样写:
但是,现在谁还写JSP页面,所以,这种方式忽略。
另外一种方式,就是服务端渲染。这里有几个关键字:单页面应用,服务端渲染,动态生成link,Node中间层。
服务端渲染的具体实现方式可以参考如下代码:
关于以上两个方式,我均做了一个简单的Demo,分别可以体验客户端JS替换和服务端替换的差别。具体源代码请联系我。
另外:对于通过PhoneGap或者Cordoba打包的H5应用,虽然,css文件和图片等已经被打包到本地,但是在替换CSS时,仍然会有轻微的闪烁问题。这种方式,是属于客户端替换,本人已亲自体验过这种换肤方式。
对于JS动态替换,折中的实现方式是,另外一套样式尽量不大面积改变DOM结构,对于背景图片和icon等内容,应进行较少量的变化。