您现在的位置是:首页 > 技术教程 正文

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

admin 阅读: 2024-03-28
后台-插件-广告管理-内容页头部广告(手机)

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 = `${content}${d.toLocaleString()}`;
  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. div>
  16. <div class="echarts" id="main">div>
  17. div>
  18. <script>
  19. const { ref, onMounted } = Vue;
  20. const MockURL = "./mock/data.json";
  21. const app = {
  22. setup() {
  23. function echartsInit(data) {
  24. const main = document.getElementById("main");
  25. const myChart = echarts.init(main);
  26. myChart.setOption({
  27. legend: {
  28. data: data,
  29. orient: "vertical",
  30. top: "26%",
  31. right: "2%",
  32. icon: "circle",
  33. textStyle: {
  34. fontSize: 20,
  35. rich: {
  36. one: {
  37. width: 80,
  38. },
  39. two: {
  40. width: 80,
  41. },
  42. three: {
  43. width: 80,
  44. },
  45. },
  46. },
  47. formatter: (name) => {
  48. var total = 0;
  49. var target;
  50. let formateData = data;
  51. for (var i = 0; i < formateData.length; i++) {
  52. if (formateData[i].value) {
  53. total += formateData[i].value;
  54. if (formateData[i].name === name) {
  55. target = formateData[i].value;
  56. }
  57. }
  58. }
  59. var v = ((target / total) * 100).toFixed(2);
  60. let row;
  61. if (name === "表头") row = `食物 含量 占比`;
  62. else row = `{one|${name}} {two|${target}} {three|${v}%}`;
  63. return row;
  64. },
  65. },
  66. color: ["#baf", "#bfa", "#cde", "#f90", "#0c9"],
  67. series: [
  68. {
  69. type: "pie",
  70. radius: ["30%", "50%"],
  71. center: ["32%", "40%"],
  72. data: data,
  73. },
  74. ],
  75. });
  76. }
  77. async function fetchData() {
  78. // TODO:待补充代码
  79. let FoodArray = [];
  80. let xhr = new XMLHttpRequest();
  81. xhr.open("GET", MockURL);
  82. xhr.onload = function () {
  83. if (this.status == 200) {
  84. FoodArray = JSON.parse(this.responseText); //这个需要转换一下 因为是JSON格式转换为js对象
  85. let NewFoodArray = [
  86. { name: "表头", icon: "none" },
  87. ]
  88. for (const item of FoodArray) {
  89. NewFoodArray.push(item)
  90. }
  91. // console.log(NewFoodArray);
  92. echartsInit(NewFoodArray) //直接在里面调用就行了
  93. for (const item of FoodArray) {
  94. let div = document.createElement("div");
  95. div.innerHTML = `${item.name} ${item.value}`;
  96. div.className= 'protein-item'
  97. let content =
  98. document.getElementsByClassName("protein-container")[0];
  99. content.appendChild(div);
  100. }
  101. } else {
  102. console.log("请求失败:" + this.status);
  103. }
  104. };
  105. xhr.send();
  106. }
  107. fetchData();
  108. return {
  109. echartsInit,
  110. };
  111. },
  112. };
  113. const vm = Vue.createApp(app);
  114. const mountedApp = vm.mount("#app");
  115. script>
  116. body>
  117. 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. <link rel="stylesheet" href="./css/style.css" />
  8. head>
  9. <body>
  10. <div id="app">
  11. <div class="header">
  12. <h1>营业状态切换h1>
  13. div>
  14. <p>当前店铺状况: {{ isWorking ? '营业中' : '已打烊' }}p>
  15. <img :src="isWorking ? workImage : restImage" alt="Status Image" />
  16. <div
  17. class="switch"
  18. @click="toggleWorking"
  19. :class="{ 'switch-on': isWorking }"
  20. >
  21. <span class="switch-inner">span>
  22. div>
  23. div>
  24. <script setup>
  25. const { ref } = Vue; // 引入Vue中的ref函数
  26. function useToggle(state) {
  27. // TODO:待补充代码
  28. let s1 = ref(state);
  29. function s2() {
  30. //调用这里的函数 返回 isWorking 为true 就得到workImage
  31. s1.value = !s1.value;
  32. }
  33. return [s1, s2]; //如果报错 那么就是返回值的问题了
  34. }
  35. const app = Vue.createApp({
  36. setup() {
  37. const [isWorking, toggleWorking] = useToggle(false); // 使用自定义的useToggle函数创建状态和切换函数
  38. const workImage = "./images/open.jpg"; // 营业状态的图片路径
  39. const restImage = "./images/close.jpg"; // 打烊状态的图片路径
  40. return {
  41. isWorking,
  42. toggleWorking,
  43. workImage,
  44. restImage,
  45. };
  46. },
  47. });
  48. app.mount("#app"); // 将Vue应用挂载到id为app的元素上
  49. script>
  50. body>
  51. html>

7、嘟嘟购物 :

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

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

  1. 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. <div class="cart-warp">
  24. <div class="cart-thead">
  25. <div class="t-checkbox">div>
  26. <div class="t-goods">商品div>
  27. <div class="t-price">单价div>
  28. <div class="t-num">数量div>
  29. <div class="t-sum">小计div>
  30. <div class="t-action">操作div>
  31. div>
  32. <div class="cart-item-list">
  33. <div
  34. class="cart-item check-cart-item"
  35. v-for="(item,index) in goodsArray"
  36. :key="item.id"
  37. >
  38. <div class="p-checkbox">
  39. <input
  40. type="checkbox"
  41. name=""
  42. id=""
  43. class="j-checkbox"
  44. @change="updateCheckedState($event,index)"
  45. />
  46. div>
  47. <div class="p-goods">
  48. <div class="p-img">
  49. <img :src="item.image" alt="" />
  50. div>
  51. <div class="p-msg">{{item.name}}div>
  52. div>
  53. <div class="p-price">{{item.price}}div>
  54. <div class="p-num">
  55. <div class="quantity-form">
  56. <a
  57. href="javascript:;"
  58. class="decrement"
  59. @click="decrement(index)"
  60. >-
  61. >
  62. <input type="text" class="itxt" :value="item.priceCount" />
  63. <a href="javascript:;" class="increment" @click="add(index)"
  64. >+
  65. >
  66. div>
  67. div>
  68. <div class="p-sum">
  69. {{(item.price * item.priceCount).toFixed(2)}}
  70. div>
  71. <div class="p-action"><a href="javascript:;">删除a>div>
  72. div>
  73. div>
  74. <div class="cart-floatbar">
  75. <div class="select-all">div>
  76. <div class="toolbar-right">
  77. <div class="amount-sum">
  78. 已经选<em>{{ selectdItemCount }}em>件商品
  79. div>
  80. <div class="price-sum">
  81. 总价: <em>¥{{ totalItemPrice }}em>
  82. div>
  83. <div class="btn-area" @click="submit">去结算div>
  84. div>
  85. div>
  86. div>
  87. div>
  88. div>
  89. div>
  90. body>
  91. <script type="module">
  92. const { createApp, onMounted, watchEffect } = Vue;
  93. const { createPinia } = Pinia;
  94. const { ElMessage, ElNotification } = ElementPlus;
  95. const app = Vue.createApp({
  96. setup() {
  97. // TODO:补充代码,实现目标效果
  98. const goodsStock = Array.from(useGoodsStore().store);
  99. const goodId = [];
  100. const goodsArray = ref([]);
  101. const priceCount = ref(1);
  102. for (const item of goodsStock) {
  103. //这个是判断有没有货的操作
  104. if (item.stock !== 0) {
  105. goodId.push(item.id);
  106. } else {
  107. goodId.push(-1);
  108. }
  109. }
  110. const getGoods = () => {
  111. axios.get("./js/goods.json").then((res) => {
  112. const tempArray = [];
  113. // console.log(goodId); //有货的id 没货的id为 -1
  114. for (let i = 0; i < res.data.length; i++) {
  115. if (res.data[i].id === goodId[i]) {
  116. tempArray.push(res.data[i]);
  117. }
  118. }
  119. goodsArray.value = tempArray;
  120. for (const item of goodsArray.value) {
  121. item.priceCount = 1; //默认为1
  122. item.checked = false; //checked按钮默认为false
  123. }
  124. console.log(goodsArray.value);
  125. });
  126. };
  127. const add = (index) => {
  128. goodsArray.value[index].priceCount++;
  129. };
  130. const decrement = (index) => {
  131. if (goodsArray.value[index].priceCount === 1) {
  132. return;
  133. }
  134. goodsArray.value[index].priceCount--;
  135. };
  136. const updateCheckedState = (event, index) => {
  137. //给到响应式数组里面
  138. goodsArray.value[index].checked = event.target.checked;
  139. };
  140. const selectdItemCount = ref(0);
  141. const totalItemPrice = ref(0);
  142. watchEffect(() => {
  143. //就是这里面的响应式发生变化 就会触发watchEffect()
  144. selectdItemCount.value = 0;
  145. totalItemPrice.value = 0;
  146. for (const item of goodsArray.value) {
  147. if (item.checked === true) {
  148. selectdItemCount.value += item.priceCount;
  149. totalItemPrice.value += item.priceCount * item.price;
  150. }
  151. }
  152. totalItemPrice.value = totalItemPrice.value.toFixed(2);
  153. });
  154. //若没有选择商品
  155. const shopNoSelect = () => {
  156. for (const item of goodsArray.value) {
  157. if (item.checked === true) {
  158. return true;
  159. }
  160. }
  161. return false; //如果没有一个true就返回false
  162. };
  163. const submit = async () => {
  164. //提交结算
  165. try {
  166. if (!shopNoSelect()) {
  167. //则提示警告信息:
  168. ElMessage({
  169. message: "请至少选择一件商品",
  170. type: "warning",
  171. });
  172. }
  173. for (const item of goodsArray.value) {
  174. console.log(item.priceCount);
  175. if (item.checked === true) {
  176. let goodsNamePriceCount = await useGoodsStore().fetchInventory(
  177. item.name
  178. );
  179. console.log(goodsNamePriceCount);
  180. if (item.priceCount > goodsNamePriceCount) {
  181. ElMessage.error(`结算失败,${item.name}库存不足`);
  182. return;
  183. }
  184. }
  185. }
  186. ElMessage({
  187. message: "结算成功",
  188. type: "success",
  189. });
  190. } catch (error) {
  191. ElMessage.error(`结算失败,${请求返回的错误信息}`);
  192. }
  193. };
  194. onMounted(() => {
  195. //页面渲染之后,直接调用
  196. getGoods(); //调用
  197. });
  198. return {
  199. //在这个非工程文件当中的vue3 都是需要return一下的
  200. goodsArray,
  201. priceCount,
  202. add,
  203. decrement,
  204. selectdItemCount,
  205. totalItemPrice,
  206. updateCheckedState,
  207. submit,
  208. };
  209. // TODOEnd
  210. },
  211. });
  212. app.use(ElementPlus);
  213. app.use(createPinia());
  214. app.mount("#app");
  215. script>
  216. 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 = `标签页${lengthTab}
  57. `
  58. event.ul.appendChild(newTab);
  59. //添加section内容
  60. let newTabScon = document.createElement('section');
  61. newTabScon.className = 'conactive';
  62. newTabScon.innerHTML = `标签页${lengthTab}的内容`;
  63. event.fsection.appendChild(newTabScon);
  64. event.updateNode(); //需要更新一下节点
  65. event.init();
  66. // TODO结束
  67. }
  68. // 4.删除功能
  69. removeTab(event) {
  70. let index = Array.from(event.remove).indexOf(this); // 获取点击的删除按钮在数组中的索引
  71. var lis = document.getElementsByTagName("li");
  72. for (let index = 0; index < lis.length; index++) {
  73. if (lis[index] == this.parentElement) {
  74. this.parentElement.setAttribute('num', index);
  75. }
  76. }
  77. if (event.lis[index].classList.contains('liactive')) { // 如果要删除的标签页是当前选中的标签页
  78. if (index < event.lis.length - 1) { // 不是最后一个标签页
  79. event.lis[index + 1].click(); // 选中临近的下一个标签页
  80. } else if (index > 0) { // 是最后一个标签页
  81. event.lis[index - 1].click(); // 选中临近的上一个标签页
  82. }
  83. }
  84. event.ul.removeChild(event.lis[index]); // 从页面中删除对应的标签页
  85. event.fsection.removeChild(event.sections[index]); // 从页面中删除对应的内容页
  86. event.updateNode(); // 更新节点
  87. }
  88. // 5.修改功能
  89. editTab() {
  90. var str = this.innerHTML;
  91. window.getSelection
  92. ? window.getSelection().removeAllRanges()
  93. : document.Selection.empty();
  94. this.innerHTML = '';
  95. var input = this.children[0];
  96. input.value = str;
  97. input.select(); //让文本框里的文字处于选定状态
  98. // TODO:实现双击修改内容,当文本框失焦时,把修改的值赋给被双击的对象,并作上已修改的标记
  99. let li = this;
  100. input.onblur = function () {
  101. li.innerHTML = this.value
  102. }
  103. // TODO结束
  104. }
  105. }
  106. var tab = new Tab("#tab");

标签:
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

在线投稿:投稿 站长QQ:1888636

后台-插件-广告管理-内容页尾部广告(手机)
关注我们

扫一扫关注我们,了解最新精彩内容

搜索