/*
影子系统
可以在前台修改 文字 和 页面图片
需要引入jquery
*/
function shadow(){
this.loginstate = 'no';
}
//登录验证模块
shadow.prototype.checklogin = function(){
var url = this.url('loginstate');
var data = {};
var promise = this.senddata(url, data);
promise.done((response) => {
this.loginstate = response.data;
this.menu();
});
}
//菜单模块
shadow.prototype.menu = function(){
if(this.loginstate == 'yes'){
this.$menu.show();
this.$client.show();
}else{
this.$menu.hide();
this.$client.hide();
}
}
//界面模块
shadow.prototype.ui = function(element){
if(this.state.uiisshow == false){
this.$ui.show();
if(element){
var $mark = $(element);
var index = $mark.attr('data-shadowindex');
var $edititem = this.$editlist[index];
var html = $edititem.html();
html = html.replace(/(^\s+)|(
/g, "\r\n");
this.state.curindex = index;
this.$ui.$text.val(html);
}
this.state.uiisshow = true;
}else{
this.$ui.hide();
this.state.uiisshow = false;
}
}
//标记模块
shadow.mark = function(){
if(this.prototype.state.marked){
this.prototype.$marklist.hide();
}else{
if(this.prototype.$marklist){
this.prototype.$marklist.show();
}else{
//获取所有可编辑元素
var $list = $('[data-shadow]');
//添加标记
var editlist = [], offset, $mark, $item;
var me = this;
var mainindex = 0;
$list.each(function(key, item){
var $item = $(item);
var offset = $item.offset();
var w = $item.width();
var h = $item.height();
$mark = $('
').css({
'position': 'absolute',
'left': parseint(offset.left) + 'px',
'top': parseint(offset.top) + 'px',
'width': w + 'px',
'height': h + 'px',
'background': 'rgba(0,0,0,0.4)',
'z-index': '9999992',
'cursor': 'pointer',
'border': '2px dashed rgba(0,0,0,0.5)',
'border-radius': '5px',
'box-sizing': 'border-box',
'box-shadow': '#bbc 0px 0px 7px 0px'
}).addclass('shadow-mark').attr({
'data-shadowindex': key
}).appendto('body');
//计算元素在模板中的索引
if(!$item.attr('data-from')){
$mark.attr('data-subindex', mainindex).attr('data-subindexorigin', mainindex);
mainindex++;
}else{
var frompage = $item.attr('data-from');
if(!me.prototype.state.includefiletagcount[frompage]){
me.prototype.state.includefiletagcount[frompage] = 0;
}
$mark.attr('data-subindex', me.prototype.state.includefiletagcount[frompage]);
$mark.attr('data-subindexorigin', me.prototype.state.includefiletagcount[frompage]);
me.prototype.state.includefiletagcount[frompage]++;
}
if($item.attr('data-group')){
var groupname = $item.attr('data-group');
$mark.attr({
'data-group': 'mark_' + $item.attr('data-group'),
'data-trueindex': key
});
if($item.attr('data-hide') === 'yes'){
$mark.attr('data-hide', 'yes').css('display', 'none');
}
//记录group的名称、索引
if(!me.prototype.state.groupmarkindex[groupname]){
me.prototype.state.groupmarkindex[groupname] = 0;
}
}
editlist.push($item);
});
//缓存可编辑元素和标记元素
this.prototype.$editlist = editlist;
this.prototype.$marklist = $('.shadow-mark');
//绑定事件
this.prototype.$marklist.on('click', function(event){
shadow.prototype.ui(event.target);
});
}
}
//更新状态
this.prototype.state.marked = !this.prototype.state.marked;
//更新分组中标记元素的尺寸、位置
this.prototype.resetgroupitemsdisplay();
}
//数据发送模块
shadow.prototype.senddata = function(url, data){
return $.ajax({
url: url,
data: data,
datatype: 'json',
type: 'post'
});
}
//当页面中多个可编辑元素处于重叠状态时,则通过data-group来分组
shadow.prototype.updateshadowindex = function(groupname, i){
//记录group的名称、索引
this.state.groupmarkindex[groupname] = i;
this.resetgroupitemsdisplay(groupname);
}
/*
当页面中多个可编辑元素处于重叠状态时,
通过重新计算编辑目标元素的尺寸、位置来更新标记元素。
通过改变同一分组内标记元素的可见性来实现编辑不同的元素
*/
shadow.prototype.resetgroupitemsdisplay = function(groupname){
if(!this.state.marked){ return; }
var grouplist = this.state.groupmarkindex;
if(groupname){
grouplist = {};
grouplist[groupname] = this.state.groupmarkindex[groupname];
}
var key, index, i, max;
var $alllist, $list, $item, $target;
var offset, count, showstart, showend, w, h, x, y;
for(key in grouplist){
index = grouplist[key];
//获取group内的所有元素、过滤出可见元素
$alllist = $('[data-group="mark_'+ key +'"]');
$list = $.map($alllist, function(item){
if($(item).attr('data-hide') !== 'yes'){
return item;
}
});
//计算偏移区间
offset = $list.length * index;
count = $list.length;
showstart = offset;
showend = offset + count;
//对group中的所有元素进行处理
for(i = 0, max = $alllist.length; i < max; i++){
$item = $alllist.eq(i);
//如果在可见区间内则更新尺寸、位置,并显示出来
if(showstart <= i && i < showend){
$target = $('[data-shadow]:eq('+ $item.attr('data-shadowindex') +')');
w = $target.width();
h = $target.height();
x = $target.offset().left;
y = $target.offset().top;
$alllist.eq(i).css({
width: w + 'px',
height: h + 'px',
left: x + 'px',
top: y + 'px'
}).show();
}
//否则,则隐藏起来
else{
$alllist.eq(i).hide();
}
}
}
}
//元素更新模块
shadow.prototype.updatehtml = function(){
var $item = this.$editlist[this.state.curindex];
var infotype = $item.attr('data-shadow');
var $mark = $(this.$marklist[this.state.curindex]);
//文字
if(infotype == 'text'){
var url = this.url('edittemplate');
var newhtml = this.$ui.$text.val();
var frompage = $item.attr('data-from') || '';
var data = {
'itemindex': $mark.attr('data-subindex'),
'infotype': infotype,
'html': newhtml,
'pageurl': this.state.pageurl,
'tag': $item[0].tagname,
'useragent': this.state.useragent,
'frompage': frompage
};
var promise = this.senddata(url, data);
promise.done(function(response){
if(response.state == 'success'){
$item.html(response.html);
shadow.mark();
}else{
alert('抱歉,更新失败');
}
});
}
this.ui();
}
//客户端模式切换(即电脑版和手机版切换)
shadow.clientswitch = function(){
this.changeurl(this.prototype.state.useragent);
}
shadow.changeurl = function(useragent){
var domain = document.location.origin;
var pathname = document.location.pathname.replace(/[\/\s]+$/, '').replace(/^\//, '');
var path = pathname == '' ? [] : pathname.split('/');
var action = 'index';
var module = 'index';
var url = domain;
var i = j = 0, max = path.length;
var params = {};
for(; i < max; i++){
if(path[i] == 'index.php'){
break;
}
}
for(; j < i; j++){
url += '/' + path[j];
}
//伪静态模式(即省略index.php)
if(i === max){
useragent = useragent == 'pc' ? 'mobile' : 'pc';
url += '?useragent=' + useragent;
location.href = url;
return;
}
//pathinfo模式
else{
url += '/index.php';
if(max - i > 2){
i++;
module = path[i];
i++;
action = path[i];
i++
for(; i< max; i=i+2){
params[path[i]] = path[i+1] || '';
}
}
url += '/' + module + '/' + action;
}
url = url.replace(/\.html$/, '');
if(useragent == 'pc'){
params.useragent = 'mobile';
}else{
params.useragent = 'pc';
}
for(var key in params){
url += '/' + key + '/' + params[key];
}
location.href = url;
}
shadow.getclient = function(){
var href = location.href;
var agentkey = /\buseragent[\/=](\w+)\b/i;
var match = agentkey.exec(href);
if(match != null && match.length == 2){
this.prototype.state.useragent = match[1];
}else{
var useragentinfo = window.navigator.useragent;
var agents = ["android", "iphone", "symbianos", "windows phone", "ipad", "ipod"];
for(var i = 0; i < agents.length; i++){
if(useragentinfo.indexof(agents[i]) > 0){
this.prototype.state.useragent = 'mobile';
break;
}
}
}
}
//===============================================私有模块
//获取根路径
shadow.prototype.getroot = function(){
var root = document.location.href;
root = root.replace(/\.html$/, '');
root = root.replace(document.location.search, '');
if(root.indexof('index.php') !== -1){
root = root.split('index.php');
}else if(root.indexof('index') !== -1){
root = root.split('index');
}else{
root = [root];
}
return root[0] + '';
}
//获取api地址
shadow.prototype.url = function(url){
var urllist = {
'loginstate': 'admin.php/api/loginstate',
'edittemplate': 'admin.php/api/edittemplate'
};
return this.root + (urllist[url] || '');
}
//初始化
shadow.init = function(){
//判断是否引入jquery
if(window.jquery == undefined){
var script = document.createelement('script');
script.onload = function(){
shadow.init();
}
script.src = shadow.prototype.getroot() + 'public/js/jquery.js';
document.body.appendchild(script);
return;
}
//创建菜单、界面
shadow.prototype.$menu = $('
编辑
模式
');
shadow.prototype.$client = $('
版式
切换
');
shadow.prototype.$ui = $('
');
//创建公用数据
shadow.prototype.root = shadow.prototype.getroot();
shadow.prototype.$editlist = null;
shadow.prototype.$marklist = null;
shadow.prototype.state = {
uiisshow: false,
marked: false,
curindex: -1,
pageurl: document.location.pathname + document.location.search,
useragent: 'pc',
includefiletagcount: {},
groupmarkindex: {}
};
//检测登录状态
var me = new this();
me.checklogin();
//初始化菜单
shadow.prototype.$menu.css({
'position': 'fixed',
'left': '20px',
'bottom': '20px',
'background': 'rgba(0,0,0,0.7)',
'width': '70px',
'height': '70px',
'text-align': 'center',
'box-sizing': 'border-box',
'line-height': '1.5em',
'padding-top': '8px',
'border': '1px solid rgba(0,0,0,0.8)',
'border-radius': '50%',
'font-size': '16px',
'font-family': '微软雅黑',
'opacity': '0.9',
'color': '#fff',
'z-index': '9999993',
'cursor': 'pointer',
'display': 'none'
}).click(function(){
shadow.mark();
}).appendto('body');
//初始化模式切换按钮
shadow.prototype.$client.css({
'position': 'fixed',
'left': '20px',
'bottom': '105px',
'background': 'rgba(0,0,0,0.7)',
'width': '70px',
'height': '70px',
'text-align': 'center',
'box-sizing': 'border-box',
'line-height': '1.5em',
'padding-top': '8px',
'border': '1px solid rgba(0,0,0,0.8)',
'border-radius': '50%',
'font-size': '16px',
'font-family': '微软雅黑',
'opacity': '0.9',
'color': '#fff',
'z-index': '9999993',
'cursor': 'pointer',
'display': 'none'
}).click(function(){
shadow.clientswitch();
}).appendto('body');
//初始化界面
var $ui = shadow.prototype.$ui.css({
'left': '0px',
'top': '0px',
'bottom': '0px',
'right': '0px',
'width': '100%',
'height': $('body').height(),
'position': 'absolute',
'display': 'none'
});
var $cover = shadow.prototype.$ui.$cover = $('
').css({
'position': 'absolute',
'left': '0px',
'right': '0px',
'top': '0px',
'bottom': '0px',
'z-index': '9999994',
'background': 'rgba(0,0,0,0.45)'
});
var $editor = shadow.prototype.$ui.$editor = $('
').css({
'position': 'fixed',
'left': '50%',
'top': '50%',
'width': '80%',
'transform': 'translate(-50%, -60%)',
'max-width': '600px',
'text-align':'center',
'padding': '10px 0 15px',
'background': '#eee',
'border-radius': '5px',
'z-index': '9999995'
});
var $text = shadow.prototype.$ui.$text = $('
').css({
'width': '95%',
'height': '300px',
'margin': '0 auto',
'margin-bottom': '15px',
'padding': '2px 4px',
'border': '1px solid #abadb3',
'border-radius': '4px'
});
var $okbtn = shadow.prototype.$ui.$okbtn = $('
').css({
'margin-right': '30px',
'padding': '3px 25px',
'border': '1px solid #707070',
'border-radius': '4px',
'cursor': 'pointer',
'background': '#dbdbdb linear-gradient(to bottom, #f2f2f2 0%, #e6e6e6 45%, #ddd 55%, #cfcfcf 100%)'
});
var $cancelbtn = shadow.prototype.$ui.$cancelbtn = $('
').css({
'margin-right': '30px',
'padding': '3px 25px',
'border': '1px solid #707070',
'border-radius': '4px',
'cursor': 'pointer',
'background': '#dbdbdb linear-gradient(to bottom, #f2f2f2 0%, #e6e6e6 45%, #ddd 55%, #cfcfcf 100%)'
});
$cover.click(function(){
shadow.prototype.ui();
});
$cancelbtn.click(function(){
shadow.prototype.ui();
});
$okbtn.click(function(){
shadow.prototype.updatehtml();
});
$editor.append($text, $okbtn, $cancelbtn);
$ui.append($cover, $editor).appendto('body');
//获取客户端信息
this.getclient();
}
shadow.init();