1.5-01:求平均年龄

C语言计算平均年龄
#include<stdio.h>
int main()
{
	int n,age,sum=0;
	scanf("%d",&n);
	int i=1;
	while(i<=n){
		scanf("%d",&age);
		sum=sum+age;
		i++;
	}
	printf("%.2lf",(double)sum/n);
	return 0;
}
<template> <div class="areaReport2 page"> <el-container class="scrollable-content"> <el-main> <h1>{{}}区教师发展区域报告</h1> <div v-for="(item,index) in treeList" :id="item.id" class="itemBox"> <h2>{{ item.name }}</h2> <component :is="item.com" :regionData="regionData"/> <div v-for="(it,ind) in item.children" :id="it.id" class="itBox"> <h3>{{ it.name }}</h3> <component :is="it.com" :chartData="it.chartData" :regionData="regionData" v-if="isReduce"/> </div> </div> </el-main> <el-aside width="320px" class="fixed-sidebar"> <el-tree :data="treeList" default-expand-all :props="defaultProps" @node-click="handleNodeClick"/> </el-aside> </el-container> </div> </template> <script setup> import {ref, onUnmounted, nextTick} from "vue"; import {post, postJson} from "@/frame/request/http"; import temp1 from './component/temp1' import temp2 from './component/temp2' import temp3 from './component/temp3' import temp4 from './component/temp4' import temp5 from './component/temp5' import temp6 from './component/temp6' import temp7 from './component/temp7' import temp8 from './component/temp8' import temp9 from './component/temp9' import temp10 from './component/temp10' import temp11 from './component/temp11' import temp12 from './component/temp12' import temp13 from './component/temp13' import temp14 from './component/temp14' import bar3Com from './component/bar3Com' import bar4Com from './component/bar4Com' import useGetters from "@/frame/store/useGetters"; const user = useGetters("user"); const defaultProps = { children: 'children', label: 'name', } let treeList = ref([ { name: '一、基本信息1', id: 'id1', com: temp1, }, { name: '二、教师年龄结构统计', id: 'id2', children: [ {name: '1.年龄段数量情况', id: 'id2-1', com: temp2, chartData: {title: '年龄段校占比与区占比对比'}}, {name: '2.各校年龄平均值(从低到高)前5所', id: 'id2-2', com: temp3,}, {name: '3.各校年龄平均值(从高到低)前5所', id: 'id2-3', com: temp3}, {name: '4.35岁一下教师占比', id: 'id2-4', com: bar3Com}, {name: '5.未来五年建退休教师占比', id: 'id2-5', com: bar4Com}, {name: '6.未来五年退休人数超10人', id: 'id2-6', com: temp4}, {name: '7.2025年退休人数校', id: 'id2-7', com: temp4}, ] }, { name: '三、教师职称结构统计', id: 'id3', children: [ {name: '1.教师职称结构统计1', id: 'id3', com: temp5, chartData: {title: '得分趋势图'}}, ] }, { name: '四、教学工作情况', id: 'id4', children: [ {name: '1.教学获奖1', id: 'id4', com: temp6, chartData: {title: '得分趋势图'}}, ] }, { name: '五、科研工作情况', id: 'id5', children: [ {name: '1.论文发表1', id: 'id5-1', com: temp7, chartData: {title: '年份得分趋势图'}}, {name: '2.主持课题1', id: 'id5-2', com: temp8, chartData: {title: '年份得分趋势图'}}, {name: '3.刊物发表1', id: 'id5-3', com: temp9, chartData: {title: '年份得分趋势图'}}, ] }, { name: '六、教师发展情况统计', id: 'id6', children: [ {name: '1.综合荣誉统计1', id: 'id6-1', com: temp10, chartData: {title: '年份得分趋势图'}}, {name: '2.名师、名校长称号获取情况统计1', id: 'id6-2', com: temp11}, {name: '3.名师、名校长累计及人均统计', id: 'id6-2', com: ''}, {name: '4.名师工作室各级别统计1', id: 'id6-3', com: temp12}, {name: '4.名师工作室累计及人均统计', id: 'id6-3', com: ''}, ] }, { name: '七、总结', id: 'id7', com: temp13 }, { name: '八、建议', id: 'id7', com: temp14 } ]) let regionData = ref({}) let isReduce = ref(false) function getAreaRegionData() { postJson('/server/regionId/report/areaRegionData', {regionId: user.value.regionId, fileYear: '2025'}).then(res => { regionData.value = res isReduce.value = true }) } getAreaRegionData() const currentNodeKey = ref(null); const handleNodeClick = (data) => { currentNodeKey.value = data.id; nextTick(() => { const targetElement = document.getElementById(data.id); if (targetElement) { // 平滑滚动到目标元素 targetElement.scrollIntoView({ behavior: 'smooth', block: 'start' }); // 为了增强用户体验,添加一个临时的高亮效果 targetElement.classList.add('highlight'); setTimeout(() => { targetElement.classList.remove('highlight'); }, 1500); } }); } // 监听滚动事件,更新当前激活的菜单项 const handleScroll = () => { const sections = document.querySelectorAll('.main-section, .sub-section'); let current = ''; sections.forEach(section => { const sectionTop = section.offsetTop; const sectionHeight = section.clientHeight; if (window.pageYOffset >= (sectionTop - sectionHeight / 3)) { current = section.getAttribute('id'); } }); if (current && currentNodeKey.value !== current) { currentNodeKey.value = current; } }; // 添加滚动事件监听 window.addEventListener('scroll', handleScroll); // 组件卸载时移除事件监听 onUnmounted(() => { window.removeEventListener('scroll', handleScroll); }); </script> <style scoped> .areaReport2.page { overflow: hidden; display: flex; } .itemBox { width: 100%; min-height: 100px; margin-bottom: 50px; } .itBox { width: 100%; min-height: 100px; margin: 5px 0px; } el-container { height: 100%; display: flex; flex: 1; } .scrollable-content { flex: 1; overflow-y: auto; height: 100vh; } .fixed-sidebar { background-color: #f9fafc; border-right: 1px solid #ebeef5; padding: 10px; overflow-y: auto; /* 当菜单内容超出时显示滚动条 */ } .main-section { margin-bottom: 30px; padding: 20px; border-radius: 8px; transition: all 0.3s ease; } .sub-section { margin-top: 20px; margin-bottom: 20px; padding: 20px; border-radius: 8px; transition: all 0.3s ease; } h1 { text-align: center; } h2 { font-size: 22px; color: #333; margin-bottom: 15px; padding-bottom: 10px; } h3 { font-size: 18px; color: #333; margin: 10px 0px; padding: 8px 0px; } .content-placeholder { padding: 15px; border-radius: 4px; min-height: 150px; color: #909399; } .highlight { animation: highlightAnimation 1.5s ease-in-out; } </style> <style lang="less"> .areaReport2 { h4 { font-size: 16px; color: #333; text-indent: 2em; padding: 30px 0px; line-height: 32px } h1 { color: #333 } .el-table__header th { background-color: #4874cb !important; color: white; } .el-tree { height: 100%; padding: 20px 0px; box-sizing: border-box; } .el-main { padding: 0px 120px; } } </style> 左边滚动,右边tree对应高亮
最新发布
08-05
<think>我们有一个需:当左侧内容滚动时,右侧树形菜单的对应节点应该高亮。这类似于一个文档阅读器,左侧是内容,右侧是目录树,当阅读到某个章节时,目录树中对应的章节节点高亮。 参考已有的引用,我们可以得到一些思路: 1. 引用[1]和[3]提到了侧边栏高亮,通过设置`default-active`属性,并动态改变它来实现高亮。 2. 引用[2]提到了滚动监听,通过比较滚动位置与各个锚点的位置,来确定当前应该高亮的菜单项。 因此,我们可以将问题拆解为: - 在内容区域(左侧)设置多个锚点(每个章节对应一个id) - 监听内容区域的滚动事件,计算当前滚动位置,并找出当前位于视口中的章节 - 根据当前章节的id,设置右侧树形菜单的高亮节点 具体步骤: 1. **准备内容区域**:在内容区域,为每个章节标题设置一个唯一的id(作为锚点)。例如: ```html <div> <h2 id="section1">Section 1</h2> <p>Content...</p> <h2 id="section2">Section 2</h2> <p>Content...</p> <!-- ... --> </div> ``` 2. **准备树形菜单**:使用Element UI的树形控件(`el-tree`),并设置`highlight-current`属性为true,同时绑定`current-node-key`属性到一个变量(比如`currentNodeKey`)。树节点的`key`应该与内容区域的锚点id对应。 3. **监听滚动事件**:在内容区域的容器上监听滚动事件(可以使用`@scroll`事件)。在滚动时,计算当前滚动位置,并检查每个锚点元素的位置(相对于视口或容器顶部),判断哪个锚点当前处于激活状态(例如,在视口顶部附近)。 4. **确定当前激活的锚点**:我们可以通过比较每个锚点元素距离内容容器顶部的偏移量(offsetTop)与当前滚动位置(scrollTop)以及视口高度,来确定当前应该高亮的章节。通常,当锚点元素滚动到容器顶部时,我们就认为它被激活。但也可以设置一个阈值(比如距离顶部100px以内)。 5. **设置当前高亮节点**:一旦确定当前激活的锚点id,我们就将这个id赋值给`currentNodeKey`,树形控件就会自动高亮对应的节点。 6. **性能优化**:滚动事件触发频繁,可以使用节流(throttle)来减少处理次数。 7. **注意点**:在组件挂载后,我们需要获取所有锚点元素的位置信息(因为内容可能动态加载,所以最好在每次内容变化后重新获取)。同时,由于窗口大小改变可能导致锚点位置变化,可能需要监听窗口大小变化并重新计算。 代码结构示例: 在模板中: ```html <template> <div class="container"> <div class="content" @scroll="handleScroll"> <!-- 内容区域,每个章节有id --> <div v-for="section in sections" :key="section.id" :id="section.id"> <h2>{{ section.title }}</h2> <p>{{ section.content }}</p> </div> </div> <div class="tree"> <el-tree ref="tree" :data="treeData" node-key="id" :highlight-current="true" :current-node-key="currentNodeKey" @node-click="handleNodeClick" ></el-tree> </div> </div> </template> ``` 在脚本中: ```javascript export default { data() { return { sections: [...], // 内容数据 treeData: [...], // 树形菜单数据,每个节点的id与内容区域的id对应 currentNodeKey: '', // 当前高亮节点的key anchorPositions: [] // 存储每个锚点的位置信息(距离内容容器顶部的距离) }; }, mounted() { this.calculateAnchorPositions(); // 监听窗口大小变化,重新计算锚点位置 window.addEventListener('resize', this.calculateAnchorPositions); }, beforeDestroy() { window.removeEventListener('resize', this.calculateAnchorPositions); }, methods: { calculateAnchorPositions() { // 获取所有锚点元素 const anchors = this.$el.querySelectorAll('.content > [id]'); const container = this.$el.querySelector('.content'); // 计算每个锚点距离容器顶部的距离 this.anchorPositions = Array.from(anchors).map(anchor => { return { id: anchor.id, offsetTop: anchor.offsetTop // 相对于内容容器顶部的位置 }; }); }, handleScroll(event) { // 使用节流函数,这里简单实现,实际中可以用lodash的throttle if (!this.scrollTimer) { this.scrollTimer = setTimeout(() => { this.doHighlight(event.target); this.scrollTimer = null; }, 100); } }, doHighlight(container) { const scrollTop = container.scrollTop; // 添加一个偏移量(比如80px),这样当章节标题在容器顶部以下80px时,就算进入视野 const offset = 80; // 从最后一个锚点开始向前查找,找到第一个位于当前滚动位置上方的锚点 let currentAnchor = null; for (let i = this.anchorPositions.length - 1; i >= 0; i--) { if (scrollTop + offset >= this.anchorPositions[i].offsetTop) { currentAnchor = this.anchorPositions[i]; break; } } if (currentAnchor) { this.currentNodeKey = currentAnchor.id; } }, handleNodeClick(data) { // 点击树节点时,滚动到对应的内容区域 const element = document.getElementById(data.id); if (element) { this.$el.querySelector('.content').scrollTo({ top: element.offsetTop, behavior: 'smooth' }); } } } }; ``` 注意事项: - 由于内容区域可能动态变化(例如,异步加载内容),需要在内容变化后重新调用`calculateAnchorPositions`。 - 如果树节点很多,或者内容区域很大,注意性能问题。 以上是一个基本的实现思路。根据实际需,可能还需要调整高亮策略(例如,当多个章节同时在视口中时,高亮哪一个)。 相关问题: 1. 如何优化滚动监听事件以避免性能问题? 2. 如果内容区域是动态加载的,如何确保锚点位置计算准确? 3. 如何实现树形菜单的节点点击后平滑滚动到对应内容? 4. 在Vue中,如何监听容器大小变化(而不仅仅是窗口大小变化)?</think>### Vue Element UI 实现滚动内容同步高亮侧边栏树节点 #### 实现原理 1. **双向绑定机制** - 内容区域设置锚点(对应树节点ID) - 监听内容滚动位置,计算当前激活节点 - 通过动态绑定`current-node-key`更新树节点高亮状态 2. **核心步骤** ```html <template> <div class="container"> <!-- 左侧内容区域 --> <div class="content" ref="content" @scroll="handleScroll"> <div v-for="section in sections" :id="section.id" :key="section.id"> <h2>{{ section.title }}</h2> <p>{{ section.content }}</p> </div> </div> <!-- 右侧树形菜单 --> <el-tree ref="tree" :data="treeData" node-key="id" :highlight-current="true" :current-node-key="currentNodeKey" @node-click="handleNodeClick"> </el-tree> </div> </template> ``` ```javascript export default { data() { return { sections: [ // 内容区块数据 { id: 'node1', title: '章节1', content: '...' }, { id: 'node2', title: '章节2', content: '...' } ], treeData: [ // 树形菜单数据 { id: 'node1', label: '章节1' }, { id: 'node2', label: '章节2' } ], currentNodeKey: '', // 当前高亮节点 anchorPositions: [] // 存储锚点位置信息 } }, mounted() { this.calculateAnchorPositions(); window.addEventListener('resize', this.calculateAnchorPositions); }, beforeDestroy() { window.removeEventListener('resize', this.calculateAnchorPositions); }, methods: { // 计算所有锚点位置 calculateAnchorPositions() { this.$nextTick(() => { this.anchorPositions = this.sections.map(section => { const el = document.getElementById(section.id); return { id: section.id, offsetTop: el.offsetTop, height: el.clientHeight }; }); }); }, // 滚动事件处理 handleScroll() { const scrollTop = this.$refs.content.scrollTop; let activeNode = ''; // 查找当前激活节点(从后向前遍历) for (let i = this.anchorPositions.length - 1; i >= 0; i--) { const { id, offsetTop, height } = this.anchorPositions[i]; if (scrollTop + 50 >= offsetTop && scrollTop < offsetTop + height) { activeNode = id; break; } } if (activeNode && activeNode !== this.currentNodeKey) { this.currentNodeKey = activeNode; } }, // 节点点击事件 handleNodeClick(data) { const targetEl = document.getElementById(data.id); if (targetEl) { this.$refs.content.scrollTo({ top: targetEl.offsetTop - 20, behavior: 'smooth' }); } } } } ``` ```css .container { display: flex; height: 100vh; } .content { flex: 1; overflow-y: auto; padding: 20px; } .el-tree { width: 250px; border-left: 1px solid #ebeef5; } ``` #### 关键优化点 1. **性能优化** - 使用`requestAnimationFrame`节流滚动事件 ```javascript let isScrolling = false; handleScroll() { if (!isScrolling) { isScrolling = true; requestAnimationFrame(() => { // 滚动计算逻辑 isScrolling = false; }); } } ``` 2. **动态内容处理** - 内容变化时重新计算锚点位置: ```javascript watch: { sections: { deep: true, handler() { this.calculateAnchorPositions(); } } } ``` 3. **边界情况处理** - 底部区域高亮修正: ```javascript // 在handleScroll末尾添加 if (!activeNode && this.anchorPositions.length > 0) { const last = this.anchorPositions[this.anchorPositions.length - 1]; if (scrollTop + this.$refs.content.clientHeight >= last.offsetTop + last.height) { this.currentNodeKey = last.id; } } ``` #### 实现效果 - 内容滚动时自动高亮右侧树节点 - 点击树节点平滑滚动到对应内容区域 - 响应式布局适配不同屏幕尺寸 - 支持动态增减内容区块 > 此方案通过计算内容区块位置与滚动位置的关系实现精准高亮同步,同时通过双向绑定确保交互一致性。对于复杂树形结构,建议在树节点数据中添加`anchorId`字段建立映射关系[^1][^3]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值