first commit

This commit is contained in:
编码猿
2024-09-27 02:06:13 +08:00
commit 852d94fbb9
36760 changed files with 3274413 additions and 0 deletions

View File

@@ -0,0 +1,50 @@
class Ajax {
get(params) {
lui.loading();
return new Promise((resolve,reject) => {
$.ajax({
type: "GET",
url: this.url() + params.url,
data: params.data,
success: (msg) =>{
lui.loading('close')
resolve(this.onreadystatechange(msg))
},
error: (err) => {
lui.loading('close')
console.log(err)
}
});
})
}
onreadystatechange(res) {
switch (res.status) {
case 200:
return res.result
break;
case 404:
throw new Error(res.msg);
break;
}
}
url() {
switch (config.stage) {
case "dev":
return config.devUrl;
break;
case "test":
return config.testUrl;
break;
case "prod":
return config.prodUrl;
break;
}
}
}
var ajax = new Ajax()

View File

@@ -0,0 +1,12 @@
var config = {
devUrl: 'http://127.0.0.1:3000/api/json',
testUrl: 'http://test.com/api/json',
prodUrl: 'http://prod.com/api/json',
stage: 'dev',
urlList: {
index: '/index',
type: '/class',
classList: '/classList',
info: '/info'
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,861 @@
;(function(global,undefined){
"use strict";
var g = {};
/**
返回文档中匹配指定 CSS 选择器的一个元素
* @param el CSS 选择器
*/
g.selector = function(el){
return document.querySelector(el);
}
/**
返回文档中匹配指定 CSS 选择器的集合
* @param el CSS 选择器
*/
g.selectorAll = function(el){
return document.querySelectorAll(el);
}
/**
* 判断是否支持touch事件
*/
g.isSupportTouch = function(){
return 'ontouchstart' in window
}
/**
* 获取地址栏参数值
* @param {string} name 参数名称
* @return 返回匹配结果
*/
g.getQueryString = function (name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
var r = window.location.search.substr(1).match(reg);
if (r != null) return unescape(r[2]);
return null;
}
/**
* 长按事件
* @param {string} el [选择器]
* @param {Function} cb [长按后的回调函数]
*/
g.longPress = function(el,cb){
var t = null,selector = g.selector(el);
var handleStart = g.isSupportTouch() ? 'touchstart' : 'mousedown',
handleEnd = g.isSupportTouch() ? 'touchend' : 'mouseup';
selector.addEventListener('contextmenu', function(e){
e.preventDefault();
});
selector.addEventListener(handleStart,function(e){
selector.style.cssText += '-webkit-touch-callout:none';
e.preventDefault();
t = setTimeout(function(){
if (cb && typeof cb == 'function') {
cb();
}
},800)
},false)
selector.addEventListener(handleEnd,function(){
clearTimeout(t);
},false)
}
/**
* 动态加载js
* @param url 传入的url,单个直接是字符串形式,多个以数组形式
* @param callback 加载js后的回调
*/
g.loadScript = function(url, callback) {
var script = document.createElement("script");
script.type = "text/javascript";
script.async = true;
script.defer = true;
if(typeof url === 'string'){
document.createElement("script");
script.type = "text/javascript";
script.async = true;
script.defer = true;
script.src = url;
} else {
for(var i = 0;i < url.length;i ++){
document.createElement("script");
script.type = "text/javascript";
script.async = true;
script.defer = true;
script.src = url[i];
}
}
document.head.appendChild(script);
if(callback && typeof callback == 'function'){
if (script.readyState) {
script.onreadystatechange = function () {
if (script.readyState == "loaded" || script.readyState == "complete") {
script.onreadystatechange = null;
callback();
}
};
} else {
script.onload = function () {
callback();
};
}
}
}
g.pullDownRefresh = function(container,callback){
var touch,startX,startY,moveX,moveY,touchX,touchY,flag = false;
var div = document.querySelector(container),
iconHeight = 50;
div.style.cssText += 'transform:translate3d(0,-'+iconHeight+'px,0);webkitTransform:translate3d(0,-'+iconHeight+'px,0);overscroll-behavior: contain';
div.addEventListener("touchstart",touchstart,false);
div.addEventListener("touchmove",touchmove,false);
div.addEventListener("touchend",touchend,false);
function touchstart(e){
flag = true;
// e.preventDefault();
var touch = e.changedTouches[0];
startX = touch.pageX;
startY = touch.pageY;
// console.log('touchstart:'+startX);
}
function touchmove(e){
var touch = e.changedTouches[0];
moveX = touch.pageX;
moveY = touch.pageY;
touchX = moveX - startX;
touchY = moveY - startY - iconHeight;
if (moveY - startY > 0 && flag){
if (touchY > 6) {
document.querySelector('#pullDown').classList.add('flip');
}else{
document.querySelector('#pullDown').classList.remove('flip');
}
div.style.cssText += 'transform:translate3d(0,'+touchY+'px,0);webkitTransform:translate3d(0,'+touchY+'px,0);';
}
// console.log('touchY:'+touchY);
}
function touchend(e){
flag = false;
div.style.cssText += 'transform:translate3d(0,-'+iconHeight+'px,0);webkitTransform:translate3d(0,-'+iconHeight+'px,0);transition:all .2s cubic-bezier(.08,.87,.08,.87);webkitTransition:all .2s cubic-bezier(.08,.87,.08,.87);';
if (callback && typeof callback === "object" && callback['end']) {
callback['end'](touchY)
};
}
},
/**
* 滑动到底加载更多(需要注意的是,有滚动条才能滚动,如果页面禁止了默认滑动,也无法使用该方法)
* @param wrap要滚动的元素
* @param callback滚动到底的回调函数
*/
g.scrollToBottom = function(wrap,callback){
var wrap = document.querySelector(wrap),
divHeight = wrap.clientHeight,
scrollTop,
scrollHeight,
t = null,
res;
wrap.onscroll = function(){
scrollHeight = this.scrollHeight;
scrollTop = this.scrollTop;
if(scrollTop + divHeight >= scrollHeight){
if(callback && typeof callback === "function"){
clearTimeout(t);
t = setTimeout(function(){
callback();
},100)
}
}else{
res = divHeight+'+'+scrollTop +'>'+ scrollHeight+'?';
callback(res);
}
};
}
/**
* tab切换
* @params tabs 包含tab和tabContent的盒子选择器
* @params cb 回调函数,内置一个下标参数
*/
g.tabs = function(tabs,cb){
var tabs = document.querySelector(tabs),
tab = tabs.querySelectorAll('[tab-role="tab"]'),
tabContent = tabs.querySelectorAll('[tab-role="tabContent"]');
tabs.addEventListener('click',function(e){
for(var i =0,len = tab.length;i < len;i++){
tab[i].setAttribute('data-id',i);
var index = e.target.dataset.id;
if(index == i){
tab[i].classList.add('active');
tabContent[i].style.display = 'block';
if (cb && typeof cb === 'function') {
cb(Number(index))
}
}else{
tab[i].classList.remove('active');
tabContent[i].style.display = 'none';
}
}
},true)
}
/**
*输入框高度自适应
*@param textarea 要绑定的textarea
*@param num 克隆的textarea的随机id(用于一个页面有多个textarea的情况)
*/
g.textareaAutoHeight = function(textarea,num){
var textarea = document.querySelector(textarea),
node = textarea.cloneNode(),
num = num || 0;
node.id = 'clone_textarea2017'+num;
document.querySelector('body').appendChild(node);
node.style.cssText = 'position:absolute;left:-1000000px';
textarea.oninput = function(e){
console.log('input');
node.value = textarea.value;
node.style.cssText += 'width:'+textarea.scrollWidth+'px';
var h = node.scrollHeight;
h=h>70?70:(h>35 ? h+2 : 30);
e.target.style.cssText = 'height:'+h+'px';
}
}
/**
* 计算文本域输入字数
* @param textField 要绑定的文本域
* @param cb 监听输入后的回调
*/
g.getTextFieldLen = function(textField,cb){
var el = g.selector(textField);
el.oninput = function(e){
var res = e.target.value.trim();
if (cb && typeof cb == 'function') {
cb(res.length);
}
}
}
/**
*搜索交互
@param opts 接收一个对象参数
*/
g.search = function(opts){
var opts = opts || {
el:el, //绑定搜索框外层元素
input:function(){ //实时输入的回调
},
clear:function(){ //清空搜索框输入值的回调
},
cancel:function(){ //取消搜索的回调
},
enter:function(){ //回车事件回调
}
}
var el = opts.el,
input = opts.input,
clear = opts.clear,
cancel = opts.cancel,
enter = opts.enter;
var labelEl = g.selector(el + ' [role="search-label"]'),
inputEl = g.selector(el + ' [role="search-input"]'),
closeEl = g.selector(el + ' [role="search-close"]'),
cancelEl = g.selector(el + ' [role="search-cancel"]');
//展开搜索框
var _showSearch = function(){
labelEl.style.display = 'none';
};
//显示删除按钮
var _showClose = function(){
var val = inputEl.value;
if(val.length){
closeEl.style.display = 'block';
if (input && typeof input === "function") {
input(val)
}
}else{
closeEl.style.display = 'none';
}
};
//清除输入框值
var _clearValue = function(){
inputEl.value = '';
closeEl.style.display = 'none';
if (clear && typeof clear === "function") {
clear()
}
};
//取消搜索
var _cancelSearch = function(){
_clearValue();
labelEl.style.display = 'block';
if (cancel && typeof cancel === "function") {
cancel()
}
};
//回车
inputEl.onkeypress = function(e){
var keyCode = e.which || e.keyCode;
var val = e.target.value;
if(keyCode == 13){
inputEl.blur();
if(enter && typeof enter === "function"){
enter(val)
}
}
}
labelEl.addEventListener('click',_showSearch,false);
inputEl.addEventListener('input',_showClose,false);
closeEl.addEventListener('click',_clearValue,false);
cancelEl.addEventListener('click',_cancelSearch,false);
}
/**
*底部弹出层
@param el 弹窗页面的选择器
@param callback 回调方法
*/
g.coverHandler = function(el,callback){
var t = null,el = document.querySelector(el);
if (!el.classList.contains('j_isOpenModal')) {
clearTimeout(t);
el.classList.add('j_isOpenModal');
el.style.display = 'block';
setTimeout(function(){
el.classList.remove('modal_out');
el.classList.add('modal_in');
},10)
if (callback && typeof callback === "object" && callback['open']) {
callback['open']();
};
}else {
el.classList.remove('j_isOpenModal');
el.classList.remove('modal_in');
el.classList.add('modal_out');
t = setTimeout(function(){
el.style.display = 'none';
},300)
if (callback && typeof callback === "object" && callback['close']) {
callback['close']();
};
}
}
/**
* loading
* @param text 提示内容,如果传入参数为close,则关闭loading
* @param opacity 遮罩透明度
*/
g.loading = function(text,opacity) {
var text = text || "加载中...";
var removeLoading = function(){
var maskEl = document.getElementById('j_loading_mask');
if (maskEl) {
maskEl.parentNode.removeChild(maskEl);
}
}
removeLoading()
if (text != 'close'){
var el = document.createElement('div');
el.id = 'j_loading_mask';
el.className = 'ui_loading_mask';
el.style.cssText = 'background:rgba(0,0,0,'+opacity+')';
el.innerHTML = '<div class="ui_loading_wrap" id="ui_loading_wrap">'
+ '<div id="loading" class="ui_loading"><div><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></div>'
+ '</div>'
+ '<div class="ui_loading_text">'
+ '<p>'+text+'</p>'
+ '</div>'
+ '</div>';
document.body.appendChild(el);
}
}
/**
* toast (opts接受一个对象参数)
* @param type 操作提示类型,文本类型text,警告类型warning,成功类型ok
* @param text 提示文本内容
* @param duration 持续多少毫秒退出
* @param position 所在页面位置
*/
g.toast = function(opts) {
var opts = opts || {};
opts.type = opts.type || 'ok';
opts.text = opts.text || '提示信息';
opts.position = opts.position || '';
opts.duration = opts.duration || 2000;
var el = document.createElement('div');
el.id = 'js_ui_toast';
el.className = 'ui_toast_wrap';
el.innerHTML = '<div class="ui_toast toast_'+opts.position+'">'
+ '<div class="ui_toast_inner">'
+ '<span class="ui_toast_ico_wrap"><i class="ui_toast_ico ui_toast_'+opts.type+'_ico"></i></span>'
+ '<div class="ui_toast_text">'
+ '<p>'+opts.text+'</p>'
+ '</div>'
+ '</div>'
+ '</div>';
document.body.appendChild(el);
el.childNodes[0].classList.add('ui_effect_fade');
setTimeout(function(){
var childEl = document.getElementById('js_ui_toast');
if (childEl) {
childEl.parentNode.removeChild(childEl);
}
},opts.duration)
}
/**
* showModal模态框 (opts 接收一个对象参数 )
* @param title 标题
* @param content 内容
* @param cancelText 取消按钮的文字
* @param confirmText 确认按钮的文字
* @param customClass 自定义class样式
* @param showCancel 是否显示取消按钮,默认为 true
* @param cancel {function} 取消按钮的回调函数
* @param confirm {function} 确定按钮的回调函数
* @param beforeHide {function} 退出模态框前的回调函数
*/
g.showModal = function(opts){
var opts = opts || {}
opts.title = opts.title || '提示';
opts.content = opts.content || '内容';
opts.cancelText = opts.cancelText || '取消';
opts.confirmText = opts.confirmText || '确认';
opts.customClass = opts.customClass || '';
opts.showCancel = opts.showCancel || false;
var modalEl = document.querySelector('#j_modal_wrap');
if (modalEl) {
modalEl.parentNode.removeChild(modalEl); //避免出现多个弹窗
}
var el = document.createElement('div');
el.id = 'j_modal_wrap';
el.className = 'ui_modal_wrap';
el.innerHTML = '<div class="ui_modal '+opts.customClass+'" id="j_modal">'
+ '<div class="ui_modal_hd">'+opts.title+'</div>'
+ '<div class="ui_modal_bd">'+opts.content+'</div>'
+ '<div class="ui_modal_ft" id="js_btns2017">'
+ '<a href="javascript:;" class="ui_modal_btn ui_modal_default_btn" data-btn="_cancel2017">'+opts.cancelText+'</a>'
+ '<a href="javascript:;" class="ui_modal_btn ui_modal_primary_btn" data-btn="_confirm2017">'+opts.confirmText+'</a>'
+ '</div>'
+ '</div>';
document.body.appendChild(el);
var cancelBtn = g.selector('[data-btn="_cancel2017"]'),
confirmBtn = g.selector('[data-btn="_confirm2017"]');
!opts.showCancel && cancelBtn.parentNode.removeChild(cancelBtn);
var modal_wrap = document.querySelector('#j_modal_wrap'),
modal = document.querySelector('#j_modal');
setTimeout(function(){
modal.classList.add('ui_modal_in');
},60)
var hideModal = function(){
modal.classList.remove('ui_modal_in');
modal.classList.add('ui_modal_out');
if (opts.beforeHide && typeof opts.beforeHide == 'function') {
opts.beforeHide()
}
setTimeout(function(){
modal_wrap.parentNode.removeChild(modal_wrap);
},200)
}
var modalBtnHandler = function(e){
var btn = e.target.dataset.btn;
if (btn) {
if(btn == "_cancel2017" && opts.cancel && typeof opts.cancel == "function"){
setTimeout(function(){
opts.cancel();
},201)
}
if(btn == "_confirm2017" && opts.confirm && typeof opts.confirm == "function") {
setTimeout(function(){
opts.confirm();
},201)
}
hideModal();
};
}
cancelBtn && cancelBtn.addEventListener('click',function(e){
modalBtnHandler(e);
},false);
confirmBtn && confirmBtn.addEventListener('click',function(e){
modalBtnHandler(e);
},false);
}
/**
* ajax封装(使用方法与jq的ajax方法几乎一样)
*/
g.request = function(opts) {
var opts = opts || {};
opts.type = opts.type.toUpperCase() || 'POST';
opts.url = opts.url || '';
opts.data = opts.data || null;
opts.beforeSend = opts.beforeSend || function() {};
opts.success = opts.success || function() {};
opts.error = opts.error || function() {};
opts.closeLoading = opts.closeLoading || false
var xmlHttp;
if (window.XMLHttpRequest) {
// IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
xmlHttp = new XMLHttpRequest();
} else {
// IE6, IE5 浏览器执行代码
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
var params = [];
for (var key in opts.data) {
params.push(key + '=' + opts.data[key]);
}
var postData = params.join('&');
opts.beforeSend();
if (opts.type === 'POST') {
xmlHttp.open(opts.type, opts.url, true);
xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlHttp.send(postData);
} else if (opts.type === 'GET') {
xmlHttp.open(opts.type, opts.url + '?' + postData, true);
xmlHttp.send();
}
if (! opts.closeLoading) {
g.loading();
}
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
g.loading('close');
var res = JSON.parse(xmlHttp.responseText);
opts.success(res)
}
}
xmlHttp.onerror = function(e){
opts.error(e)
}
}
/**
* 索引列表滑动
* @param scrollElem 滚动元素的选择器
*/
g.indexAction = function(scrollElem){
var startX, startY, moveX, moveY, title, a, y = [],h = [],english,word_popup,t = null,flag = false;
title = document.querySelectorAll('[data-role="word_index"]');
english = document.querySelector('[data-role="word_list"]');
a = document.querySelectorAll('[data-role="word_list"] a');
word_popup = document.querySelector('[data-role="word_popup"]'); //popup
var fixed_h = (document.body.clientHeight - english.clientHeight) / 2; //原生js的offsetTop在元素用了fixed属性后,有bug,会从0计算,所以用窗口的高度减去元素的高度来计算距离
// console.log((fixed_h));
var scrollElem = scrollElem || '.ui_page_bd';
var offsetTop = 0;
var item = document.querySelector(scrollElem);
var startAction = this.isSupportTouch() ? 'touchstart' : 'mousedown';
var endAction = this.isSupportTouch() ? 'touchend' : 'mouseup';
for (var i = 0; i < a.length; i++) {
a[i].addEventListener([startAction], _start, false);
a[i].addEventListener('touchmove', _move, false);
a[i].addEventListener([endAction], _end, false);
y[i] = a[i].offsetTop + fixed_h;
h[i] = a[i].clientHeight;
};
function _start(e) {
flag = true;
if (g.isSupportTouch()) {
var touch = e.changedTouches[0];
startX = touch.pageX;
startY = touch.pageY;
}
var attr = e.target.dataset.href;
word_popup.classList.add('active');
word_popup.innerText = attr;
offsetTop = document.querySelector('#'+attr).offsetTop;
// item.scrollTo(0,offsetTop);
item.scrollTop = offsetTop
}
function _move(e) {
e.preventDefault();
if (flag) {
var touch = e.changedTouches[0];
moveX = touch.pageX;
moveY = touch.pageY;
word_popup.classList.add('active');
var scrollTop = document.body.scrollTop;
for (var j = 0; j < title.length; j++) { //循环需要滑动的英文字母
if ((y[j] + scrollTop < moveY) && (moveY < y[j] + h[j] + scrollTop)) { //计算区间获得对应字母的位置
offsetTop = document.querySelector('#'+title[j].id).offsetTop;
// item.scrollTo(0,offsetTop);
item.scrollTop = offsetTop;
word_popup.innerText = title[j].id;
}
};
}
}
function _end() {
flag = false;
clearTimeout(t);
t = setTimeout(function(){
word_popup.classList.remove('active');
},500);
}
}
/**
* 水印(增加密度)
* @param div 将水印挂载到指定div
* @param str 水印文字
* @param len 水印个数
*/
g.watermark = function(div,str,len){
var str = str || '保密水印';
var el,top,left,translateX,len = len || 10,container = document.querySelector(div);
container.style.cssText += 'position:relative;overflow:hidden;user-select:none;-webkit-user-select:none;'
for (var i = 0; i < len; i++) {
top = 19*i-40;
if(i%5 == 0){
left = '10%';
}
if(i%5 == 1){
left = '30%';
}
if(i%5 == 2){
left = '50%';
}
if(i%5 == 3){
left = '70%';
}
if(i%5 == 4){
left = '90%';
}
translateX = '-50%';
el = document.createElement('div');
el.className = 'fixed_watermark';
el.style.cssText = 'pointer-events:none;position:absolute;transform:rotate(-25deg) translateX('+translateX+');-webkit-transform:rotate(-25deg) translateX('+translateX+');font-size:16px;color:#bcc7cd;opacity:.5;user:none;-webkit-user:none;white-space:nowrap';
el.innerHTML = str;
el.style.cssText += 'left:'+left+';top:'+top+'px;';
if(container){
container.appendChild(el);
}else{
document.body.appendChild(el);
}
}
}
/**
* 详情图片预览
* @param img 图片选择器集合
*/
g.photoViewer = function(img){
var arr = document.querySelectorAll(img),i,len = arr.length,str ='',div;
div = document.createElement('div');
div.id = 'js_photoZoomWrap';
div.className = 'photoZoomWrap';
var init = function(){
str +='<div class="swiper-container photoZoom modal_out" id="swiperZoom">'
str += '<div class="swiper-wrapper">'
for (i = 0; i < len; i++) {
str += '<div class="swiper-slide">'
str += '<div class="swiper-zoom-container">'
str += '<img src="'+arr[i].src+'" class="swiper-lazy">'
str += '</div>'
str += '</div>';
}
str +='</div>'
str +='<div class="swiper-pagination swiper-pagination-white"></div>'
str += '<div class="swiper-button-prev"></div>'
str += '<div class="swiper-button-next"></div>'
str +='<div class="close_photoZoom" id="close_photoZoom"></div>'
str +='</div>';
div.innerHTML = str;
document.body.appendChild(div);
}();
var swiper = new Swiper('#swiperZoom', {
zoom: true,
pagination: {
el: '.swiper-pagination',
},
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
on:{
click: function(event){
closePhotoZoom();
}
}
});
//关闭
var closePhotoZoom = function(){
g.selector('#swiperZoom').classList.remove('modal_in');
g.selector('#swiperZoom').classList.add('modal_out');
setTimeout(function(){
g.selector('#js_photoZoomWrap').classList.remove('active');
},200)
}
document.addEventListener('click',function(e){
if (e.target.id == 'close_photoZoom') {
closePhotoZoom();
}
},false)
//预览当前
for (var i = 0; i < arr.length; i++) {
(function(index){
arr[index].addEventListener('click',function(){
swiper.slideTo(index,0);
g.selector('#js_photoZoomWrap').classList.add('active');
g.selector('#swiperZoom').classList.remove('modal_out');
g.selector('#swiperZoom').classList.add('modal_in');
},false)
})(i)
};
}
/**
*上传图片预览大图
* @param img 图片选择器集合
* @param index 当前图片预览的索引
*/
g.photoZoomUpload = function(img,index){
var arr = document.querySelectorAll(img),i,len = arr.length,str ='',div;
div = document.createElement('div');
div.id = 'js_photoZoomUploadWrap';
div.className = 'photoZoomWrap';
var init = function(){
str += '<div class="swiper-container photoZoom modal_out" id="swiperZoomUpload">'
str += '<div class="swiper-wrapper">'
for (i = 0; i < len; i++) {
str += '<div class="swiper-slide">'
str += '<div class="swiper-zoom-container">'
str += '<img src="'+arr[i].src+'" class="swiper-lazy">'
str += '</div>'
str += '</div>';
}
str +='</div>'
str +='<div class="swiper-pagination swiper-pagination-white"></div>'
str +='<div class="swiper-button-prev"></div>'
str +='<div class="swiper-button-next"></div>'
str +='<div class="close_photoZoom" id="close_photoZoomUpload"></div>'
str +='</div>';
div.innerHTML = str;
document.body.appendChild(div);
}();
//关闭
var closePhotoZoom = function(){
var photoZoomWrap = g.selector('#js_photoZoomUploadWrap');
console.log(photoZoomWrap.parentNode)
photoZoomWrap.parentNode.removeChild(photoZoomWrap)
}
var swiper = new Swiper('#swiperZoomUpload', {
zoom: true,
initialSlide:index,
pagination: {
el: '.swiper-pagination',
},
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
on:{
click: function(event){
closePhotoZoom();
}
}
});
swiper.pagination.update();
g.selector('#js_photoZoomUploadWrap').classList.add('active');
g.selector('#swiperZoomUpload').classList.remove('modal_out')
g.selector('#swiperZoomUpload').classList.add('modal_in');
document.addEventListener('click',function(e){
if (e.target.id == 'close_photoZoomUpload') {
closePhotoZoom();
}
},false)
}
/**
* 倒计时
* @param str 时间字符串
* @param cb 回调函数
*/
g.countDown = function(str,cb){
var s = "";
var t = setInterval(function(){
str = str.replace(/-/g,"/");
var lastDate = new Date(str);
var currDate = new Date();
if(lastDate < currDate){
clearInterval(t);
cb();
}
var intDiff = (lastDate.getTime()-currDate.getTime())/1000;
var day=0,
hour=0,
minute=0,
second=0;//时间默认值
if(intDiff > 0){
day = Math.floor(intDiff / (60 * 60 * 24));
hour = Math.floor(intDiff / (60 * 60)) - (day * 24);
minute = Math.floor(intDiff / 60) - (day * 24 * 60) - (hour * 60);
second = Math.floor(intDiff) - (day * 24 * 60 * 60) - (hour * 60 * 60) - (minute * 60);
}
if (day < 10) day = '0' + day;
if (hour < 10) hour = '0' + hour;
if (minute < 10) minute = '0' + minute;
if (second < 10) second = '0' + second;
s = day+"|"+hour+'|'+minute+'|'+second;
intDiff--;
cb(s)
}, 1000);
}
/**
* 获取第几天的时间
* @param num {Number} 第几天
* @param datetime {Date} 某天的日期
* @param format {String} 格式化
*/
g.getDateTime = function (num, datetime, format) {
var datetime = datetime || new Date(),
d = new Date(datetime);
d.setTime(d.getTime() + (24*60*60*1000) * num);
var addZero = function (n) {
return n < 10 ? "0" + n : n
}
var y = addZero(d.getFullYear()),
M = addZero(d.getMonth() + 1),
_d = addZero(d.getDate()),
h = addZero(d.getHours()),
m = addZero(d.getMinutes()),
s = addZero(d.getSeconds());
var res = ''
switch (format) {
case 'yyyy-MM-dd':
res = y + "-" + M + "-" + _d;
break;
case 'yyyy-MM-dd HH:mm':
res = y + "-" + M + "-" + _d + ' ' + h + ':' + m;
break;
default:
res = y + "-" + M + "-" + _d + ' ' + h + ':' + m + ':' + s;
break;
}
return res
},
/**
* 返回某天中文星期
* @param datetime {Date}
*/
g.getCnDay = function(datetime){
var datetime = datetime || new Date();
var d = new Date(datetime).getDay();
var arr = ['日','一','二','三','四','五','六']
return arr[d]
}
/**
* 控制select默认样式
*/
g.changeSelectStyle = function(ev){
if (ev.target.value === '') {
ev.target.classList.add('placeholderColor')
}else{
ev.target.classList.remove('placeholderColor')
}
}
//开启vConsole调试模式
if (g.getQueryString('vConsole') === '1') {
g.loadScript('js/3rd-plugins/vconsole.min.js',function(){
new VConsole();
})
}
global.lui = g;
})(window);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,267 @@
class PreviewImage {
// 属性都是全局的
body = this.$("body");
option = {};
isBackMove = false;
x1 = 0;
y1 = 0;
l = 0;
t = 0;
constructor(option) {
if (!option.hasOwnProperty("image")) {
throw new Error("参数image缺少,请检查")
}
if (!option.hasOwnProperty("showIndex")) {
throw new Error("参数showIndex缺少,请检查")
}
this.option = option
console.log(this.option);
this.created();
this.BindClose();
this.BindPrevious();
this.BindNext();
this.BindSuoXiao();
this.BindFangDa();
this.BindFullScreen();
this.BindXuanZhuan();
this.MouseEvent();
}
// 1:把图片预览的html插入到网页上
created() {
this.body.insertAdjacentHTML("beforeend", `<div class="previewImage">
<div class="zhezhao"></div>
<div class="preview">
<div class="closed">x</div>
<div class="action">
<div class="left d">&lt;</div>
<div class="right d">&gt;</div>
</div>
<img class="mainImg" style="transform: scale(1) rotate(0deg);margin-left: 0;margin-top: 0;"
src="${this.option.image[this.option.showIndex]}" alt="">
<ul class="operation">
<li>
<i class="iconfont icon-suoxiao suoxiao"></i>
</li>
<li>
<i class="iconfont icon-fangda fangda"></i>
</li>
<li>
<i class="iconfont icon-fullscreen fullscreen"></i>
</li>
<li class="xz">
<i class="iconfont icon-shuaxin leftshuaxin"></i>
</li>
<li>
<i class="iconfont icon-shuaxin rightshuaxin"></i>
</li>
</ul>
</div>
</div>`)
}
// 缩小
BindSuoXiao() {
this.$(".suoxiao").onclick = () => {
var value = this.Scale() - 0.2;
if (value != 0) {
this.$(".mainImg").style.transform = `scale(${value}) rotate(${this.Rotate()}deg)`
}
}
}
// 全屏
BindFullScreen() {
this.$(".fullscreen").onclick = () => {
// true 缩小
if (this.$(".fullscreen").classList.contains("icon-fullscreen")) {
this.$(".fullscreen").classList.remove("icon-fullscreen")
this.$(".fullscreen").classList.add("icon-suoxiao1")
this.$(".mainImg").style = `
transform: scale(2) rotate(${this.Rotate()}deg);
margin-left: 0;
margin-top: 0;
`
// 放大
} else {
this.$(".fullscreen").classList.remove("icon-suoxiao1")
this.$(".fullscreen").classList.add("icon-fullscreen")
this.$(".mainImg").style = `
transform: scale(1) rotate(0deg);
margin-left: 0;
margin-top: 0;
`
}
}
}
// 放大
BindFangDa() {
this.$(".fangda").onclick = () => {
this.$(".mainImg").style.transform = `scale(${this.Scale() + 0.2}) rotate(${this.Rotate()}deg)`
}
}
// 旋转
BindXuanZhuan() {
// -90
this.$(".leftshuaxin").onclick = () => {
this.xuanzhuan(-90)
}
// +90
this.$(".rightshuaxin").onclick = () => {
this.xuanzhuan(90)
}
}
MouseEvent() {
// 鼠标滑动的时候放大缩小网页
document.onmousewheel = (e) => {
if (e.wheelDelta == 210) {
this.$(".fangda").onclick()
} else {
this.$(".suoxiao").onclick()
}
}
// document.addEventListener('mousewheel',(e) => {
// if (e.wheelDelta == 210) {
// this.$(".fangda").onclick()
// } else {
// this.$(".suoxiao").onclick()
// }
// },false)
// 鼠标在图片上按下的时候
this.$(".mainImg").onmousedown = (e) => {
e.preventDefault()
this.isBackMove = true
//获取鼠标按下的坐标
this.x1 = e.clientX;
this.y1 = e.clientY;
this.l = parseInt(this.$(".mainImg").style.marginLeft);
this.t = this.$(".mainImg").offsetTop;
this.ImgMove(".mainImg")
}
// 按住拖动,但鼠标从图片上离开的
// 给背景层绑定鼠标移动事件
this.$(".mainImg").onmouseleave = () => {
console.log("鼠标从图片上离开的,给背景层绑定鼠标移动事件");
if (this.isBackMove) {
this.ImgMove(".preview")
}
}
// 鼠标在背景层上松开
this.$(".preview").onmouseup = (ev) => {
console.log("鼠标在背景层上松开");
this.isBackMove = false
this.$(".mainImg").onmousemove = null;
this.$(".preview").onmousemove = null;
}
// 鼠标在图片上松开
this.$(".mainImg").onmouseup = (ev) => {
console.log("鼠标在图片上松开");
this.$(".mainImg").onmousemove = null;
this.$(".preview").onmousemove = null;
}
}
ImgMove(className) {
this.$(className).onmousemove = (ev) => {
var x2 = ev.clientX;
var y2 = ev.clientY;
//计算出鼠标的移动距离
var x = x2 - this.x1;
var y = y2 - this.y1;
//移动的数值与元素的left,top相加,得出元素的移动的距离
var lt = y + this.t;
var ls = x + this.l;
//更改元素的left,top值
this.$(".mainImg").style.marginLeft = ls + 'px';
this.$(".mainImg").style.marginTop = lt + 'px';
}
}
xuanzhuan(offset) {
this.$(".mainImg").style.transform = `scale(${this.Scale()}) rotate(${this.Rotate() + offset}deg)`
}
// 关闭按钮
BindClose() {
//1 var ddddc = this;
//2 es6 => 箭头函数
console.log("this1: ", this);
// this 指向
this.$(".closed").onclick = () => {
this.body.removeChild(this.$(".previewImage"))
}
}
// 上一页
BindPrevious() {
this.$(".left").onclick = () => {
this.option.showIndex -= 1;
if (this.option.showIndex < 0) {
this.option.showIndex = this.option.image.length - 1
}
this.$(".mainImg").src = this.option.image[this.option.showIndex]
}
}
// 下一页
BindNext() {
this.$(".right").onclick = () => {
this.option.showIndex += 1;
if (this.option.showIndex > this.option.image.length - 1) {
this.option.showIndex = 0
}
this.$(".mainImg").src = this.option.image[this.option.showIndex]
}
}
Scale() {
return Number(this.$(".mainImg").style.transform.match(/scale\(([\s\S]*?)\) /)[1])
}
Rotate() {
return Number(this.$(".mainImg").style.transform.match(/rotate\(([\s\S]*?)deg\)/)[1])
}
$(className) {
return document.querySelector(className)
}
}

View File

@@ -0,0 +1,12 @@
window.onload = function () {
getRem(750, 100)
};
window.onresize = function () {
getRem(750, 100)
};
function getRem(pwidth, prem) {
var html = document.getElementsByTagName("html")[0];
var oWidth = document.body.clientWidth || document.documentElement.clientWidth;
console.log(oWidth / pwidth * prem)
html.style.fontSize = oWidth / pwidth * prem + "px";
}

View File

@@ -0,0 +1,69 @@
class Edit {
constructor() {
pHeader("分类编辑")
// 已选
this.principal = get_storage("principal")
// 待选
this.additional = get_storage("additional")
this.yx();
}
yx () {
$(".yx").empty()
this.principal.forEach(v => {
$(".yx").append(`
<li>${v.title}</li>
`)
});
var self = this
$(".yx li").click(function () {
self.additional.push(self.principal[$(this).index()])
self.principal = self.principal.filter((v,i) => {
if (i != $(this).index()) {
return v
}
});
set_storage("principal", self.principal)
set_storage("additional", self.additional)
self.yx()
})
$(".dx").empty()
this.additional.forEach(v => {
$(".dx").append(`
<li>${v.title}</li>
`)
})
var self = this
$(".dx li").click(function () {
self.principal.push(self.additional[$(this).index()])
self.additional = self.additional.filter((v,i) => {
if (i != $(this).index()) {
return v
}
});
set_storage("principal", self.principal)
set_storage("additional", self.additional)
self.yx()
})
}
}
new Edit()

View File

@@ -0,0 +1,142 @@
class Index {
constructor() {
this.currentIndex = 0;
this.classData = []
this.geIndex();
this.GetType();
footer()
lui.scrollToBottom('.swiper-slide-active',function(){
console.log("11")
})
}
async GetType() {
var principal = [], additional = []
if (localStorage.getItem("principal") == null) {
let res = await indexServe.type();
principal = res.principal
additional = res.additional
localStorage.setItem("principal", JSON.stringify(principal))
localStorage.setItem("additional", JSON.stringify(additional))
} else {
principal = get_storage("principal")
additional = get_storage("additional")
}
var self = this;
principal.unshift({
title: '首页',
id: -1,
page: 0,
content: []
})
this.classData = principal
principal.forEach((v,i) => {
$(".header_menu ul").append(`
<li class="${i == 0 ? 'active': ''}">${v.title}</li>
`)
if (i > 0) {
$(".page-wrapper").append(`
<div class="swiper-slide eee list_fa padding_16 top"></div>
`)
}
});
var page = new Swiper ('.page-container', {
direction: 'horizontal',
on:{
slideChange: function (){
self.currentIndex = this.activeIndex;
$(".header_menu ul li").eq(this.activeIndex).addClass("active").siblings().removeClass("active")
self.getClassList();
},
},
})
$(".header_menu ul li").click(function () {
self.currentIndex = $(this).index()
$(this).addClass("active").siblings().removeClass("active")
page.slideTo($(this).index())
})
}
async getClassList() {
if (this.classData[this.currentIndex].id != -1) {
if (this.classData[this.currentIndex].content.length == 0) {
let res = await indexServe.classList({
page: this.classData[this.currentIndex].page,
id: this.classData[this.currentIndex].id
});
this.classData[this.currentIndex].total_page = res.total_page
this.classData[this.currentIndex].content = [
...this.classData[this.currentIndex].content,
...res.data
]
item($(".page-wrapper .eee").eq(this.currentIndex -1),
this.classData[this.currentIndex].content)
}
}
}
async geIndex() {
let data = await indexServe.index()
console.log(data)
var modelArr = [ { content: [] }, { content: [] } ]
data.model.res.forEach((v,i) => {
if (i<4) {
modelArr[0].content.push(v)
} else {
modelArr[1].content.push(v)
}
})
modelArr.forEach(v=> {
$(".model-wrapper").append(`
<ul class="swiper-slide">
${
v.content.map(item => {
return ` <li>
<a href="">
<div class="top">
<img src="${item.preview}" alt="">
<span>${item.total}</span>
</div>
<p>${item.title}</p>
</a>
</li>`
}).toString().replaceAll(",","")
}
</ul>
`)
})
item(".news", data.newest.data)
item(".remm", data.recommended.data)
new Swiper ('.model-container', {
direction: 'horizontal',
})
}
}
new Index()

View File

@@ -0,0 +1,119 @@
class Info {
constructor() {
this.res = {}
this.like = {}
this.likeArr =
localStorage.getItem("like") == null
? []
: JSON.parse(localStorage.getItem("like"))
this.page = 1;
this.total_page = 0;
this.pswpElement = $(".pswp")[0]
this.getInfo()
.then(() => this.renderInfo())
}
async getInfo() {
this.res = await indexServe.info({
page: this.page,
id: query("id")
});
this.total_page = this.res.total_page
// this.total_page = 3
// 详情页
this.res.data.forEach(v => {
var image = new Image();
image.src = v.src
image.onload = () => {
if (image.width < image.height) {
this.like.preview = v.src
}
$(".info_img").append(`
<figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
<a href="${v.src}" itemprop="contentUrl" data-size="${image.width}x${image.height}">
<img src="${v.src}" itemprop="thumbnail" alt="${v.title}" />
</a>
<figcaption itemprop="caption description">${v.title}</figcaption>
</figure>
`)
}
})
initPhotoSwipeFromDOM(".info_img")
$(".tuijian").empty()
$(".xianguan").empty()
item(".tuijian", this.res.recommend)
item(".xianguan", this.res.relevant)
}
renderInfo() {
console.log(this.res)
pHeader(this.res.title, `
<i class="iconfont like icon-xin"></i>
<i class="iconfont icon-home"></i>
`);
this.like = {
id: query("id"),
title: this.res.title,
total: this.res.total,
preview: ''
}
var isHave = this.likeArr.filter((v,i) => {
if (v.id == query("id")) {
return v
}
})
// 本地收藏过了
if (isHave.length != 0) {
$(".like").removeClass("icon-xin")
$(".like").addClass("icon-aixin")
} else {
$(".like").removeClass("icon-aixin")
$(".like").addClass("icon-xin")
}
$(".like").click(() => {
// 如果空心,表示未收藏,改成实心 收藏
if ($(".like").hasClass("icon-xin")) {
$(".like").removeClass("icon-xin")
$(".like").addClass("icon-aixin")
this.likeArr.push(this.like)
localStorage.setItem("like",JSON.stringify(this.likeArr))
// 取消收藏
} else {
$(".like").removeClass("icon-aixin")
$(".like").addClass("icon-xin")
this.likeArr = this.likeArr.filter((v,i) => {
if (v.id != query("id")) {
return v
}
})
localStorage.setItem("like",JSON.stringify(this.likeArr))
}
})
$(".icon-xiangxia").click(() => {
this.page+=1
if (this.page == this.total_page) {
$(".icon-xiangxia").hide()
}
this.getInfo()
})
}
}
new Info();

View File

@@ -0,0 +1,7 @@
class Mechanism {
constructor() {
footer()
}
}
new Mechanism();

View File

@@ -0,0 +1,44 @@
class IndexServe {
async index(params = {}) {
return await ajax.get({
url: config.urlList.index,
data: params,
})
}
async info(params = {}) {
return await ajax.get({
url: config.urlList.info,
data: params,
})
}
async classList(params = {}) {
return await ajax.get({
url: config.urlList.classList,
data: params,
})
}
async type(params = {}) {
var data = await ajax.get({
url: config.urlList.type,
data: params,
});
data.principal.forEach(v => {
v.content = []
v.total_page = 0
});
data.additional.forEach(v => {
v.content = []
v.total_page = 0
});
return data
}
}
var indexServe = new IndexServe();

View File

@@ -0,0 +1,316 @@
class Utils {
constructor() {
}
query(name) {
var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if(r!=null)return unescape(r[2]); return null;
}
footer() {
var footerList = [
{ title: '首页', img: 'icon-home', isActve: true, url: './index.html' },
{ title: '机构', img: 'icon-jigou', isActve: false, url: './mechanism.html' },
{ title: '模特', img: 'icon-me', isActve: false, url: './model.html' },
{ title: '我的', img: 'icon-wo', isActve: true, url: './me.html' },
];
// 当前访问的页面地址
var currentUrl = location.href.match(/page\/([\s\S]*?).html/)[1]
$("body").append(`
<ul class="footer">
${
footerList.map((v,i) => {
return `<li class="${ v.url.includes(currentUrl) ? 'footer_active': '' }">
<a href="${v.url}">
<i class="iconfont ${v.img}"></i>
<p>${v.title}</p>
</a>
</li>`
}).toString().replaceAll(",","")
}
</ul>
`)
}
item(father, data) {
var li = ""
data.forEach(v => {
li+= `
<li>
<div class="newest_img">
<a href="./info.html?id=${v.id}">
<img src="${v.preview}" alt="">
<span>${v.total}</span>
</a>
</div>
<div class="newest_text">
<div class="t">${v.title}</div>
${
v.user.length != 0
? `<div class="source">${v.user}</div>`
: ''
}
${
v.source.length != 0
? `<div class="source">${v.source}</div>`
: ''
}
</div>
<div class="tags">
${
v?.tags.map((item) => {
return ` <a class="tags_item" href="">${item.title}</a>`
}).toString().replaceAll(",","")
}
</div>
</li>
`
})
$(father).append(li)
}
pHeader(title, right_action = "") {
$("body").prepend(`
<div class="pub_header themeColor padding_16">
<div class="back">
<i class="iconfont icon-back1"></i>
<span>${title}</span>
</div>
<div class="right_action">
${right_action}
</div>
</div>
`);
$(".pub_header .icon-back1").click(() => history.back())
if ($(".icon-home").length != 0) {
$(".icon-home").click(() => location.href = "./index.html" )
}
}
initPhotoSwipeFromDOM(gallerySelector) {
// parse slide data (url, title, size ...) from DOM elements
// (children of gallerySelector)
var parseThumbnailElements = function(el) {
var thumbElements = el.childNodes,
numNodes = thumbElements.length,
items = [],
figureEl,
linkEl,
size,
item;
for(var i = 0; i < numNodes; i++) {
figureEl = thumbElements[i]; // <figure> element
// include only element nodes
if(figureEl.nodeType !== 1) {
continue;
}
linkEl = figureEl.children[0]; // <a> element
size = linkEl.getAttribute('data-size').split('x');
// create slide object
item = {
src: linkEl.getAttribute('href'),
w: parseInt(size[0], 10),
h: parseInt(size[1], 10)
};
if(figureEl.children.length > 1) {
// <figcaption> content
item.title = figureEl.children[1].innerHTML;
}
if(linkEl.children.length > 0) {
// <img> thumbnail element, retrieving thumbnail url
item.msrc = linkEl.children[0].getAttribute('src');
}
item.el = figureEl; // save link to element for getThumbBoundsFn
items.push(item);
}
return items;
};
// find nearest parent element
var closest = function closest(el, fn) {
return el && ( fn(el) ? el : closest(el.parentNode, fn) );
};
// triggers when user clicks on thumbnail
var onThumbnailsClick = function(e) {
e = e || window.event;
e.preventDefault ? e.preventDefault() : e.returnValue = false;
var eTarget = e.target || e.srcElement;
// find root element of slide
var clickedListItem = closest(eTarget, function(el) {
return (el.tagName && el.tagName.toUpperCase() === 'FIGURE');
});
if(!clickedListItem) {
return;
}
// find index of clicked item by looping through all child nodes
// alternatively, you may define index via data- attribute
var clickedGallery = clickedListItem.parentNode,
childNodes = clickedListItem.parentNode.childNodes,
numChildNodes = childNodes.length,
nodeIndex = 0,
index;
for (var i = 0; i < numChildNodes; i++) {
if(childNodes[i].nodeType !== 1) {
continue;
}
if(childNodes[i] === clickedListItem) {
index = nodeIndex;
break;
}
nodeIndex++;
}
if(index >= 0) {
// open PhotoSwipe if valid index found
openPhotoSwipe( index, clickedGallery );
}
return false;
};
// parse picture index and gallery index from URL (#&pid=1&gid=2)
var photoswipeParseHash = function() {
var hash = window.location.hash.substring(1),
params = {};
if(hash.length < 5) {
return params;
}
var vars = hash.split('&');
for (var i = 0; i < vars.length; i++) {
if(!vars[i]) {
continue;
}
var pair = vars[i].split('=');
if(pair.length < 2) {
continue;
}
params[pair[0]] = pair[1];
}
if(params.gid) {
params.gid = parseInt(params.gid, 10);
}
return params;
};
var openPhotoSwipe = function(index, galleryElement, disableAnimation, fromURL) {
var pswpElement = document.querySelectorAll('.pswp')[0],
gallery,
options,
items;
items = parseThumbnailElements(galleryElement);
// define options (if needed)
options = {
// define gallery index (for URL)
galleryUID: galleryElement.getAttribute('data-pswp-uid'),
getThumbBoundsFn: function(index) {
console.log(items[index])
// See Options -> getThumbBoundsFn section of documentation for more info
var thumbnail = items[index].el.getElementsByTagName('img')[0], // find thumbnail
pageYScroll = window.pageYOffset || document.documentElement.scrollTop,
rect = thumbnail.getBoundingClientRect();
return {x:rect.left, y:rect.top + pageYScroll, w:rect.width};
}
};
// PhotoSwipe opened from URL
if(fromURL) {
if(options.galleryPIDs) {
// parse real index when custom PIDs are used
// http://photoswipe.com/documentation/faq.html#custom-pid-in-url
for(var j = 0; j < items.length; j++) {
if(items[j].pid == index) {
options.index = j;
break;
}
}
} else {
// in URL indexes start from 1
options.index = parseInt(index, 10) - 1;
}
} else {
options.index = parseInt(index, 10);
}
// exit if index not found
if( isNaN(options.index) ) {
return;
}
if(disableAnimation) {
options.showAnimationDuration = 0;
}
// Pass data to PhotoSwipe and initialize it
gallery = new PhotoSwipe( pswpElement, PhotoSwipeUI_Default, items, options);
gallery.init();
};
// loop through all gallery elements and bind events
var galleryElements = document.querySelectorAll( gallerySelector );
for(var i = 0, l = galleryElements.length; i < l; i++) {
galleryElements[i].setAttribute('data-pswp-uid', i+1);
galleryElements[i].onclick = onThumbnailsClick;
}
// Parse URL and open gallery if it contains #&pid=3&gid=1
var hashData = photoswipeParseHash();
if(hashData.pid && hashData.gid) {
openPhotoSwipe( hashData.pid , galleryElements[ hashData.gid - 1 ], true, true );
}
}
get_storage(name) {
return JSON.parse(localStorage.getItem(name))
}
set_storage(name, value) {
localStorage.setItem(name, JSON.stringify(value))
}
}
var {
footer, query,
item, pHeader,
initPhotoSwipeFromDOM, get_storage,
set_storage
} = new Utils();