mirror of
https://github.com/NaiboWang/EasySpider.git
synced 2025-04-23 01:29:20 +08:00
525 lines
17 KiB
HTML
525 lines
17 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<script src="jquery-3.4.1.min.js"></script>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport"
|
|
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
|
<script src="bootstrap/js/bootstrap.js"></script>
|
|
<link rel="stylesheet" href="bootstrap/css/bootstrap.css"></link>
|
|
<title>设计流程</title>
|
|
<style>
|
|
@font-face {
|
|
font-family: 'Glyphicons Halflings';
|
|
src: url('bootstrap/fonts/glyphicons-halflings-regular.eot');
|
|
src: url('bootstrap/fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('bootstrap/fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
|
|
}
|
|
* {
|
|
margin: 0;
|
|
padding: 0;
|
|
font-size: 17px!important;
|
|
}
|
|
|
|
div.node {
|
|
height: 45px;
|
|
width: 120px;
|
|
border-radius: 7px;
|
|
border:skyblue solid;
|
|
background: rgb(73, 156, 189);
|
|
color:white;
|
|
text-align: center;
|
|
padding: 5px;
|
|
margin: 10px auto;
|
|
}
|
|
.arrow
|
|
{
|
|
margin: 10px auto;
|
|
text-align: center;
|
|
font-size: 23px!important;
|
|
color:black;
|
|
}
|
|
.arrow:hover
|
|
{
|
|
background-color: deepskyblue;
|
|
cursor: pointer;
|
|
color:white;
|
|
}
|
|
.branchAdd
|
|
{
|
|
margin: 10px auto;
|
|
text-align: center;
|
|
font-size: 18px!important;
|
|
color:black;
|
|
}
|
|
.branchAdd:hover
|
|
{
|
|
background-color: deepskyblue;
|
|
cursor: pointer;
|
|
color:white;
|
|
}
|
|
div.node:hover {
|
|
cursor: pointer;
|
|
background:navy;
|
|
}
|
|
|
|
.loop
|
|
{
|
|
border:skyblue solid;
|
|
text-align: center;
|
|
padding: 5px;
|
|
width:80%;
|
|
margin: 10px auto;
|
|
border-radius: 7px;
|
|
}
|
|
.judge
|
|
{
|
|
display:flex;
|
|
text-align: center;
|
|
padding: 5px;
|
|
width:100%;
|
|
margin: 10px auto;
|
|
justify-content: center;
|
|
border-radius: 7px;
|
|
}
|
|
.branch
|
|
{
|
|
margin: 5px;
|
|
border:skyblue solid;
|
|
text-align: center;
|
|
padding: 5px;
|
|
width:200px;
|
|
min-width: 100px;
|
|
margin: 10px;
|
|
border-radius: 7px;
|
|
}
|
|
.sequence
|
|
{
|
|
display: block;
|
|
}
|
|
.toolbox button{
|
|
margin-top: 5px;
|
|
margin-left: 3px;
|
|
margin-bottom: 5px;
|
|
width:80%;
|
|
font-size:15px!important;
|
|
}
|
|
.cancel:focus
|
|
{
|
|
box-shadow: none;
|
|
}
|
|
</style>
|
|
|
|
</head>
|
|
<body>
|
|
<div style="display:flex">
|
|
<div style="width: 200px;float:left">
|
|
<div class="toolbox" style="text-align:center;margin: 20px;border-radius:10px;border:navy solid;background-color:rgb(242,243,245);z-index: 9999;">
|
|
<div style="padding: 10px;border-radius:10px;font-size: 20px;">工具箱</div>
|
|
|
|
<button type="button" data = 1 class="btn btn-xs btn-outline-primary openPage">打开网页</button>
|
|
<button type="button" data = 2 class="btn btn btn-outline-primary openPage">点击元素</button>
|
|
<button type="button" data = 3 class="btn btn btn-outline-primary openPage">提取数据</button>
|
|
<button type="button" data = 4 class="btn btn btn-outline-primary openPage">输入文字</button>
|
|
<button type="button" data = 5 class="btn btn btn-outline-primary openPage">识别验证码</button>
|
|
<button type="button" data = 6 class="btn btn btn-outline-primary openPage">切换下拉选项</button>
|
|
<button type="button" data = 7 class="btn btn btn-outline-primary openPage">移动到元素</button>
|
|
<button type="button" data = 8 class="btn btn btn-outline-primary openPage">循环</button>
|
|
<button type="button" data = 9 class="btn btn btn-outline-primary openPage">判断条件</button>
|
|
<div>-----------------</div>
|
|
<button type="button" data = 10 class="btn btn btn-outline-primary openPage">剪切当前元素</button>
|
|
<button type="button" data = 11 class="btn btn btn-outline-primary openPage">复制当前元素</button>
|
|
<button type="button" data = 12 class="btn btn btn-outline-primary openPage">删除当前元素</button>
|
|
<button type="button" data = 0 class="btn btn btn-outline-primary openPage cancel">取消操作</button>
|
|
<div>-----------------</div>
|
|
<div style="text-align: left;margin: 10px;font-size:15px!important">提示:点击上方操作按钮后点击要添加/剪切/复制的位置处的箭头,可按取消操作按钮取消。</div>
|
|
</div>
|
|
</div>
|
|
<div style="margin-top:20px;border: solid;height:850px;overflow: auto;width:85%;float:right;min-width:800px">
|
|
<div id="0" >
|
|
</div>
|
|
<div style="border-radius: 50%;width: 40px;height: 40px;border:solid black;margin: 5px auto;background-color:lightcyan">
|
|
<p style="font-size: 29px!important;text-align: center;margin-left: 1px;margin-top: -6px;">■</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|
|
<script>
|
|
|
|
var first = {
|
|
id:0,
|
|
parentId:0,
|
|
type:0,
|
|
title:"打开网页1",
|
|
sequence:[]
|
|
};
|
|
var second = {
|
|
id:0,
|
|
parentId:0,
|
|
type:0,
|
|
title:"点击元素2",
|
|
sequence:[]
|
|
};
|
|
|
|
var fourth = {
|
|
id:0,
|
|
parentId:0,
|
|
type:0,
|
|
title:"关闭网页4",
|
|
sequence:[]
|
|
};
|
|
var fifth = {
|
|
id:0,
|
|
parentId:0,
|
|
type:0,
|
|
title:"提取数据5",
|
|
sequence:[]
|
|
};
|
|
var seventh = {
|
|
id:0,
|
|
parentId:0,
|
|
type:0,
|
|
title:"提取数据7",
|
|
sequence:[]
|
|
};
|
|
var sixth = {
|
|
id:0,
|
|
parentId:0,
|
|
type:1,
|
|
title:"循环操作6",
|
|
sequence:[seventh]
|
|
};
|
|
var n1 = {
|
|
id:0,
|
|
parentId:0,
|
|
type:1,
|
|
title:"循环操作",
|
|
sequence:[fifth]
|
|
};
|
|
var n2 = {
|
|
id:0,
|
|
parentId:0,
|
|
type:0,
|
|
title:"node5",
|
|
sequence:[]
|
|
};
|
|
var n3 = {
|
|
id:0,
|
|
parentId:0,
|
|
type:3, //判断分支
|
|
title:"判断分支1",
|
|
sequence:[]
|
|
};
|
|
var n4 = {
|
|
id:0,
|
|
parentId:0,
|
|
type:3,
|
|
title:"判断分支2",
|
|
sequence:[]
|
|
};
|
|
var n6 = {
|
|
id:0,
|
|
parentId:0,
|
|
type:0,
|
|
title:"正常操作",
|
|
sequence:[]
|
|
};
|
|
|
|
var n5 = {
|
|
id:0,
|
|
parentId:0,
|
|
type:3,
|
|
title:"判断分支3",
|
|
parameters:{
|
|
"pdtype":0,//判断的5种类型
|
|
"value":"",
|
|
},//所有操作的参数都放在这里,这个参数是顺序执行的条件
|
|
sequence:[n6]
|
|
};
|
|
var pd = {
|
|
id:0,
|
|
parentId:0,
|
|
type:2,
|
|
title:"判断操作",
|
|
parameters:{},
|
|
sequence:[n3,n4,n5]//执行的时候按照顺序检测一遍第一个满足条件的语句然后压栈执行
|
|
};
|
|
var third = {
|
|
id:0,
|
|
parentId:0,
|
|
type:1,
|
|
title:"循环操作3",
|
|
sequence:[n2,n1,pd]
|
|
};
|
|
|
|
var root = {
|
|
id:0,
|
|
parentId:0,
|
|
type:-1,
|
|
title:"root",
|
|
sequence:[second,sixth,fourth,third,first]
|
|
};
|
|
var queue = new Array();
|
|
var actionSequence = new Array();
|
|
var nowNode = null;//存储现在所在的节点
|
|
var lastNode = null;
|
|
// 根据元素类型返回不同元素的样式
|
|
function newNode(node)
|
|
{
|
|
id = node["id"];
|
|
title = node["title"];
|
|
type = node["type"];
|
|
if(type==0) //顺序
|
|
{
|
|
return `<div class="sequence"><div class="node clk" data="${id}" id = "${id}" position=${node["position"]} pId=${node["parentId"]}>
|
|
<div >
|
|
<p>${title}</p>
|
|
</div>
|
|
</div>
|
|
<p class="arrow" position=${node["position"]} data = "${id}" pId=${node["parentId"]}>↓</p></div>`;
|
|
}
|
|
else if(type==1) //循环
|
|
{
|
|
return `<div class="loop clk" data="${id}" id = "${id}" position=${node["position"]} pId=${node["parentId"]}>
|
|
<p style="background:#d6d6d6;text-align:left;padding:2px">${title}</p>
|
|
<p class="arrow" position=-1 data = "${id}" pId=${id}>↓</p>
|
|
</div>
|
|
<p class="arrow" data = "${id}" position=${node["position"]} pId=${node["parentId"]}>↓</p></div>`;
|
|
}
|
|
else if(type==2) //判断
|
|
{
|
|
return `<div class="loop clk" data="${id}" position=${node["position"]} pId=${node["parentId"]}>
|
|
<p style="background:#d6d6d6;text-align:left;padding:2px">${title}</p>
|
|
<p class="branchAdd" data="${id}">点击此处在最左边增加条件分支</p>
|
|
<div class="judge" id = "${id}">
|
|
</div></div>
|
|
<p class="arrow" data = "${id}" position=${node["position"]} pId=${node["parentId"]}>↓</p></div>`;
|
|
}
|
|
else //判断分支
|
|
{
|
|
return `<div class="branch clk" data="${id}" position=${node["position"]} pId=${node["parentId"]}>
|
|
<p style="background:#d6d6d6;text-align:left;padding:2px">${title}</p>
|
|
<p data = "${id}" class="arrow" position=-1 pId=${id}>↓</p>
|
|
<div id = "${id}">
|
|
</div></div>`;
|
|
}
|
|
}
|
|
//增加分支点击事件
|
|
function branchClick(e)
|
|
{
|
|
let judgeId = this.getAttribute('data');
|
|
var t = {
|
|
id:0,
|
|
parentId:0,
|
|
type:3,
|
|
option:12,
|
|
title:"条件分支",
|
|
sequence:[]
|
|
};
|
|
actionSequence[judgeId]["sequence"].splice(0,0,t);
|
|
refresh();
|
|
e.stopPropagation();//防止冒泡
|
|
}
|
|
//元素点击事件
|
|
function elementClick(e)
|
|
{
|
|
let title = this.getAttribute('data');
|
|
if(nowNode != null)
|
|
{
|
|
nowNode.style.borderColor="skyblue";
|
|
}
|
|
nowNode = this;
|
|
this.style.borderColor="blue";
|
|
e.stopPropagation();//防止冒泡
|
|
}
|
|
var option = 0;//选择要增加的内容
|
|
var title = "";
|
|
//箭头点击事件
|
|
function arrowClick(e)
|
|
{
|
|
if(option==10)
|
|
{
|
|
console.log(nowNode);
|
|
if(nowNode==null)
|
|
{
|
|
e.stopPropagation();//防止冒泡
|
|
}
|
|
else if($(nowNode).is(".branch"))
|
|
{
|
|
alert("判断分支不可移动!");
|
|
e.stopPropagation();//防止冒泡
|
|
}
|
|
else
|
|
{
|
|
let position = parseInt(nowNode.getAttribute('position'));
|
|
let pId = nowNode.getAttribute('pId');
|
|
var position2 = parseInt(this.getAttribute('position'));
|
|
var pId2 = this.getAttribute('pId');
|
|
var id = nowNode.getAttribute('data');
|
|
var pidt = pId2;
|
|
var move = true;
|
|
console.log(pidt,id);
|
|
while(pidt!=0)
|
|
{
|
|
if(pidt==id)
|
|
{
|
|
move=false;
|
|
break;
|
|
}
|
|
pidt = actionSequence[pidt]["parentId"];
|
|
}
|
|
if(move) //如果自己要移动到自己节点里就不允许移动
|
|
{
|
|
let element = actionSequence[pId]["sequence"].splice(position,1);//在相应位置删除元素
|
|
if(pId==pId2 && position<position2) //如果要移动的位置属于同一层并且是从前往后移动,注意需要控制数组插入位置向前错位
|
|
{
|
|
position2--;
|
|
}
|
|
console.log(element);
|
|
actionSequence[pId2]["sequence"].splice(position2+1,0,element[0]);//在相应位置添加新元素
|
|
refresh();//重新渲染页面
|
|
}
|
|
else
|
|
{
|
|
alert("自己不能移动到自己的节点里!");
|
|
}
|
|
e.stopPropagation();//防止冒泡
|
|
}
|
|
}
|
|
else if(option>0)
|
|
{
|
|
var t = {
|
|
id:0,
|
|
parentId:0,
|
|
type:0,
|
|
option:option,
|
|
title:title,
|
|
sequence:[]
|
|
};
|
|
if(option == 8)//循环
|
|
{
|
|
t["type"]=1;
|
|
}
|
|
else if(option==9)//判断
|
|
{
|
|
t["type"]=2;
|
|
// 增加两个分支
|
|
var nt=
|
|
{
|
|
id:0,
|
|
parentId:0,
|
|
type:3,
|
|
option:option,
|
|
title:"条件分支",
|
|
sequence:[]
|
|
};
|
|
var nt2=
|
|
{
|
|
id:0,
|
|
parentId:0,
|
|
type:3,
|
|
option:option,
|
|
title:"条件分支",
|
|
sequence:[]
|
|
};
|
|
t["sequence"].push(nt);
|
|
t["sequence"].push(nt2);
|
|
}
|
|
let position = parseInt(this.getAttribute('position'));
|
|
let pId = this.getAttribute('pId');
|
|
actionSequence[pId]["sequence"].splice(position+1,0,t);//在相应位置添加新元素
|
|
refresh();//重新渲染页面
|
|
e.stopPropagation();//防止冒泡
|
|
}
|
|
option = 0;
|
|
}
|
|
$(".openPage").click(function(){
|
|
option = this.getAttribute("data");
|
|
title = this.innerHTML;
|
|
if(option>=10 && nowNode==null)
|
|
{
|
|
alert("目前未选中元素");
|
|
}
|
|
else if(option==12)
|
|
{
|
|
deleteElement();
|
|
}
|
|
|
|
});
|
|
|
|
function bindEvents()
|
|
{
|
|
// 清空原来的listener然后再添加新的listener
|
|
let rect = document.getElementsByClassName('clk');
|
|
for (let i = 0, rule; rule = rect[i++];) {
|
|
rule.removeEventListener('click',elementClick);
|
|
rule.addEventListener('click',elementClick);
|
|
}
|
|
let arr = document.getElementsByClassName('arrow');
|
|
for (let i = 0, rule; rule = arr[i++];) {
|
|
rule.removeEventListener('click',arrowClick);
|
|
rule.addEventListener('click',arrowClick);
|
|
}
|
|
let branch = document.getElementsByClassName('branchAdd');
|
|
for (let i = 0, rule; rule = branch[i++];) {
|
|
rule.removeEventListener('click',branchClick);
|
|
rule.addEventListener('click',branchClick);
|
|
}
|
|
}
|
|
//重新画图
|
|
function refresh()
|
|
{
|
|
$("#0").empty();
|
|
$("#0").append(`<div style="border-radius: 50%;width: 40px;height: 40px;border:solid;border-color:seagreen;margin:5px auto;background-color:lightcyan;margin-top:20px">
|
|
<p style="font-size: 24px!important;text-align: center;margin-left: 6px;font-family:'Times New Roman'">▶</p>
|
|
</div>
|
|
<p id="testAdd" class="arrow" position=-1 pId=0>↓</p>`);
|
|
actionSequence.splice(0);
|
|
queue.splice(0);
|
|
var idd = 1;
|
|
queue.push(root);
|
|
actionSequence.push(root);
|
|
while(queue.length!=0)
|
|
{
|
|
var nd = queue.shift();
|
|
for(i = 0;i<nd.sequence.length;i++)
|
|
{
|
|
nd.sequence[i].parentId = nd.id;
|
|
nd.sequence[i]["position"] = i;
|
|
nd.sequence[i].id = idd++;
|
|
queue.push(nd.sequence[i]);
|
|
actionSequence.push(nd.sequence[i]);
|
|
}
|
|
}
|
|
console.log(actionSequence);
|
|
//第一个元素不渲染
|
|
for(i=1;i<actionSequence.length;i++)
|
|
{
|
|
parentId = actionSequence[i]["parentId"];
|
|
$("#"+parentId).append(newNode(actionSequence[i]));
|
|
}
|
|
bindEvents();
|
|
}
|
|
function deleteElement()
|
|
{
|
|
let position = parseInt(nowNode.getAttribute('position'));
|
|
let pId = nowNode.getAttribute('pId');
|
|
actionSequence[pId]["sequence"].splice(position,1);//在相应位置删除元素
|
|
refresh();//重新渲染页面
|
|
e.stopPropagation();//防止冒泡
|
|
}
|
|
document.oncontextmenu=function(){return false;}//屏蔽右键菜单
|
|
//删除元素
|
|
document.onkeydown = function (e)
|
|
{
|
|
if(nowNode!=null && e.keyCode == 46)
|
|
{
|
|
if(confirm("确定要删除元素吗?"))
|
|
{
|
|
deleteElement();
|
|
}
|
|
}
|
|
}
|
|
refresh();
|
|
</script> |