我的LODOP打印控件代码备份
<script src="/static/lodop/LodopFuncs.js?v=reg"></script>
<script>
//定义打印控件
var LODOP = null;
//已打印标识
var printFlag = [0,0]; //打印次数、页数
window.onload=function(){LODOP=getLodop();};
function createPage(data){
/**
* LODOP基础知识
* 计量单位关系如下(其中px单位与像素类似,但不是一个概念)
* 1in = 2.54cm = 25.4mm = 72pt = 96px
* 1mm = 2.83465pt = 3.77953px
* 1pt = 0.352777mm = 1.333333px
* 1px = 0.264583mm = 0.75pt
*
* 字号默认单位为pt,不设置默认为9pt
* 长度单位默认为px(SET_PRINT_PAGESIZE中的PageWidth和PageHeight除外,默认为0.1mm)
*
* 设置纸张大小(initOrient为1-3时会锁定打印方向,为0时由用户控制)
* SET_PRINT_PAGESIZE(intOrient, PageWidth,PageHeight,strPageName)
* 不调用此函数则由用户在打印设置中自主设置
*/
//LODOP.PRINT_INIT('证书打印');
LODOP.PRINT_INITA(0,0,'330mm','240mm','证书打印'); //top,left,width,height,printName,整体打印有偏差时,只需要调整top和left值即可
LODOP.SET_PRINT_MODE('CUSTOM_TASK_NAME', data.name); //打印任务名
LODOP.SET_PRINT_MODE('POS_BASEON_PAPER',true); //true以纸张边缘为基点;false可打区域边缘为基点
LODOP.SET_PRINT_MODE('AUTO_CLOSE_PREWINDOW',1); //打印后自动关闭预览窗口
//LODOP.SET_PRINT_PAGESIZE(0, '240mm','330mm', 'CreateCustomPage'); // 第一个参数:1纵向打印2横向打印3宽度固定高度自适应0用户控制
LODOP.SET_PRINT_PAGESIZE(2,0,0,''); //后三个值无效时只用来设置打印方向
LODOP.SET_PRINT_STYLE('FontSize',13.5); //全局字号,单位pt
LODOP.SET_PRINT_STYLE('FontName', '新宋体'); //全局字体(宋体、新宋体设置加粗无效)
LODOP.SET_PRINT_STYLE('Bold',1); //全局加粗
LODOP.SET_SHOW_MODE('BKIMG_PRINT',false); //是否打印背景图
//LODOP.SET_PRINT_STYLE('Alignment', 2); //全局水平居中
//LODOP.ADD_PRINT_TEXT(top, left, width, height, textContent); //默认单位px
LODOP.ADD_PRINT_TEXT(157,912,234,30, data.name);
//LODOP.SET_PRINT_STYLEA(0, 'FontSize', 13.5); //为前面刚添加的项目设置字号、字体、颜色等打印式样
LODOP.ADD_PRINT_TEXT(231,912,234,30, data.gender);
LODOP.ADD_PRINT_TEXT(306,912,234,30, data.nationality);
LODOP.ADD_PRINT_TEXT(381,912,234,30, data.ethnic_group);
LODOP.ADD_PRINT_TEXT(455,946,234,30, data.birth);
LODOP.ADD_PRINT_TEXT(338,289,260,30, data.major_name);
LODOP.ADD_PRINT_TEXT(418,254,260,30, data.grade);
LODOP.ADD_PRINT_TEXT(498,289,260,30, data.certdate);
LODOP.ADD_PRINT_TEXT(578,289,260,30, data.certno);
LODOP.ADD_PRINT_TEXT(659,275,260,30, data.grade_begin_end);
if(data.photo){
LODOP.ADD_PRINT_IMAGE(155,659,'36mm','49mm','<img border="0" src="'+data.photo+'?rnd='+Math.random()+'">');
LODOP.SET_PRINT_STYLEA(0,'Stretch',2);//默认不设置或0为截取模式;1按打印区域尺寸缩放(变形);2按原图比例(不变形)缩放模式
}
}
//更新打印日志
function update_print_log(row){
row.print=parseInt(row.print)+1;
table.updateRow('myTable', {index:row.LAY_INDEX, data:row}, true);
$.ajax({
type: 'POST',
data: {act:'update_print_log', id:row.id},
success: function(res){
if(res.code)return layer.alert(res.msg);
}
});
}
function batch_print(){
var data=table.checkStatus('myTable').dataCache;
if(!data.length)return layer.msg('请选择要打印的记录', {time:2e3});
$.each(data, function(index,row){
createPage(row);
LODOP.PRINT();
update_print_log(row)
});
}
//选择打印机
function print_printer(){
//return layer.alert('请在打印预览界面中点击菜单栏的"设置"选择打印机或打印设置。');
/*
var printer_list=[];
for(var i=0; i<LODOP.GET_PRINTER_COUNT(); ++i){
printer_list.push(LODOP.GET_PRINTER_NAME(i));
}
console.log(printer_list);
return;
*/
}
//打印维护
function print_edit(){
var row=create_data();
if(row===null)return layer.alert('无数据');
createPage(row);
LODOP.ADD_PRINT_SETUP_BKIMG('<img border="0" src="/static/images/cert.jpg">');
LODOP.SET_SHOW_MODE('SHOW_SCALEBAR',1); //显示标尺
LODOP.SET_SHOW_MODE("BKIMG_LEFT",0);
LODOP.SET_SHOW_MODE("BKIMG_TOP",0);
LODOP.SET_SHOW_MODE('HIDE_PBUTTIN_SETUP',true);
LODOP.SET_SHOW_MODE('HIDE_PBUTTIN_PREVIEW',true);
LODOP.PRINT_SETUP();
}
//打印预览
function print_view(){
var row=create_data();
if(row===null)return layer.alert('无数据');
createPage(row);
LODOP.ADD_PRINT_SETUP_BKIMG('<img border="0" src="/static/images/cert.jpg">');
LODOP.SET_SHOW_MODE('BKIMG_IN_PREVIEW',1); //打印预览显示背景图
LODOP.SET_SHOW_MODE('SHOW_SCALEBAR',1); //显示标尺
LODOP.SET_SHOW_MODE('HIDE_PAPER_BOARD',1); //隐藏打印预览背景进纸版的图案
LODOP.SET_SHOW_MODE("BKIMG_LEFT",0);
LODOP.SET_SHOW_MODE("BKIMG_TOP",0);
LODOP.SET_SHOW_MODE('HIDE_PBUTTIN_SETUP',true);
LODOP.SET_SHOW_MODE('HIDE_PBUTTIN_PREVIEW',true);
LODOP.PREVIEW();
}
function print_design(){
LODOP.PRINT_INITA(0,0, '330mm','240mm', '打印设计');
LODOP.PRINT_DESIGN();
}
//版本检测
function print_version(){
try{
if(LODOP.VERSION) {
let str=LODOP.CVERSION ? 'C-Lodop版本:'+LODOP.CVERSION+'<br>Lodop版本:'+LODOP.VERSION : '本机已安装Lodop控件!<br>版本号:'+LODOP.VERSION;
layer.alert(str);
};
}catch(e){}
}
//打印预览、打印维护时展示的数据
function create_data(){
var data=table.getData('myTable');
if(!data.length)return null;
var checkData=table.checkStatus('myTable').data;
return checkData.length ? checkData[0] : data[0];
}
</script>
怎么判断是否在微信浏览器中打开
方法一:
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
<script>
// 判断是否在微信中打开
if (typeof WeixinJSBridge === 'object' && typeof WeixinJSBridge.invoke === 'function') {
console.log('当前页面在微信中打开');
} else {
console.log('当前页面不在微信中打开');
}
方法二:
function is_weixn(){
var ua=navigator.userAgent.toLowerCase();
if(ua.match(/MicroMessenger/i)=="micromessenger"){
return true;
}else{
return false;
}
}
用jQuery对html转义字符进行反转义
$('<div></div>').html(转义后的html).text();datetimepicker手册
来源:
https://xdsoft.net/jqplugins/datetimepicker/
https://github.com/xdan/datetimepicker
Full options list
| Name | default | Descr | Ex. |
|---|---|---|---|
| lazyInit | false | Initializing plugin occurs only when the user interacts. Greatly accelerates plugin work with a large number of fields | |
| parentID | 'body' | Attach datetimepicker to this element, which can be either a selector or a DOM/JQuery element | |
| value | null | Current value datetimepicker. If it is set, ignored input.value | |
| lang | en | Language i18n ar - Arabic az - Azerbaijanian (Azeri) bg - Bulgarian bs - Bosanski ca - Català ch - Simplified Chinese cs - Čeština da - Dansk de - German el - Ελληνικά en - English en-GB - English (British) es - Spanish et - "Eesti" eu - Euskara fa - Persian fi - Finnish (Suomi) fr - French gl - Galego he - Hebrew (עברית) hr - Hrvatski hu - Hungarian id - Indonesian it - Italian ja - Japanese ko - Korean (한국어) kr - Korean lt - Lithuanian (lietuvių) lv - Latvian (Latviešu) mk - Macedonian (Македонски) mn - Mongolian (Монгол) nl - Dutch no - Norwegian pl - Polish pt - Portuguese pt-BR - Português(Brasil) ro - Romanian ru - Russian se - Swedish sk - Slovenčina sl - Slovenščina sq - Albanian (Shqip) sr - Serbian Cyrillic (Српски) sr-YU - Serbian (Srpski) sv - Svenska th - Thai tr - Turkish uk - Ukrainian vi - Vietnamese zh - Simplified Chinese (简体中文) zh-TW - Traditional Chinese (繁體中文) | |
| format | Y/m/d H:i | Format datetime. More Also there is a special type of «unixtime» | |
| formatDate | Y/m/d | Format date for minDate and maxDate | |
| formatTime | H:i | Similarly, formatDate . But for minTime and maxTime | |
| step | 60 | Step time | |
| closeOnDateSelect | 0 | | |
| closeOnWithoutClick | true | | |
| validateOnBlur | true | Verify datetime value from input, when losing focus. If value is not valid datetime, then to value inserts the current datetime | |
| timepicker | true | | |
| datepicker | true | | |
| weeks | false | Show week number | |
| theme | 'default' | Setting a color scheme. Now only supported default and dark theme | |
| minDate | false | | |
| maxDate | false | | |
| startDate | false | calendar set date use starDate | |
| defaultDate | false | if input value is empty, calendar set date use defaultDate | |
| defaultTime | false | if input value is empty, timepicker set time use defaultTime | |
| minTime | false | | |
| maxTime | false | | |
| allowTimes | [] | | |
| mask | false | Use mask for input. true - automatically generates a mask on the field 'format', Digit from 0 to 9, set the highest possible digit for the value. For example: the first digit of hours can not be greater than 2, and the first digit of the minutes can not be greater than 5 | |
| opened | false | ||
| yearOffset | 0 | Year offset for Buddhist era | |
| inline | false | ||
| todayButton | true | Show button "Go To Today" | |
| defaultSelect | true | Highlight the current date even if the input is empty | |
| allowBlank | false | Allow field to be empty even with the option validateOnBlur in true | |
| timepickerScrollbar | true | ||
| onSelectDate | function(){} | | |
| onSelectTime | function(current_time,$input){} | ||
| onChangeMonth | function(current_time,$input){} | ||
| onChangeYear | function(current_time,$input){} | ||
| onChangeDateTime | function(current_time,$input){} | ||
| onShow | function(current_time,$input){} | ||
| onClose | function(current_time,$input){} | | |
| onGenerate | function(current_time,$input){} | trigger after construct calendar and timepicker | |
| withoutCopyright | true | ||
| inverseButton | false | ||
| scrollMonth | true | ||
| scrollTime | true | ||
| scrollInput | true | ||
| hours12 | false | ||
| yearStart | 1950 | Start value for fast Year selector | |
| yearEnd | 2050 | End value for fast Year selector | |
| roundTime | round | Round time in timepicker, possible values: round, ceil, floor | |
| dayOfWeekStart | 0 | Star week DatePicker. Default Sunday - 0. Monday - 1 ... | |
| className | |||
| weekends | [] | | |
| disabledDates | [] | Disbale all dates in list | |
| allowDates | [] | Allow all dates in list | |
| allowDateRe | [] | Use Regex to check dates | |
| disabledWeekDays | [] | Disable days listed by index | |
| id | |||
| style | |||
| ownerDocument | document | The ownerDocument object for the datetimepicker to properly attach events and calc position (iframe support). | |
| contentWindow | window | The contentWindow object that contains the datetimepicker to properly attach events (iframe support). |
Methods
show
Show Datetimepicker
$('#input').datetimepicker();
$('button.somebutton').on('click', function () {
$('#input').datetimepicker('show');
});hide
Hide Datetimepicker
$('#input').datetimepicker();
$(window).on('resize', function () {
$('#input').datetimepicker('hide');
});toggle
Sgow/Hide Datetimepicker
$('#input').datetimepicker();
$('button.trigger').on('click', function () {
$('#input').datetimepicker('toggle');
});destroy
Destroy datetimepicker
$('#input').datetimepicker();
$('#input').datetimepicker('destroy');
reset
Reset datetimepicker's value
$('#input').datetimepicker();
$('#input').val('12/01/2006');
$('#input')
.datetimepicker('show')
.datetimepicker('reset')
validate
Validate datetimepicker's value
$('#input').datetimepicker();
$('#input').datetimepicker(validate)
setOptions
Set datetimepicker's options
$('#input').datetimepicker({format: 'd.m.Y'});
$('#input').datetimepicker('setOptions', {format: 'd/m/Y'});
//or
$('#input').datetimepicker({format: 'd/m/Y'});
getValue
Get current datetimepicker's value (Date object)
$('#input').datetimepicker();
$('button.somebutton').on('click', function () {
var d = $('#input').datetimepicker('getValue');
console.log(d.getFullYear());
});JS之array.sort
array.sort(compareFunction)
参数值
| 参数 | 描述 |
|---|---|
| compareFunction | 可选。定义替代排序顺序的函数。该函数应返回负值、零值或正值,具体取决于参数,例如:
sort() 方法比较两个值时,将值发送给比较函数,根据返回的(负、零、正)值对值进行排序。 举例:比较 40 和 100 时,sort() 方法调用比较函数(40,100)。 该函数计算 40-100,并返回 -60(负值)。 sort 函数会将 40 排序为小于 100 的值。 |
JS array.sort() 中文排序
// 创建包含中文元素的数组
var arr = ['张三', '李四', '王五'];
// 自定义比较函数
function compare(a, b) {
return a.localeCompare(b); // 根据本地化设置对中文进行排序
}
arr.sort(compare);
console.log(arr); // 输出结果为 ["李四", "王五", "张三"]
按升序对数组中的数字排序
var points = [40, 100, 1, 5, 25, 10];
points.sort(function(a, b){return a-b});按降序对数组中的数字排序
var points = [40, 100, 1, 5, 25, 10];
points.sort(function(a, b){return b-a});数组反转
array.reverse()
深入理解JavaScript——Object(对象)
转自:https://zhuanlan.zhihu.com/p/556955018
先回顾下之前一节所讲知识
- 引用类型指的是 object
- object 包括内置对象、宿主对象、自定义对象
- 内置对象中有 Object、Function、Array、String、Number、Boolean 等原生对象构造函数
- 在 JavaScript 中,一切皆对象(除 undefined、null 外)
无论是内置对象,还是自定义对象,都是基于 Object 来创建,其中的原理是原型继承,所以笔者喜欢称 Object.prototype 为“始祖巨人”,一切力量源于尤弥尔
我们看看 Object 是什么,它能做什么,并将其扩展,连接 Object 相关的各个知识点。知识列表如下:
- 属性与方法
- 如何创建对象
- 如何拷贝对象
- 对象继承的秘密——原型
- 继承的九种方法
属性与方法
JavaScript 对象可以从一个称为原型的对象里继承属性。对象的方法通常是继承的属性。这种”原型式继承“(prototypal inheritance)是 JavaScript 的核心特征
可以看下这个例子
var johan = { name: 'johan' };
console.dir(johan);

能看出,我们使用对象字面量的方法创建了一个对象实例 johan,并赋予了一个属性 name,值为 johan,当打印日志时,发现多了一个对象[[Prototype]],并且这个对象中有很多对象
这是因为「对象字面量」创建的实例,在底层已经做了「隐式继承」的操作,它和 new Object('johan') 是一个意思,除此之外,如果使用 new ,会进行原型继承,[[prototype]] 正是继承 Object 的原型(即 Object.prototype)
这里,不妨多说一句,实例是继承 Object.prototype,而不是 Object,原型才会被继承,构造函数是个空壳,不信,你答应 Object 和 Object.prototype,看看内容
console.dir(Object)如下图所示:

console.dir(Object.prototype)如下图所示

johan 的 [[prototype]] 和 Object 的 prototype 的内容一致
关于原型和继承的内容后文会详细说明,这里埋个伏笔
看以上例子,你能发现 Object 的属性和方法不少,而且它的实例也有属性和方法,这里对其进行说明注解
静态方法
Object.assign():通过复制一个或多个对象来创建一个新的对象Object.create():使用指定的原型对象和属性创建一个新对象Object.defineProperty():给对象添加一个属性并指定该属性的配置Object.defineProperties():给对象添加多个属性并分别指定它们的配置Object.entries():返回给定对象自身可枚举属性的[key, value]数组Object.keys():返回一个包含所有给定对象自身可枚举属性名称的数组Object.values():返回给定对象自身可枚举值的数组
实例属性
Object.prototype.constructor:一个引用值,指向 Object 构造函数Object.prototype.__proto__:指向一个对象,当一个 object 实例化时,使用该对象作为实例化对象的原型
实例方法
Object.prototype.hasOwnProperty():返回一个布尔值,用于表示一个对象自身是否包含指定的属性,该方法并不会查找原型链上继承来的属性- 用
hasOwnProperty就能检测出,它能区别自身属性与继承属性 Object.prototype.isPrototypeOf():返回一个布尔值,用于表示该方法所调用的对象是否在指定对象的原型链中Object.prototype.toString():返回一个代表该对象的字符串。Object.prototype.valueOf():返回指定对象的原始值
更多信息可以查看 MDN
了解 Object 的属性、方法,以及基于它创建的实例属性和方法后,我们去看看如何创建对象
创建对象
有三种方法。对象直接量、关键字 new、 Object.create 函数来创建对象
对象直接量
创建一个新对象的最简单的方法,就是用对象直接量,就如使用以下语句:
var obj = {};
{} 表示的 new Object()
关键字 new
使用 new 创建新对象,一般要跟随一个函数调用。这里的函数称为构造函数(constructor),构造函数用以初始化一个新创建的对象。例如:
var obj = new Object(); // 效果如同 var obj = {}
更多内容,可查看这篇 new 做了什么
Object.create
此方法是 ECMAScript 5 定义了,它牵扯到原型、继承等方面的知识。简单来说,它创造了一个新对象,其中第一个参数就是这个对象的原型。而第二个可选参数,是对其属性的更多描述。例如:
var obj = Object.create({ name: 'johan', age: 23 }); // obj 继承了属性name 和 age
var obj2 = Object.create(null); // obj2 不继承任何属性和方法
var obj3 = Object.create(Object.prototype); // 与 {} 和 new Object() 一个意思
更多内容,可查看这篇 Object.create
之所以将 new 和 Object.create 单独拿出来说,是因为两则都是比较重要的知识点,非一两句就能说明白
了解 Object 是如何创造的之后,我们看看如何赋值
如何拷贝对象
赋值是简单的,但赋值后的再赋值,就会引起源对象被修改
var o1 = { name: 'johan' };
var o2 = o1;
o2.name = 'elaine';
console.log(o1); // {name: 'elaine'}
console.log(o2); // {name: 'elaine'}
之前文章也说过,因为 Object 是引用类型,引用类型的拷贝拷贝的是引用地址,所以当 o2 被修改时,o1 也随之被修改
针对如何拷贝对象,这篇文章拷贝的秘密会对其进行说明
对象继承的秘密——原型
要想解释 JavaScript 中为什么大多数元素都是对象,就必须先知道原型。JavaScript 是一门基于原型的语言——每个对象拥有一个原型对象,对象以其原型为模板、从原型继承方法和属性。原型对象也可能拥有原型,并从中继承方法和属性,一层一层,以此类推。这种关系常被称为原型链
有关原型和原型链的知识,会归纳总结为一篇——原型
继承的九种方法
原型是实现继承的方法之一,当然 JavaScript 还有其他的方法,总共九种
- 原型链继承
- 盗用构造函数
- 组合继承(原型链+盗用构造函数)
- 原型式继承
- Object.create
- Object.setPrototypeOf
- 寄生式继承
- 寄生式组合继承
- Object.create + 盗用构造函数
- Object.setPrototypeOf + 盗用构造函数
- 类继承
具体的文章会在继承说明
总结
这一节,我们就 Object 进行展开,详细说明了 Object 及其实例的属性与方法。并对如何创建对象、如何拷贝对象、原型、继承等进行说明分析,因篇幅以及知识点聚焦问题,本节不做过多说明,下一节,我们从如何创建对象之new说起
系列文章
- 深入理解JavaScript——开篇
- 深入理解JavaScript——JavaScript 是什么
- 深入理解JavaScript——JavaScript 由什么组成
- 深入理解JavaScript——一切皆对象
- 深入理解JavaScript——Object(对象)
- 深入理解JavaScript——new 做了什么
- 深入理解JavaScript——Object.create
- 深入理解JavaScript——拷贝的秘密
- 深入理解JavaScript——原型
- 深入理解JavaScript——继承
- 深入理解JavaScript——JavaScript 中的始皇
- 深入理解JavaScript——instanceof找祖籍
- 深入理解JavaScript——Function
- 深入理解JavaScript——作用域
- 深入理解JavaScript——this关键字
- 深入理解JavaScript——call、apply、bind三大将
- 深入理解JavaScript——立即执行函数(IIFE)
- 深入理解JavaScript——词法环境
- 深入理解JavaScript——执行上下文与调用栈
- 深入理解JavaScript——作用域 VS 执行上下文
- 深入理解JavaScript——闭包
- 深入理解JavaScript——防抖与节流
- 深入理解JavaScript——函数式编程
- 深入理解JavaScript——垃圾回收机制
- 深入理解JavaScript——数组
- 深入理解JavaScript——循环都来这儿
- 深入理解JavaScript——字符串
lodop打印控件-关于谷歌Chrome浏览器94版跨域问题的解决方案
谷歌浏览器再次迈出激进安全步骤,Win10+Chrome94版阻断http页面访问localhost服务, 这一举动广泛影响了Web模式的设备管理系统,例如路由服务、打印服务等,其中也包括C-Lodop软件。 安全是个美好的托词,真正让谷歌贸然行动的动机是大力推广https协议,而https背后是TLS证书, TLS证书背后是浏览器厂商的年费分成,利益巨大...闲话少说,解决方案如下:
有四种方法,选其一就行:
一、网站改用HTTPS方式(彻底方案)
二、安装最新的C-Lodop6.564及后版本,并更新LodopFuncs.js文件;
三、手动修改客户浏览器安全设置,在Chrome地址栏输入:chrome://flags/#block-insecure-private-network-requests
看到底色泛黄的“Block insecure...”项的 Default 值,改选成 Disabled然后窗口下方会出现蓝底的Relaunch按钮,点它重启浏览器。
四、客户端改用低版本Chrome(94版前)浏览器,简单办法是安装360急速版(Chrome内核)
注:微软的浏览器Edge94版因为采用了Chrome内核,故以上解决方案也适用。
layui自动触发select事件
来源:https://toscode.gitee.com/layui/layui/issues/I5JMRW
$(obj).siblings("div.layui-form-select").find("dl dd[lay-value='"+value+"']").click();
国内常用前端静态资源公共库
转自:https://azpay.cn/post/210.html
BootCDN 是 极兔云 联合 Bootstrap 中文网 共同支持并维护的前端开源项目免费 CDN 服务,致力于为 jQuery、Bootstrap、Vue.js 一样优秀的前端开源项目提供稳定、快速的免费 CDN 加速服务。BootCDN 所收录的开源项目主要同步于 cdnjs 开源项目仓库。
官网:https://www.bootcdn.cn
Staticfile CDN 是由国内优秀的云存储服务商 七牛云 提供存储和加速赞助,技术社区掘金支持。同步国外 cdnjs 源站,同时由国内开源贡献者提交其它有价值的库。
官网:https://www.staticfile.org
360 前端静态资源库是由奇舞团支持并维护的开源项目免费 CDN 服务,支持 HTTPS 和 HTTP/2,囊括上千个前端资源库和 Google 字体库。该站静态资源库数据均同步于 cdnjs 开源项目仓库。
官网:https://cdn.baomitu.com
字节跳动静态资源库支持多协议、资源动态拼接、快速检索及资源的动态更新,安全、稳定、实时。本网站静态资源定期同步自 cdnjs ,有多个文件拼接的功能。
官网:https://cdn.bytedance.com
js 字符和unicode互转
String.fromCharCode(97); //a String.fromCharCode(97,97); //aa String.fromCharCode(20013); //中 '中国'.charCodeAt(0); //20013
