当前位置: 首页 > news >正文

网站建设长期待摊费用重庆seo网页优化

网站建设长期待摊费用,重庆seo网页优化,网上学电脑培训中心,大型网站构建实施方案效果图 说明 下面会贴出组件代码以及一个Demo&#xff0c;上面的效果图即为Demo的效果&#xff0c;建议直接将两份代码拷贝到自己的开发环境直接运行调试。 组件代码 <template><!-- 鼠标画矩形选择对象 --><div class"objects" ref"objectsR…

效果图

效果图

说明

下面会贴出组件代码以及一个Demo,上面的效果图即为Demo的效果,建议直接将两份代码拷贝到自己的开发环境直接运行调试。

组件代码

<template><!-- 鼠标画矩形选择对象 --><div class="objects" ref="objectsRef" @mousedown="handleMouseDown"><!-- 矩形选择框 --><divclass="mask"ref="maskRef"v-show="maskPosition.show":style="'width:' +maskWidth +'left:' +maskLeft +'height:' +maskHeight +'top:' +maskTop"/><!-- 选择对象内容的目标插槽 --><slot name="selcetObject" /></div>
</template><script lang="ts" setup>
import { reactive, toRefs, ref, computed } from "vue";const props = withDefaults(defineProps<{objectClassName: string; // 选择对象的class name,用于定义如何获取对象objectIdName: string; // 选择对象的id name,用于定义如何获取对象的idselectObjectIds?: Array<string>; // 选中的对象IDselectObjects?: Array<HTMLElement>; // 选中的对象useCtrlSelect?: boolean; // 是否支持按住Ctrl多选}>(),{useCtrlSelect: true // 默认支持按住Ctrl多选}
);const objectsRef = ref();
const maskRef = ref();
const emits = defineEmits(["update:selectObjects", "update:selectObjectIds"]);
const state = reactive({maskPosition: {show: false,startX: 0,startY: 0,endX: 0,endY: 0}, // 矩形框位置isPressCtrlKey: false // 是否按下了Ctrl键
});
const { maskPosition, isPressCtrlKey } = toRefs(state);// 若支持按住Ctrl多选,监听Ctrl事件
if (props.useCtrlSelect) {// 释放document.addEventListener("keyup", event => {if (event.keyCode === 17) {isPressCtrlKey.value = false;}});// 按下document.addEventListener("keydown", event => {if (event.keyCode === 17) {isPressCtrlKey.value = true;}});
}/** 鼠标按下 */
const handleMouseDown = event => {// 展示矩形框,通过坐标位置来画出矩形maskPosition.value.show = true;maskPosition.value.startX = event.clientX;maskPosition.value.startY = event.clientY;maskPosition.value.endX = event.clientX;maskPosition.value.endY = event.clientY;// 监听鼠标移动事件和抬起离开事件objectsRef.value.addEventListener("mousemove", handleMouseMove);objectsRef.value.addEventListener("mouseup", handleMouseUp);
};/** 鼠标移动 */
const handleMouseMove = event => {maskPosition.value.endX = event.clientX;maskPosition.value.endY = event.clientY;
};/** 鼠标抬起离开 */
const handleMouseUp = () => {// 移除鼠标监听事件objectsRef.value.removeEventListener("mousemove", handleMouseMove);objectsRef.value.removeEventListener("mouseup", handleMouseUp);maskPosition.value.show = false;handleResetMaskPosition();handleGetSelectObject();
};/** 获取选择的对象 */
const handleGetSelectObject = () => {// 选中对象ID和对象元素let tempSelectObjectIds: Array<string> = [];let tempSelectObjects: Array<HTMLElement> = [];// 如果按下了Ctrl键,之前选择的数据不清空if (isPressCtrlKey.value) {tempSelectObjectIds =props.selectObjectIds === undefined ? [] : props.selectObjectIds;tempSelectObjects =props.selectObjects === undefined ? [] : props.selectObjects;}// 获取鼠标画出的矩形框位置const rectanglePosition = maskRef.value.getClientRects()[0];// 获取所有选择区域的对象; 这里获取的元素的方式定义于父组件的objectClassNameconst selectedObjects = objectsRef.value.querySelectorAll(`.${props.objectClassName}`);// 遍历对象,获取到每个对象的坐标位置,判断该位置是否在上面获取到的鼠标画矩形的框的位置中selectedObjects.forEach(item => {const objectPosition = item.getClientRects()[0];// 这里获取的id的方式定义于父组件的objectIdNameif (compareObjectPosition(objectPosition, rectanglePosition)) {const id = item.getAttribute(props.objectIdName);// 如果按下了Ctrl键if (isPressCtrlKey.value) {// 已被选中的需要被取消选中if (tempSelectObjectIds.includes(id)) {tempSelectObjectIds = tempSelectObjectIds.filter(a => a != id);tempSelectObjects = tempSelectObjects.filter(a => a != item);} else {tempSelectObjectIds.push(id);tempSelectObjects.push(item);}} else {tempSelectObjectIds.push(id);tempSelectObjects.push(item);}}});// 回传到父组件emits("update:selectObjects", tempSelectObjects);emits("update:selectObjectIds", tempSelectObjectIds);
};/*** 判断对象坐标是否在鼠标画出的矩形框坐标位置内* @param objectPosition 对象坐标位置* @param rectanglePosition 鼠标画出的矩形框坐标位置*/
const compareObjectPosition = (objectPosition, rectanglePosition) => {const maxX = Math.max(objectPosition.x + objectPosition.width,rectanglePosition.x + rectanglePosition.width);const maxY = Math.max(objectPosition.y + objectPosition.height,rectanglePosition.y + rectanglePosition.height);const minX = Math.min(objectPosition.x, rectanglePosition.x);const minY = Math.min(objectPosition.y, rectanglePosition.y);return (maxX - minX <= objectPosition.width + rectanglePosition.width &&maxY - minY <= objectPosition.height + rectanglePosition.height);
};/** 重置鼠标位置 */
const handleResetMaskPosition = () => {maskPosition.value.startX = 0;maskPosition.value.startY = 0;maskPosition.value.endX = 0;maskPosition.value.endY = 0;
};/** 通过鼠标位置实时计算矩形框大小 */
const maskWidth = computed(() => {return `${Math.abs(maskPosition.value.endX - maskPosition.value.startX)}px;`;
});
const maskHeight = computed(() => {return `${Math.abs(maskPosition.value.endY - maskPosition.value.startY)}px;`;
});
const maskLeft = computed(() => {return `${Math.min(maskPosition.value.startX, maskPosition.value.endX)}px;`;
});
const maskTop = computed(() => {return `${Math.min(maskPosition.value.startY, maskPosition.value.endY)}px;`;
});
</script><style scoped lang="scss">
.objects {height: 100%;width: 100%;overflow-y: auto;.mask {position: fixed;background: #409eff;opacity: 0.4;z-index: 100;}
}
</style>

Demo

建议直接将上面组件命名为 MouseDrawRectangle

<template><!------------- 鼠标画矩形选择对象组件DEMO,可以直接拷贝到你的页面去运行-----------------------><div class="content"><!-- MouseDrawRectangle说明:objectClassName绑定到下面对象class名称; objectIdName名称对应object_id;useCtrlSelect默认是打开的,用于按住Ctrl键进行多选,以及取消已选择的对象。selectObjectIds会实时从子组件更新过来,监听它的值来控制页面的选择状态即可。另外有参数selectObjects会实时从子组件传回被选中的对象Dom信息--><MouseDrawRectangleobjectClassName="select_object"objectIdName="object_id":useCtrlSelect="true"v-model:selectObjectIds="selectObjectIds"v-model:selectObjects="selectObjects"><!-- 这个是插槽,将业务内容的Dom限制在MouseDrawRectangle组件内,这样可以将后面组件所有的监听事件绑定到组件上而不是整个页面Dom上,鼠标滑动的区域也会限制死在组件内,而不是整个页面的范围 --><template #selcetObject><div class="objects_content"><!-- 每一个选择的目标对象 --><divv-for="item in 50":key="item"class="select_object":object_id="item":class="selectObjectIds.includes(item.toString()) ? 'is_selected' : ''">{{ item }}</div></div></template></MouseDrawRectangle></div>
</template><script lang="ts" setup>
import { reactive, toRefs, watch } from "vue";
import MouseDrawRectangle from "@/components/objectSelect/mouseDrawRectangle.vue";const state = reactive({selectObjectIds: [] as Array<string>, // 选中的对象IDselectObjects: [] as Array<HTMLElement> // 选中的对象DOM
});
const { selectObjectIds, selectObjects } = toRefs(state);watch(() => [selectObjectIds.value, selectObjects.value],() => {console.log("选中的ID=>", selectObjectIds);console.log("选中的Dom=>", selectObjects);}
);
</script><style scoped lang="scss">
.content {// 因为使用flex布局,最下面一行盒子换行只会出现一半的高度,这里最好减去下每个盒子的高度height: calc(100% - 50px);overflow-y: auto;padding: 20px;.objects_content {user-select: none;display: flex;flex-wrap: wrap;gap: 10px;margin-bottom: 10px;// 盒子样式> div {width: 200px;height: 100px;background-color: #999;}.is_selected {color: #fff;box-sizing: border-box;border: 3px #317aff solid;border-radius: 5px;}}
}
</style>
http://www.15wanjia.com/news/155350.html

相关文章:

  • 做网站一班需要多少钱婚庆公司创业计划书
  • 苏州网站定制公司哪家好php网站屏蔽词怎么做
  • 搭建什么网站好玩推广工具
  • 2017年免费建网站如何将微信公众号文章转wordpress
  • 中英文微信网站开发法律电商如何做网站推广营销
  • 网站个人和公司有什么区别是什么网站建设需求分析
  • 网上购物商城网站海外网络是什么意思
  • 网站备案审核制度深圳有没有维护公司网站
  • 制作宝安网站建设免费游戏推广平台
  • 导航网站怎么赚钱手机微信网页版登录
  • 注销主体备案与网站备案广安专业网站建设报价
  • 做橡胶应该看什么网站广东网站建设专业公司
  • 网站导航三角怎么做怎么分析网站用什么技术做的
  • 做网站特别简单的软件广告投放需要什么资质
  • 北京网络营销招聘重庆网站优化排名
  • 网站色彩的搭配原则有哪些平度做网站
  • 备案后怎么建设网站去哪儿网站开发
  • 网站建设岗位要求seo流量查询
  • 打开网站乱码怎么做青岛开发区网站制作
  • 网站制作流程的组成部分包括seo服务商找行者seo
  • 做网站哪里便宜网站建设费会计
  • 网站后台改成只有一个管理员登陆天元建设集团有限公司企业号
  • wordpress 网站重置用ps怎么做网站步骤
  • 做优惠卷网站倒闭了多少山东省建设工程执业资格中心网站
  • c2c网站有哪几个软件培训
  • 教育营销型的网站建设品牌形象
  • 在线生成app网站源码长沙做一个网站要多少钱
  • 云服务器做淘客网站网站建设绩效目标
  • 专业的铁岭做网站公司上海品牌营销策划公司排名
  • 自媒体135网站免费下载安装江西企业网站定制