0


第十五届蓝桥杯(Web 应用开发)模拟赛 3 期-大学组And职业组

1、创意广告牌 代码:

  1. .billboard {
  2. position: relative;
  3. background-color: #8e6534;
  4. color: #fff;
  5. padding: 20px;
  6. box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.3);
  7. background-size: cover;
  8. border-radius: 10px; /* 设置圆角为 10px */
  9. background-image: url('../images/woodiness.jpg'); /* 设置背景图片为 woodiness.jpg */
  10. }
  11. .top-sign {
  12. position: relative;
  13. width: 200px;
  14. height: 100px;
  15. background-color: #a87f4a;
  16. display: flex;
  17. justify-content: center;
  18. align-items: center;
  19. font-size: 1rem;
  20. border-top-left-radius: 15px; /* 设置上左角为圆角 15px */
  21. border-top-right-radius: 15px; /* 设置上右角为圆角 15px */
  22. transform: skewX(-20deg); /* 在 x 轴方向倾斜元素 20度 */
  23. }

2、原子化CSS 的代码

直接在css下面加个flex弹性布局的操作,然后竖着。

  1. /* TODO: 实现原子化 flex */
  2. div {
  3. display: flex;
  4. flex-direction: column;
  5. }

3、神秘咒语

简单的token操作,axios知识点,请求的时候在请求头带上token,就可以顺利请求访问到。

  1. // TODO:新增或者修改以下代码
  2. let token = '2b58f9a8-7d73-4a9c-b8a2-9f05d6e8e3c7';
  3. key1Button.addEventListener('click', async () => {
  4. // 从后台请求钥匙1的咒语部分
  5. key1Button.disabled = true;
  6. let {data} = await axios.get('/spellone', {headers: {'Authorization': token}})
  7. spell1.innerHTML = data;
  8. tryOpenTreasureBox();
  9. });
  10. key2Button.addEventListener('click', async () => {
  11. // 从后台请求钥匙2的咒语部分
  12. key2Button.disabled = true;
  13. let {data} = await axios.get('/spelltwo', {headers: {'Authorization': token}})
  14. spell2.innerHTML = data;
  15. tryOpenTreasureBox();
  16. });

4、朋友圈 代码:

防抖考了,会不会在真题的时候考节流。。。

JS练习题

  1. document.addEventListener("DOMContentLoaded", function() {
  2. let textContent = localStorage.getItem('savedText');
  3. document.getElementById('text').value = textContent;
  4. show()
  5. });
  6. document.getElementById("text").addEventListener(
  7. "input",
  8. debounce(function() {
  9. document.getElementById("prompt").textContent = "正在保存中...";
  10. let textContent = document.getElementById('text').value;
  11. localStorage.setItem('savedText', textContent);
  12. show()
  13. setTimeout(function() {
  14. document.getElementById("prompt").textContent = "内容已保存";
  15. }, 750);
  16. }, 200)
  17. );
  18. document.getElementById("post").addEventListener("click", function() {
  19. const content = document.getElementById("text").value;
  20. // 假设 createContent 是一个已定义的函数,用于创建表示内容的DOM元素
  21. const element = createContent(content);
  22. document.querySelector(".contents").appendChild(element);
  23. document.getElementById("prompt").textContent = "发表成功!";
  24. document.getElementById("text").value = '';
  25. localStorage.removeItem('savedText');
  26. show()
  27. });
  28. // 防抖工具函数
  29. /**
  30. * @param {function} fn - 回调函数
  31. * @param {string} delay - 函数执行延迟,单位为ms
  32. */
  33. function debounce(fn, delay) {
  34. // return fn; // 这一行是为了确保页面正常运行,可以去掉
  35. let timer = null;
  36. return function () {
  37. if (timer) {
  38. clearTimeout(timer);
  39. }
  40. timer = setTimeout(() => {
  41. fn();
  42. }, delay);
  43. }
  44. // TODO: 请实现函数防抖的功能
  45. }
  46. function show(){
  47. if (document.getElementById("text").value !== '') {
  48. document.getElementById("post").removeAttribute('disabled');
  49. } else {
  50. document.getElementById("post").setAttribute('disabled', 'disabled');
  51. }
  52. }
  53. // 用户点击“发表”后,创建一条新信息的DOM元素
  54. function createContent(content) {
  55. const div = document.createElement("div");
  56. const d = new Date();
  57. const deleteBtn = document.createElement("button");
  58. deleteBtn.textContent = "删除";
  59. deleteBtn.addEventListener("click", function() {
  60. div.remove();
  61. });
  62. div.innerHTML = `<div><span class="content">${content}</span><span class="date">${d.toLocaleString()}</span></div>`;
  63. div.appendChild(deleteBtn);
  64. return div;
  65. }

5、美食蛋白质揭秘 代码:

JS原生ajax请求 )xhr = new XMLHttpRequest();

open("请求方式","请求路径“);

用onload加载一次就行了,补充一个就是

  • onreadystatechange
  • 当 readyState 属性发生变化时,调用的事件处理器。
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <title>不同食物的蛋白质占比</title>
  7. <script src="./lib/vue3.global.js"></script>
  8. <script src="./lib/echarts.min.js"></script>
  9. <link rel="stylesheet" href="css/style.css" />
  10. </head>
  11. <body>
  12. <div id="app">
  13. <h2>不同食物的蛋白质占比</h2>
  14. <div class="protein-container">
  15. <!-- TODO:待补充代码,渲染获取的数据 -->
  16. </div>
  17. <div class="echarts" id="main"></div>
  18. </div>
  19. <script>
  20. const { ref, onMounted } = Vue;
  21. const MockURL = "./mock/data.json";
  22. const app = {
  23. setup() {
  24. function echartsInit(data) {
  25. const main = document.getElementById("main");
  26. const myChart = echarts.init(main);
  27. myChart.setOption({
  28. legend: {
  29. data: data,
  30. orient: "vertical",
  31. top: "26%",
  32. right: "2%",
  33. icon: "circle",
  34. textStyle: {
  35. fontSize: 20,
  36. rich: {
  37. one: {
  38. width: 80,
  39. },
  40. two: {
  41. width: 80,
  42. },
  43. three: {
  44. width: 80,
  45. },
  46. },
  47. },
  48. formatter: (name) => {
  49. var total = 0;
  50. var target;
  51. let formateData = data;
  52. for (var i = 0; i < formateData.length; i++) {
  53. if (formateData[i].value) {
  54. total += formateData[i].value;
  55. if (formateData[i].name === name) {
  56. target = formateData[i].value;
  57. }
  58. }
  59. }
  60. var v = ((target / total) * 100).toFixed(2);
  61. let row;
  62. if (name === "表头") row = `食物 含量 占比`;
  63. else row = `{one|${name}} {two|${target}} {three|${v}%}`;
  64. return row;
  65. },
  66. },
  67. color: ["#baf", "#bfa", "#cde", "#f90", "#0c9"],
  68. series: [
  69. {
  70. type: "pie",
  71. radius: ["30%", "50%"],
  72. center: ["32%", "40%"],
  73. data: data,
  74. },
  75. ],
  76. });
  77. }
  78. async function fetchData() {
  79. // TODO:待补充代码
  80. let FoodArray = [];
  81. let xhr = new XMLHttpRequest();
  82. xhr.open("GET", MockURL);
  83. xhr.onload = function () {
  84. if (this.status == 200) {
  85. FoodArray = JSON.parse(this.responseText); //这个需要转换一下 因为是JSON格式转换为js对象
  86. let NewFoodArray = [
  87. { name: "表头", icon: "none" },
  88. ]
  89. for (const item of FoodArray) {
  90. NewFoodArray.push(item)
  91. }
  92. // console.log(NewFoodArray);
  93. echartsInit(NewFoodArray) //直接在里面调用就行了
  94. for (const item of FoodArray) {
  95. let div = document.createElement("div");
  96. div.innerHTML = `${item.name} ${item.value}`;
  97. div.className= 'protein-item'
  98. let content =
  99. document.getElementsByClassName("protein-container")[0];
  100. content.appendChild(div);
  101. }
  102. } else {
  103. console.log("请求失败:" + this.status);
  104. }
  105. };
  106. xhr.send();
  107. }
  108. fetchData();
  109. return {
  110. echartsInit,
  111. };
  112. },
  113. };
  114. const vm = Vue.createApp(app);
  115. const mountedApp = vm.mount("#app");
  116. </script>
  117. </body>
  118. </html>

6、营业状态切换

其实就是 自定义一个东西 只不过这里的返回是需要对应上,要记得;

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8" />
  5. <title>营业状态切换</title>
  6. <script src="./lib/vue.global.js"></script>
  7. <!-- 引入Vue.js库 -->
  8. <link rel="stylesheet" href="./css/style.css" />
  9. <!-- 引入样式表 -->
  10. </head>
  11. <body>
  12. <div id="app">
  13. <div class="header">
  14. <h1>营业状态切换</h1>
  15. <!-- 页面标题 -->
  16. </div>
  17. <!-- 显示店铺状态 -->
  18. <p>当前店铺状况: {{ isWorking ? '营业中' : '已打烊' }}</p>
  19. <!-- 根据状态显示相应的图片 -->
  20. <img :src="isWorking ? workImage : restImage" alt="Status Image" />
  21. <!-- 切换店铺状态的开关按钮 -->
  22. <div
  23. class="switch"
  24. @click="toggleWorking"
  25. :class="{ 'switch-on': isWorking }"
  26. >
  27. <span class="switch-inner"></span>
  28. </div>
  29. </div>
  30. <script setup>
  31. const { ref } = Vue; // 引入Vue中的ref函数
  32. function useToggle(state) {
  33. // TODO:待补充代码
  34. let s1 = ref(state);
  35. function s2() {
  36. //调用这里的函数 返回 isWorking 为true 就得到workImage
  37. s1.value = !s1.value;
  38. }
  39. return [s1, s2]; //如果报错 那么就是返回值的问题了
  40. }
  41. const app = Vue.createApp({
  42. setup() {
  43. const [isWorking, toggleWorking] = useToggle(false); // 使用自定义的useToggle函数创建状态和切换函数
  44. const workImage = "./images/open.jpg"; // 营业状态的图片路径
  45. const restImage = "./images/close.jpg"; // 打烊状态的图片路径
  46. return {
  47. isWorking,
  48. toggleWorking,
  49. workImage,
  50. restImage,
  51. };
  52. },
  53. });
  54. app.mount("#app"); // 将Vue应用挂载到id为app的元素上
  55. </script>
  56. </body>
  57. </html>

7、嘟嘟购物 :

这里就是vue3的练习,职业组的一道题,大学组的是一道node题。

就是Pinia和vue3。WatchEffect监听 只要里面的响应式发生变化就会调用一次,还有在页面开始也会调用一次,至于Pinia,直接调用就行了,这里是非工程文件,已经有script引入了Pinia

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <link rel="stylesheet" href="./css/element-plus@2.3.7/index.css" />
  7. <link rel="stylesheet" href="./css/index.css" />
  8. <script src="./lib/vue.min.js"></script>
  9. <script src="./css/element-plus@2.3.7/index.full.js"></script>
  10. <script src="./lib/axios.js"></script>
  11. <script src="./lib/vueDemi.js"></script>
  12. <script src="./lib/pinia.min.js"></script>
  13. <script src="./js/store.js"></script>
  14. <title>嘟嘟购物</title>
  15. </head>
  16. <body>
  17. <div id="app">
  18. <div class="c-container">
  19. <div class="w">
  20. <div class="cart-filter-bar">
  21. <em>全部商品</em>
  22. </div>
  23. <!-- 购物车主要核心区域 -->
  24. <div class="cart-warp">
  25. <div class="cart-thead">
  26. <div class="t-checkbox"></div>
  27. <div class="t-goods">商品</div>
  28. <div class="t-price">单价</div>
  29. <div class="t-num">数量</div>
  30. <div class="t-sum">小计</div>
  31. <div class="t-action">操作</div>
  32. </div>
  33. <!-- 商品详细模块 -->
  34. <div class="cart-item-list">
  35. <div
  36. class="cart-item check-cart-item"
  37. v-for="(item,index) in goodsArray"
  38. :key="item.id"
  39. >
  40. <div class="p-checkbox">
  41. <input
  42. type="checkbox"
  43. name=""
  44. id=""
  45. class="j-checkbox"
  46. @change="updateCheckedState($event,index)"
  47. />
  48. </div>
  49. <div class="p-goods">
  50. <div class="p-img">
  51. <img :src="item.image" alt="" />
  52. </div>
  53. <div class="p-msg">{{item.name}}</div>
  54. </div>
  55. <div class="p-price">{{item.price}}</div>
  56. <div class="p-num">
  57. <div class="quantity-form">
  58. <a
  59. href="javascript:;"
  60. class="decrement"
  61. @click="decrement(index)"
  62. >-</a
  63. >
  64. <input type="text" class="itxt" :value="item.priceCount" />
  65. <a href="javascript:;" class="increment" @click="add(index)"
  66. >+</a
  67. >
  68. </div>
  69. </div>
  70. <div class="p-sum">
  71. {{(item.price * item.priceCount).toFixed(2)}}
  72. </div>
  73. <div class="p-action"><a href="javascript:;">删除</a></div>
  74. </div>
  75. </div>
  76. <!-- 结算模块 -->
  77. <div class="cart-floatbar">
  78. <div class="select-all"></div>
  79. <div class="toolbar-right">
  80. <div class="amount-sum">
  81. 已经选<em>{{ selectdItemCount }}</em>件商品
  82. </div>
  83. <div class="price-sum">
  84. 总价: <em>¥{{ totalItemPrice }}</em>
  85. </div>
  86. <div class="btn-area" @click="submit">去结算</div>
  87. </div>
  88. </div>
  89. </div>
  90. </div>
  91. </div>
  92. </div>
  93. </body>
  94. <script type="module">
  95. const { createApp, onMounted, watchEffect } = Vue;
  96. const { createPinia } = Pinia;
  97. const { ElMessage, ElNotification } = ElementPlus;
  98. const app = Vue.createApp({
  99. setup() {
  100. // TODO:补充代码,实现目标效果
  101. const goodsStock = Array.from(useGoodsStore().store);
  102. const goodId = [];
  103. const goodsArray = ref([]);
  104. const priceCount = ref(1);
  105. for (const item of goodsStock) {
  106. //这个是判断有没有货的操作
  107. if (item.stock !== 0) {
  108. goodId.push(item.id);
  109. } else {
  110. goodId.push(-1);
  111. }
  112. }
  113. const getGoods = () => {
  114. axios.get("./js/goods.json").then((res) => {
  115. const tempArray = [];
  116. // console.log(goodId); //有货的id 没货的id为 -1
  117. for (let i = 0; i < res.data.length; i++) {
  118. if (res.data[i].id === goodId[i]) {
  119. tempArray.push(res.data[i]);
  120. }
  121. }
  122. goodsArray.value = tempArray;
  123. for (const item of goodsArray.value) {
  124. item.priceCount = 1; //默认为1
  125. item.checked = false; //checked按钮默认为false
  126. }
  127. console.log(goodsArray.value);
  128. });
  129. };
  130. const add = (index) => {
  131. goodsArray.value[index].priceCount++;
  132. };
  133. const decrement = (index) => {
  134. if (goodsArray.value[index].priceCount === 1) {
  135. return;
  136. }
  137. goodsArray.value[index].priceCount--;
  138. };
  139. const updateCheckedState = (event, index) => {
  140. //给到响应式数组里面
  141. goodsArray.value[index].checked = event.target.checked;
  142. };
  143. const selectdItemCount = ref(0);
  144. const totalItemPrice = ref(0);
  145. watchEffect(() => {
  146. //就是这里面的响应式发生变化 就会触发watchEffect()
  147. selectdItemCount.value = 0;
  148. totalItemPrice.value = 0;
  149. for (const item of goodsArray.value) {
  150. if (item.checked === true) {
  151. selectdItemCount.value += item.priceCount;
  152. totalItemPrice.value += item.priceCount * item.price;
  153. }
  154. }
  155. totalItemPrice.value = totalItemPrice.value.toFixed(2);
  156. });
  157. //若没有选择商品
  158. const shopNoSelect = () => {
  159. for (const item of goodsArray.value) {
  160. if (item.checked === true) {
  161. return true;
  162. }
  163. }
  164. return false; //如果没有一个true就返回false
  165. };
  166. const submit = async () => {
  167. //提交结算
  168. try {
  169. if (!shopNoSelect()) {
  170. //则提示警告信息:
  171. ElMessage({
  172. message: "请至少选择一件商品",
  173. type: "warning",
  174. });
  175. }
  176. for (const item of goodsArray.value) {
  177. console.log(item.priceCount);
  178. if (item.checked === true) {
  179. let goodsNamePriceCount = await useGoodsStore().fetchInventory(
  180. item.name
  181. );
  182. console.log(goodsNamePriceCount);
  183. if (item.priceCount > goodsNamePriceCount) {
  184. ElMessage.error(`结算失败,${item.name}库存不足`);
  185. return;
  186. }
  187. }
  188. }
  189. ElMessage({
  190. message: "结算成功",
  191. type: "success",
  192. });
  193. } catch (error) {
  194. ElMessage.error(`结算失败,${请求返回的错误信息}`);
  195. }
  196. };
  197. onMounted(() => {
  198. //页面渲染之后,直接调用
  199. getGoods(); //调用
  200. });
  201. return {
  202. //在这个非工程文件当中的vue3 都是需要return一下的
  203. goodsArray,
  204. priceCount,
  205. add,
  206. decrement,
  207. selectdItemCount,
  208. totalItemPrice,
  209. updateCheckedState,
  210. submit,
  211. };
  212. // TODOEnd
  213. },
  214. });
  215. app.use(ElementPlus);
  216. app.use(createPinia());
  217. app.mount("#app");
  218. </script>
  219. </html>

8、冰岛人:

我这种方法是比较简单的 其实还可以用map集合或者 递归 他这里说五代人 并不包含第五代人。

  1. /**
  2. * @description 通过输入的两个人的姓名返回相应的字符串
  3. * @param {array} data 当地的人口信息
  4. * @param {string} name1 要查询的两人名字之一
  5. * @param {string} name2 要查询的两人名字之一
  6. * @return {string} 根据被查询两人的名字返回对应的字符串
  7. * */
  8. function marry(data, name1, name2) {
  9. // TODO:补充代码,实现目标效果
  10. console.log(data); //和NameAll是对应的
  11. let data2 = deepCopy(data);
  12. console.log(data2);
  13. const NameAll = [];
  14. for (let i = 0; i < data2.length; i++) {
  15. NameAll.push(`${data2[i].givenName} ${removeSuffix(data2[i].familyName)}`);
  16. }
  17. console.log(NameAll); // 和data是对应,就是去掉了后面的尾缀
  18. //查询其中一人是否在名单中
  19. const person1 = NameAll.findIndex((name) => name == name1);
  20. const person2 = NameAll.findIndex((name) => name == name2);
  21. console.log(person1);
  22. console.log(person2);
  23. if (person1 == -1 || person2 == -1) {
  24. return "NA";
  25. }
  26. //直接判断性别
  27. const gender1 = getGender(data2[person1].familyName);
  28. const gender2 = getGender(data2[person2].familyName);
  29. if (gender1 === gender2) {
  30. return "Whatever";
  31. }
  32. let nameObj1 = data2[person1];
  33. let nameObj2 = data2[person2];
  34. //前面的代码都已经拦截完毕了,现在开始直接进入查找就行了
  35. //april mikesdottir 和 steve billsson 是no
  36. //april mike 和 steve bill 是 no
  37. if (hasCommonAncestor(data2, nameObj1, nameObj2)) {
  38. return "No";
  39. } else {
  40. return "Yes";
  41. }
  42. }
  43. //深拷贝
  44. function deepCopy(obj) {
  45. if (typeof obj !== 'object' || obj === null) {
  46. return obj;
  47. }
  48. let copy = Array.isArray(obj) ? [] : {};
  49. for (let key in obj) {
  50. if (Object.prototype.hasOwnProperty.call(obj, key)) {
  51. copy[key] = deepCopy(obj[key]);
  52. }
  53. }
  54. return copy;
  55. }
  56. function hasCommonAncestor(data, name1, name2) {
  57. const ancestors1 = computeAncestors(data, name1);
  58. const ancestors2 = computeAncestors(data, name2);
  59. if (ancestors1 == ancestors2) {
  60. return true;
  61. }
  62. return false;
  63. }
  64. //找到最后的祖先
  65. function computeAncestors(data, name) {
  66. //先切割掉 sson和sdottir 不要割掉 m 和 f 知道是祖宗
  67. for (let i = 0; i < data.length; i++) {
  68. data[i].familyName = removeSuffix2(data[i].familyName);
  69. }
  70. let ancestor = null; //设置祖先变量
  71. // console.log(name.familyName == data[7].givenName);
  72. for (let i = 0; i < data.length; i++) {
  73. if (data[i].givenName == name.familyName) {
  74. if (data[i].familyName.charAt(data[i].familyName.length - 1) == 'm') {
  75. ancestor = data[i].givenName;
  76. break;
  77. }
  78. for (let j = 0; j < data.length; j++) {
  79. if (data[j].givenName == data[i].familyName) {
  80. if (data[j].familyName.charAt(data[j].familyName.length - 1) == 'm') {
  81. ancestor = data[j].givenName;
  82. break;
  83. }
  84. for (let k = 0; k < data.length; k++) {
  85. if (data[k].givenName == data[j].familyName) {
  86. ancestor = data[k].givenName;
  87. }
  88. }
  89. }
  90. }
  91. }
  92. }
  93. console.log(ancestor);
  94. return ancestor
  95. }
  96. //递归
  97. /**
  98. * 查询冰岛人名的性别的函数
  99. * @param {String} name 传递进来的冰岛人名
  100. * @return {String} 返回男是 male 女的是female
  101. */
  102. function getGender(name) {
  103. if (name.endsWith("sson") || name.endsWith("m")) {
  104. return "male"; //男
  105. } else if (name.endsWith("sdottir") || name.endsWith("f")) {
  106. return "female"; //女
  107. }
  108. }
  109. // 使用正则表达式匹配字符串结尾的 'sson'、'sdottir'、'm' 或 'f' 并替换为 ''
  110. function removeSuffix(name) {
  111. return name.replace(/(sson|sdottir|m|f)$/, "");
  112. }
  113. // 使用正则表达式匹配字符串结尾的 'sson'、'sdottir'并替换为 ''
  114. function removeSuffix2(name) {
  115. return name.replace(/(sson|sdottir)$/, "");
  116. }
  117. module.exports = marry;

9、这是一个“浏览器”

也是纯粹的JS题,功能是实现了,但是不知为啥过不了检测。

  1. "use strict";
  2. class Tab {
  3. // 构造方法
  4. constructor(id) {
  5. // 获取元素
  6. this.main = document.querySelector(id);
  7. this.add = this.main.querySelector(".tabadd");
  8. this.ul = this.main.querySelector(".fisrstnav ul");
  9. this.fsection = this.main.querySelector(".tabscon"); //content页面
  10. this.init();
  11. }
  12. // 初始化
  13. init() {
  14. this.updateNode();
  15. // init初始化操作让相关元素绑定事件
  16. this.add.onclick = this.addTab.bind(this.add, this);
  17. for (var i = 0; i < this.lis.length; i++) {
  18. this.lis[i].index = i;
  19. this.lis[i].onclick = this.toggleTab.bind(this.lis[i], this);
  20. this.remove[i].onclick = this.removeTab.bind(this.remove[i], this);
  21. this.spans[i].ondblclick = this.editTab;
  22. this.sections[i].ondblclick = this.editTab;
  23. }
  24. }
  25. // 更新所有的li和section
  26. updateNode() {
  27. this.lis = this.main.querySelectorAll("li");
  28. this.remove = this.main.querySelectorAll(".icon-guanbi");
  29. this.sections = this.main.querySelectorAll("section");
  30. this.spans = this.main.querySelectorAll(".content");
  31. }
  32. // 1.切换功能
  33. toggleTab(event) {
  34. // TODO: 添加代码,点击标签页,切换到对应标签页的功能
  35. var num = this.getAttribute("num");
  36. if (num != null && !(this.classList.contains("liactive"))) return; //阻止冒泡
  37. event.clearClass(); //this.clearClass不行 因为指向的是元素
  38. this.className = 'liactive'
  39. event.sections[this.index].className = 'conactive'
  40. // TODO结束
  41. }
  42. // 2.清空所有标签页及其内容页类名
  43. clearClass() {
  44. for (var i = 0; i < this.lis.length; i++) {
  45. this.lis[i].className = "";
  46. this.sections[i].className = "";
  47. }
  48. }
  49. // 3.添加标签页
  50. addTab(event) {
  51. // TODO:添加代码,当点击加号,添加新的标签页(对应的内容页也应一并添加)
  52. event.clearClass(); //清除一下
  53. let newTab = document.createElement('li');
  54. let lengthTab = event.lis.length + 1
  55. newTab.className = 'liactive'
  56. newTab.innerHTML = `<span class="content">标签页${lengthTab}</span>
  57. <span class="iconfont icon-guanbi">
  58. <span class="glyphicon glyphicon-remove">
  59. </span>
  60. </span>`
  61. event.ul.appendChild(newTab);
  62. //添加section内容
  63. let newTabScon = document.createElement('section');
  64. newTabScon.className = 'conactive';
  65. newTabScon.innerHTML = `标签页${lengthTab}的内容`;
  66. event.fsection.appendChild(newTabScon);
  67. event.updateNode(); //需要更新一下节点
  68. event.init();
  69. // TODO结束
  70. }
  71. // 4.删除功能
  72. removeTab(event) {
  73. let index = Array.from(event.remove).indexOf(this); // 获取点击的删除按钮在数组中的索引
  74. var lis = document.getElementsByTagName("li");
  75. for (let index = 0; index < lis.length; index++) {
  76. if (lis[index] == this.parentElement) {
  77. this.parentElement.setAttribute('num', index);
  78. }
  79. }
  80. if (event.lis[index].classList.contains('liactive')) { // 如果要删除的标签页是当前选中的标签页
  81. if (index < event.lis.length - 1) { // 不是最后一个标签页
  82. event.lis[index + 1].click(); // 选中临近的下一个标签页
  83. } else if (index > 0) { // 是最后一个标签页
  84. event.lis[index - 1].click(); // 选中临近的上一个标签页
  85. }
  86. }
  87. event.ul.removeChild(event.lis[index]); // 从页面中删除对应的标签页
  88. event.fsection.removeChild(event.sections[index]); // 从页面中删除对应的内容页
  89. event.updateNode(); // 更新节点
  90. }
  91. // 5.修改功能
  92. editTab() {
  93. var str = this.innerHTML;
  94. window.getSelection
  95. ? window.getSelection().removeAllRanges()
  96. : document.Selection.empty();
  97. this.innerHTML = '<input type="text" />';
  98. var input = this.children[0];
  99. input.value = str;
  100. input.select(); //让文本框里的文字处于选定状态
  101. // TODO:实现双击修改内容,当文本框失焦时,把修改的值赋给被双击的对象,并作上已修改的标记
  102. let li = this;
  103. input.onblur = function () {
  104. li.innerHTML = this.value
  105. }
  106. // TODO结束
  107. }
  108. }
  109. var tab = new Tab("#tab");

本文转载自: https://blog.csdn.net/m0_56646930/article/details/136558163
版权归原作者 Stolen 遗憾 所有, 如有侵权,请联系我们删除。

“第十五届蓝桥杯(Web 应用开发)模拟赛 3 期-大学组And职业组”的评论:

还没有评论