baozhuangscript.js 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. //表现层的处理
  2. if (window.location.href.indexOf("backEndAddressServiceWrapper") >= 0) {
  3. throw "serviceGrid"; //如果是服务器网页页面,则不执行工具
  4. }
  5. //返回element相对node节点的xpath,默认的node节点是: /
  6. function readXPath(element, type = 1, node = document.body) {
  7. try {
  8. if (type == 0) //type=0代表默认可通过id生成xpath type=1代表只能从根节点生成xpath, nodeList里必须使用绝对xpath!
  9. {
  10. if (element.id !== "") { //判断id属性,如果这个元素有id,则显示//*[@id="xPath"] 形式内容
  11. return '//*[@id=\"' + element.id + '\"]';
  12. }
  13. if (element.className != ""){ //如果有class且某个class name只有一个元素,则使用class name生成xpath
  14. console.log("class name: " + element.className);
  15. names = element.className.split(" ");
  16. for (var i = 0; i < names.length; i++) {
  17. if (names[i] != "") {
  18. // return '//*[@class=\"' + names[i] + '\"]';
  19. console.log('//*[@contains(@class, \"' + names[i] + '\")]');
  20. elements_of_class = node.getElementsByClassName(names[i]);
  21. console.log("Length of elements_of_class: " + elements_of_class.length);
  22. if(elements_of_class.length == 1){
  23. return '//*[contains(@class, \"' + names[i] + '\")]'
  24. }
  25. }
  26. }
  27. }
  28. }
  29. //这里需要需要主要字符串转译问题,可参考js 动态生成html时字符串和变量转译(注意引号的作用)
  30. if (element == node) { //递归到body处,结束递归
  31. if (node == document.body) {
  32. return '/html/' + element.tagName.toLowerCase();
  33. } else {
  34. return "";
  35. }
  36. }
  37. var ix = 1, //在nodelist中的位置,且每次点击初始化
  38. siblings = element.parentNode.childNodes; //同级的子元素
  39. for (var i = 0, l = siblings.length; i < l; i++) {
  40. var sibling = siblings[i];
  41. //如果这个元素是siblings数组中的元素,则执行递归操作;arguments.callee代表当前函数的名称
  42. if (sibling == element) {
  43. return readXPath(element.parentNode, type, node) + '/' + element.tagName.toLowerCase() + '[' + (ix) + ']';
  44. //如果不符合,判断是否是element元素,并且是否是相同元素,如果是相同的就开始累加
  45. } else if (sibling.nodeType == 1 && sibling.tagName == element.tagName) {
  46. //注意此处,为了防止多计算了插入的操作台的3个div元素导致定位错误,这里需要屏蔽掉三个元素的索引号
  47. if(sibling.id != "wrapperDiv" && sibling.id != "wrapperTdiv" &&sibling.id != "wrapperToolkit"){
  48. ix++;
  49. }
  50. }
  51. }
  52. } catch {
  53. return "/"
  54. }
  55. };
  56. //创造div作为选中元素后的样式存在
  57. var div = document.createElement('div');
  58. div.style.zIndex = -2147483647;
  59. div.setAttribute("id", "wrapperDiv");
  60. div.style.position = "fixed";
  61. div.style.boxSizing = "border-box";
  62. div.style.border = "dotted";
  63. var tdiv = document.createElement('div');
  64. tdiv.style.zIndex = 2147483647;
  65. tdiv.style.position = "fixed";
  66. tdiv.setAttribute("id", "wrapperTdiv");
  67. tdiv.classList = "tdiv";
  68. tdiv.style.top = "0px";
  69. tdiv.style.width = "3000px";
  70. tdiv.style.height = "3000px";
  71. tdiv.style.pointerEvents = "none";
  72. var mousemovebind = false; //如果出现元素默认绑定了mousemove事件导致匹配不到元素的时候,开启第二种模式获得元素
  73. var toolkit = document.createElement("div")
  74. toolkit.classList = "tooltips"; //添加样式
  75. toolkit.setAttribute("id", "wrapperToolkit");
  76. var tooltips = false; //标记鼠标是否在提示框上
  77. var defaultbgColor = 'rgba(221,221,255,0.8)'; //移动到元素的背景颜色
  78. var selectedColor = "rgba(151,255,255, 0.6)"; //选中元素的背景颜色
  79. var boxShadowColor = "blue 0px 0px 5px"; //待选元素的边框属性
  80. //右键菜单屏蔽
  81. document.oncontextmenu = () => false;
  82. var nodeList = []; //已被选中的节点列表
  83. var readyList = []; //预备选中的list
  84. var outputParameters = []; //输出参数列表
  85. var outputParameterNodes = []; //输出参数节点列表
  86. NowNode = null;
  87. var xnode = null;
  88. var step = 0; //记录这是第几次点击操作
  89. var style = ""; //记录上个元素的颜色
  90. document.addEventListener("mousemove", function() {
  91. if (mousemovebind) {
  92. tdiv.style.pointerEvents = "none";
  93. }
  94. //如果鼠标在元素框内则点击和选中失效
  95. var x = event.clientX;
  96. var y = event.clientY;
  97. var divx1 = toolkit.offsetLeft;
  98. var divy1 = toolkit.offsetTop;
  99. var divx2 = toolkit.offsetLeft + toolkit.offsetWidth;
  100. var divy2 = toolkit.offsetTop + toolkit.offsetHeight;
  101. if (x >= divx1 && x <= divx2 && y >= divy1 && y <= divy2) {
  102. tooltips = true;
  103. return;
  104. }
  105. oe = document.elementFromPoint(event.x, event.y);
  106. if (oe == tdiv) {
  107. return;
  108. }
  109. tooltips = false;
  110. NowNode = oe;
  111. te = 0;
  112. exist = 0;
  113. exist2 = 0;
  114. for (o of nodeList) {
  115. if (o["node"] == oe) {
  116. exist = 1;
  117. break;
  118. }
  119. }
  120. for (o of nodeList) {
  121. if (o["node"] == xnode) {
  122. exist2 = 1;
  123. break;
  124. }
  125. }
  126. // console.log(oe);
  127. if (xnode == null) {
  128. xnode = oe;
  129. }
  130. if (xnode != oe) {
  131. if (exist2 == 0) { //如果上个元素不在数组里,改回上个元素的初始颜色
  132. try {
  133. xnode.style.backgroundColor = style; //上个元素改回原来元素的背景颜色
  134. } catch {
  135. xnode.style.backgroundColor = ""; //上个元素改回原来元素的背景颜色
  136. }
  137. }
  138. try {
  139. style = oe.style.backgroundColor;
  140. } catch {
  141. style = "";
  142. }
  143. if (exist == 1) {
  144. } else {
  145. try {
  146. oe.style.backgroundColor = defaultbgColor; //设置新元素的背景元素
  147. } catch {}
  148. }
  149. xnode = oe;
  150. div.style.display = "none";
  151. }
  152. if (mousemovebind) {
  153. tdiv.style.pointerEvents = "";
  154. }
  155. });
  156. //点击没反应时候的替代方案
  157. document.onkeydown = function(event) {
  158. // console.log("keydown");
  159. var e = event || window.event || arguments.callee.caller.arguments[0];
  160. if (e && e.keyCode == 118) { // 按 F7
  161. addEl();
  162. } else if (e && e.keyCode == 119) { //按F8
  163. clearEl();
  164. } else if (e && e.keyCode == 120) { //按F9
  165. NowNode.focus();
  166. NowNode.click();
  167. // console.log("click",NowNode);
  168. } else {
  169. return event.keyCode;
  170. }
  171. };
  172. //选中元素到列表中
  173. function addEl() {
  174. // if (tooltips) {
  175. // return;
  176. // }
  177. let exist = false;
  178. for (o of nodeList) {
  179. if (o["node"] == oe) {
  180. exist = true;
  181. break;
  182. }
  183. }
  184. //元素没有被添加过才去添加
  185. if (!exist) {
  186. step++;
  187. exist = false; //判断刚加入的元素是否在readyList中,如果在,则将所有readylist中的元素全部放入list中
  188. for (o of readyList) {
  189. if (o["node"] == oe) {
  190. exist = true;
  191. break;
  192. }
  193. }
  194. if (exist) { //存在在readylist就全选中
  195. readyToList(step);
  196. if (app._data.selectedDescendents) {
  197. handleDescendents(); //如果之前有选中子元素,新加入的节点又则这里也需要重新选择子元素
  198. }
  199. } else //不然只添加一个元素
  200. {
  201. clearReady(); //readylist清零重新算
  202. nodeList.push({ node: NowNode, "step": step, bgColor: style, "boxShadow": NowNode.style.boxShadow == "" || boxShadowColor ? "none" : NowNode.style.boxShadow, xpath: readXPath(NowNode, 1) });
  203. NowNode.style.backgroundColor = selectedColor;
  204. }
  205. handleElement(); //处理新状态
  206. //将虚线框显示在元素上方但屏蔽其鼠标操作
  207. var pos = NowNode.getBoundingClientRect();
  208. div.style.display = "block";
  209. div.style.height = NowNode.offsetHeight + "px";
  210. div.style.width = NowNode.offsetWidth + "px";
  211. div.style.left = pos.left + "px";
  212. div.style.top = pos.top + "px";
  213. div.style.zIndex = 2147483645;
  214. div.style.pointerEvents = "none";
  215. }
  216. // console.log("------");
  217. // for (i = 0; i < nodeList.length; i++) {
  218. // console.log(nodeList[i]["xpath"]);
  219. // }
  220. //对于可点击元素,屏蔽a标签默认点击事件
  221. event.stopImmediatePropagation();
  222. event.stopPropagation();
  223. event.preventDefault ? event.preventDefault() : event.returnValue = false;
  224. }
  225. document.addEventListener("mousedown", addEl);
  226. toolkit.addEventListener("mousedown", function(e) { e.stopPropagation(); }); //重新定义toolkit里的点击事件
  227. //清除选择项
  228. function clearEl() {
  229. //如果最后停留的元素被选中,则调整此元素的style为原始style,否则不进行调整
  230. for (node of nodeList) {
  231. node["node"].style.backgroundColor = node["bgColor"];
  232. node["node"].style.boxShadow = node["boxShadow"];
  233. if (NowNode == node["node"]) {
  234. style = node["bgColor"];
  235. }
  236. }
  237. step = 0;
  238. clearReady();
  239. clearParameters();
  240. nodeList.splice(0, nodeList.length); //清空数组
  241. app._data.option = 0; //选项重置
  242. app._data.page = 0; //恢复原始页面
  243. }
  244. //清除预备数组
  245. function clearReady() {
  246. for (node of readyList) //节点列表状态恢复原状
  247. {
  248. node["node"].style.boxShadow = node["boxShadow"];
  249. }
  250. readyList.splice(0, readyList.length); //清空数组
  251. }
  252. document.body.append(div); //默认如果toolkit不存在则div和tdiv也不存在
  253. document.body.append(tdiv);
  254. document.body.append(toolkit);
  255. var timer;