jiuye_index.html 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>就业服务</title>
  6. <style>
  7. html, body, div {
  8. width: 100%;
  9. height: 100%;
  10. margin: 0;
  11. padding: 0;
  12. overflow: hidden;
  13. }
  14. #loadingIndicator {
  15. position: fixed;
  16. top: 0;
  17. left: 0;
  18. width: 100%;
  19. height: 100%;
  20. display: flex;
  21. align-items: center;
  22. justify-content: center;
  23. background-color: white;
  24. z-index: 100;
  25. }
  26. .spinner {
  27. width: 50px;
  28. height: 50px;
  29. border: 3px solid rgba(0,0,0,0.1);
  30. border-radius: 50%;
  31. border-top-color: #007BFF;
  32. animation: spin 1s ease-in-out infinite;
  33. }
  34. @keyframes spin {
  35. to { transform: rotate(360deg); }
  36. }
  37. </style>
  38. </head>
  39. <body>
  40. <div id="loadingIndicator">
  41. <div class="spinner"></div>
  42. </div>
  43. <div>
  44. <iframe id="scmFrameMain" src="" style="width: 100%;height: 100%;overflow: hidden;border: 0; display: none;"></iframe>
  45. </div>
  46. <script type="text/javascript">
  47. // 配置参数
  48. const CONFIG = {
  49. topElementSelector: "#app > div > div.aws-portal.top-nav > section > section > header.el-header.public-header-border > div > div",
  50. navSelector: "#app > div > div.aws-portal.top-nav > section > section > header.el-header.top-nav-border > div > div > div > div.menu-box > ul",
  51. menuItems: [
  52. { text: "学校", id: "school" },
  53. { text: "单位", id: "company" },
  54. { text: "学生", id: "student" }
  55. ],
  56. timeout: 15000, // 全局超时时间(毫秒)
  57. checkInterval: 200 // 检查间隔(毫秒)
  58. };
  59. var uid = '<#uid>';
  60. var sid = '<#sid>';
  61. var url = '<#url>';
  62. window.onload = function() {
  63. const scmFrameMain = document.getElementById('scmFrameMain');
  64. scmFrameMain.src = url;
  65. // 等待iframe加载完成
  66. waitForIframeLoad(scmFrameMain)
  67. .then(modifyIframeContent)
  68. .then(showIframe)
  69. .catch(error => {
  70. console.error('初始化失败:', error);
  71. showIframe(); // 出错时也显示iframe
  72. });
  73. };
  74. // 显示iframe并隐藏加载指示器
  75. function showIframe() {
  76. const loadingIndicator = document.getElementById('loadingIndicator');
  77. const scmFrameMain = document.getElementById('scmFrameMain');
  78. // 使用淡入效果显示iframe
  79. scmFrameMain.style.display = 'block';
  80. scmFrameMain.style.opacity = '0';
  81. // 淡出加载指示器
  82. loadingIndicator.style.transition = 'opacity 0.5s';
  83. loadingIndicator.style.opacity = '0';
  84. setTimeout(() => {
  85. loadingIndicator.style.display = 'none';
  86. scmFrameMain.style.opacity = '1';
  87. scmFrameMain.style.transition = 'opacity 0.5s';
  88. }, 500);
  89. }
  90. // 等待iframe加载完成
  91. function waitForIframeLoad(iframe) {
  92. return new Promise((resolve, reject) => {
  93. if (!iframe) {
  94. reject(new Error('未找到iframe元素'));
  95. return;
  96. }
  97. // 设置超时
  98. const timeoutId = setTimeout(() => {
  99. reject(new Error('iframe加载超时'));
  100. }, CONFIG.timeout);
  101. // 监听iframe加载完成
  102. iframe.onload = () => {
  103. clearTimeout(timeoutId);
  104. const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
  105. if (!iframeDoc) {
  106. reject(new Error('无法访问iframe文档'));
  107. return;
  108. }
  109. // 等待iframe文档完全加载
  110. if (iframeDoc.readyState === 'complete') {
  111. resolve(iframeDoc);
  112. } else {
  113. iframeDoc.onreadystatechange = () => {
  114. if (iframeDoc.readyState === 'complete') {
  115. resolve(iframeDoc);
  116. }
  117. };
  118. }
  119. };
  120. });
  121. }
  122. // 修改iframe内容
  123. async function modifyIframeContent(iframeDoc) {
  124. try {
  125. // 并行执行移除和修改操作
  126. await Promise.all([
  127. removeElement(iframeDoc, CONFIG.topElementSelector),
  128. modifyNavigationMenu(iframeDoc)
  129. ]);
  130. console.log('所有修改已完成');
  131. } catch (error) {
  132. console.error('修改iframe内容时出错:', error);
  133. }
  134. }
  135. // 移除指定元素(无感知版本)
  136. function removeElement(doc, selector) {
  137. return new Promise((resolve, reject) => {
  138. if (!doc || !selector) {
  139. reject(new Error('无效的参数'));
  140. return;
  141. }
  142. // 立即检查元素是否存在
  143. const element = doc.querySelector(selector);
  144. if (element) {
  145. // 先隐藏元素,避免视觉闪烁
  146. element.style.visibility = 'hidden';
  147. // 使用requestAnimationFrame确保DOM渲染完成后再移除
  148. requestAnimationFrame(() => {
  149. element.remove();
  150. console.log('元素已成功移除:', selector);
  151. resolve();
  152. });
  153. return;
  154. }
  155. // 设置超时
  156. const timeoutId = setTimeout(() => {
  157. observer.disconnect();
  158. reject(new Error(`查找元素超时: ${selector}`));
  159. }, CONFIG.timeout);
  160. // 使用MutationObserver监听DOM变化
  161. const observer = new MutationObserver((mutationsList) => {
  162. const foundElement = doc.querySelector(selector);
  163. if (foundElement) {
  164. clearTimeout(timeoutId);
  165. observer.disconnect();
  166. // 先隐藏元素,避免视觉闪烁
  167. foundElement.style.visibility = 'hidden';
  168. // 使用requestAnimationFrame确保DOM渲染完成后再移除
  169. requestAnimationFrame(() => {
  170. foundElement.remove();
  171. console.log('元素已成功移除:', selector);
  172. resolve();
  173. });
  174. }
  175. });
  176. // 开始观察
  177. observer.observe(doc.body, {
  178. childList: true,
  179. subtree: true
  180. });
  181. });
  182. }
  183. // 修改导航菜单(无感知版本)
  184. function modifyNavigationMenu(doc) {
  185. return new Promise((resolve, reject) => {
  186. if (!doc) {
  187. reject(new Error('无效的参数'));
  188. return;
  189. }
  190. // 立即检查导航栏是否存在
  191. const navUl = doc.querySelector(CONFIG.navSelector);
  192. if (navUl) {
  193. modifyNav(navUl, doc);
  194. resolve();
  195. return;
  196. }
  197. // 设置超时
  198. const timeoutId = setTimeout(() => {
  199. observer.disconnect();
  200. reject(new Error('查找导航栏超时'));
  201. }, CONFIG.timeout);
  202. // 使用MutationObserver监听DOM变化
  203. const observer = new MutationObserver((mutationsList) => {
  204. const foundNav = doc.querySelector(CONFIG.navSelector);
  205. if (foundNav) {
  206. clearTimeout(timeoutId);
  207. observer.disconnect();
  208. modifyNav(foundNav, doc);
  209. resolve();
  210. }
  211. });
  212. // 开始观察
  213. observer.observe(doc.body, {
  214. childList: true,
  215. subtree: true
  216. });
  217. });
  218. }
  219. // 实际修改导航栏的函数
  220. function modifyNav(navUl, doc) {
  221. try {
  222. // 先隐藏导航栏,避免视觉闪烁
  223. navUl.style.visibility = 'hidden';
  224. // 使用requestAnimationFrame确保DOM渲染完成后再修改
  225. requestAnimationFrame(() => {
  226. // 保留第一个li,删除其他所有li
  227. const navItems = navUl.querySelectorAll("li");
  228. for (let i = 1; i < navItems.length; i++) {
  229. navItems[i].remove();
  230. }
  231. // 添加新菜单项
  232. CONFIG.menuItems.forEach(item => {
  233. addMenuItem(navUl, doc, item.text, item.id);
  234. });
  235. // 恢复可见性
  236. requestAnimationFrame(() => {
  237. navUl.style.visibility = 'visible';
  238. console.log('导航栏修改完成');
  239. });
  240. });
  241. } catch (e) {
  242. console.error('修改导航栏时出错:', e);
  243. }
  244. }
  245. // 添加菜单项
  246. function addMenuItem(parent, doc, text, id) {
  247. if (!parent || !doc || !text || !id) return;
  248. // 使用iframe的document创建元素
  249. const newLi = doc.createElement("li");
  250. newLi.className = "el-sub-menu";
  251. newLi.setAttribute("role", "menuitem");
  252. newLi.setAttribute("id", `custom-${id}`);
  253. const newA = doc.createElement("a");
  254. newA.href = `javascript:void(0);`;
  255. newA.className = "el-menu-item";
  256. newA.setAttribute("role", "menuitem");
  257. newA.setAttribute("aria-disabled", "false");
  258. newA.setAttribute("tabindex", "-1");
  259. newA.setAttribute("aria-selected", "false");
  260. newA.textContent = text;
  261. // 添加点击事件
  262. newA.addEventListener('click', () => {
  263. console.log(`${text} 菜单项被点击`);
  264. // 这里可以添加菜单项点击后的逻辑
  265. onMenuItemClick(id);
  266. });
  267. newLi.appendChild(newA);
  268. parent.appendChild(newLi);
  269. }
  270. // 菜单项点击处理
  271. function onMenuItemClick(id) {
  272. // 根据不同的菜单项ID执行不同的操作
  273. console.log(`执行 ${id} 相关操作`);
  274. // 示例:根据ID执行不同操作
  275. switch(id) {
  276. case 'school':
  277. // 执行学校相关操作
  278. break;
  279. case 'company':
  280. // 执行单位相关操作
  281. break;
  282. case 'student':
  283. // 执行学生相关操作
  284. break;
  285. }
  286. }
  287. </script>
  288. </html>