易笔记易笔记
首页
文章
分类
标签
首页
文章
分类
标签
CSS高度塌陷问题

高度塌陷(Height Collapse)是 CSS 布局里常见的问题,通常在父元素包含浮动子元素时出现。下面详细解释该问题的成因、表现及解决办法。

问题成因

在正常的文档流中,父元素的高度默认会根据其包含的子元素内容自动调整,以包裹住所有子元素。不过,当子元素设置了 float 属性(如 float: left 或 float: right)后,这些子元素会脱离正常的文档流,不再占据原有的空间。此时,父元素在计算自身高度时,会忽略这些浮动的子元素,进而导致父元素高度变为 0 或者只包含非浮动子元素的高度,这就是高度塌陷问题。

表现示例

分类: CSS标签: CSS
日期: 2025/7/26
防抖(Debounce)与节流(Throttle)

在前端开发中,我们经常会遇到一些频繁触发的事件,如窗口的 resize、scroll,输入框的 input,鼠标的 mousemove 等。如果这些事件的处理函数执行频率过高,可能会导致页面卡顿、性能下降等问题。为了解决这些问题,我们可以使用两种常见的优化技术:防抖(Debounce)和节流(Throttle)。

什么是防抖(Debounce)

防抖是一种限制函数执行频率的技术,它确保函数在一段时间内只执行一次。当事件被触发时,函数并不会立即执行,而是等待一段时间,如果在这段时间内事件再次被触发,则重新计时。只有当事件停止触发一段时间后,函数才会真正执行。

分类: 前端标签: JS
日期: 2025/9/26
光标处插入文本

function insert() {
  let element = document.getElementById('text')
      let value = '_'
      // IE support
      if (document.selection) {
        console.log('ie')
        element.focus()
        let sel = document.selection.createRange()
        sel.text = value
      } else if (element.selectionStart || element.selectionStart === '0') { // MOZILLA and others
        console.log('modern')
        let startPos = element.selectionStart
        let endPos = element.selectionEnd
        element.value = element.value.substring(0, startPos) + value + element.value.substring(endPos, element.value.length)
        element.selectionStart = startPos + value.length
        element.selectionEnd = startPos + value.length
      } else {
        element.value += value
      }
}
分类: JS标签: JS
日期: 2022/5/19
移除匿名事件监听

window.addEventListener("onDrawSucceeded", function (c) {
      window.removeEventListener("onDrawSucceeded", arguments.callee)
 })
分类: JS标签: JS
日期: 2021/10/8
uni-app渲染后多一层嵌套问题

首先定义一个子组件my-component

问题

<template>
  <view class="dddd"></view>
</template>
分类: Vue3标签: Vue, Vue3, uni-app
日期: 2025/9/22
CSS: 外边距塌陷问题

现象:

现有两个div,上面的div设置margin-bottom:200px,下面的设置margin-top:100px,最终两个div距离却是200px。

原因:

当两个在标准流中相邻(兄弟或父子关系)的块级元素的外边距,组合在一起变成单个外边距,但只有上下外边距会发生塌陷。 计算方式: 1. 两个块margin都为正,取其较大的一个 2. 两个块magin都为负,取其绝对值较大的一个 3. 一个块为负,一个块为正,取两个块margin之和

分类: CSS标签: CSS
日期: 2021/11/21
安装lodash-es

pnpm install lodash-es --save
分类: Vue3标签: Vue, Vue3
日期: 2025/7/6
将弹窗组件封装成方法调用

import {
    createApp,
    h,
    ref,
    Component,
    ComponentInternalInstance
} from 'vue';
import AddDialog from './AddDialog.vue';
import ElementPlus from 'element-plus';
import 'element-plus/dist/index.css';

/**
 * 打开添加对话框
 * @param currentInstance - 当前组件实例
 * @param url - 请求接口地址
 * @param title - 对话框标题
 * @param config - 表单配置
 */
export const openAddDialog = (currentInstance: ComponentInternalInstance | null, url: string, title: string, config: any[]) => {
    // 创建用于挂载对话框的容器
    const container = document.createElement('div');
    document.body.appendChild(container);
    const parentApp = currentInstance?.appContext.app;

    // 定义对话框组件引用
    const dialogRef = ref<InstanceType<typeof AddDialog>>();

    // 创建 Vue 应用实例
    const app = createApp({
        setup() {
            // 渲染 AddDialog 组件
            return () => h(AddDialog, {
                ref: dialogRef,
                title,
                url,
                config,
                onClose: () => {
                    destroyDialog();
                }
            });
        }
    });

    if (parentApp) {
        // 继承全局属性
        Object.assign(app.config.globalProperties, parentApp.config.globalProperties);

        // 继承局部注册组件
        if (currentInstance) {
            // @ts-ignore 绕过 TypeScript 类型检查,获取内部组件定义
            const localComponents = currentInstance.type?.components || {};
            for (const [name, component] of Object.entries(localComponents)) {
                app.component(name, component as Component);
            }
        }
    }

    // 在应用实例中注册 Element Plus
    app.use(ElementPlus);

    // 定义销毁对话框的方法
    const destroyDialog = () => {
        app.unmount();
        document.body.removeChild(container);
    };

    // 挂载应用实例
    app.mount(container);

    // 打开对话框
    if (dialogRef.value) {
        dialogRef.value.open();
    }

    return {
        destroy: destroyDialog
    };
};

分类: Vue3标签: Vue, Vue3
日期: 2025/7/4

Cesium:向固定方向平移

/**
 * 获取移动位置
 * @param {Cesium.Cartesian3} start 开始位置
 * @param {Cesium.Cartesian3} direction 移动方向和距离
 * @returns {*}
 */
export const getMovePosition = (start, direction) => {
  return Cesium.Matrix4.multiplyByPoint(
    Cesium.Transforms.eastNorthUpToFixedFrame(
      start
    ),
    direction,
    new Cesium.Cartesian3()
  )
}
分类: cesium标签: cesium
日期: 2023/7/22
Cesium:为图形添加边框

翻遍Cesium文档未能发现border相关内容,但src支持canvas格式索性通过canvas添加图片。

/**
 * 为图形添加边框
 * @param entity cesium实体
 * @param url 图片地址
 * @param color 边框颜色
 */
export const addBorderToImage = (entity, url,color = 'green') => {
  const canvas = document.createElement('canvas');
  canvas.width = entity.billboard.width
  canvas.height = entity.billboard.height
  const ctx = canvas.getContext('2d')
  let image = new Image()
  image.crossOrigin = "anonymous";
  image.width = canvas.width
  image.height = canvas.height
  image.onload = () => {
    ctx.drawImage(image,0,0, canvas.width, canvas.height)
    ctx.strokeStyle = color
    ctx.lineWidth = 6
    ctx.rect(0,0,canvas.width,canvas.height)
    ctx.stroke()
    entity.billboard.image = canvas
  }
  image.src = url
}
分类: cesium标签: cesium
日期: 2023/3/25
Vue 3中ref和reactive的区别详解

在Vue 3的Composition API中,ref和reactive是创建响应式数据的两种主要方式。虽然它们都能实现响应式,但在使用场景和行为上存在一些重要区别。本文将详细探讨这两种API的异同点,帮助开发者更好地理解和使用它们。

ref和reactive的基本概念

ref

ref用于创建一个响应式的引用对象,它可以包装任何类型的值(基本类型或对象类型)。ref返回的对象有一个.value属性,指向内部的值。

分类: Vue标签: Vue 3, Composition API, ref, reactive
日期: 2025/9/26
PHP:发送本地请求死循环问题

原因

发送请求这个动作本身也是一个请求,必须等之前的请求发送完才会执行接下来请求,这就构成了死循环。

解决方案

开启多个php端口

upstream backend{    
    server 127.0.0.1:9123;    
    server 127.0.0.1:9124; 
} 
server 
  {    
  ...    
  location ~ \.php$ {      
    ...        
    fastcgi_pass backend;      
    ...     
  }     
... 
}
分类: PHP标签: PHP
日期: 2021/10/8
windows修改hosts

打开hosts

使用vs code 打开,保存时会提示用管理员权限。

C:\Windows\System32\drivers\etc\hosts
分类: Windows标签: Windows
日期: 2022/2/10
无窗口后台运行bat

文件头部加入一下代码

if "%1"=="h" goto begin
start mshta vbscript:createobject("wscript.shell").run("""%~nx0"" h",0)(window.close)&&exit
:begin
分类: Windows标签: Windows
日期: 2022/2/10
Windows远程桌面总是提示用户名或者密码错误

你好,感谢您联系微软社区!

了解到您远程桌面登入的问题,请尝试 Win + R 键,在运行框中输入 gpedit.msc 之后确定,打开组策略编辑器。

Windows 设置 -> 安全设置 -> 本地策略 -> 安全选项 -> 网络访问: 本地帐户的共享和安全模型。从 “仅来宾” 修改为 “经典” ,重启看看效果。

希望以上信息能帮助您!

分类: Windows标签: Windows
日期: 2022/2/10
用CSS实现点九图效果

.content{
  border-image-source: url(data:image/png;base64,...); // 图片路径
  border-image-slice: 10 10 10 10 fill; // 每个区域截取宽度为 10px
  border-image-width: 10px 10px 10px 10px; // 设置各个区域的图片宽度
  border-image-repeat: repeat; // 图片重复或拉伸模式
  border-image-outset: 10px 10px 10px 10px; // 
}
分类: CSS标签: CSS
日期: 2021/10/1
Vue中$set原理详解

在Vue开发中,我们经常会遇到这样的问题:直接通过索引设置数组项或者给对象添加新属性时,视图并没有更新。这时我们就需要使用Vue提供的$set方法来解决这个问题。本文将深入探讨Vue中$set的实现原理。

为什么需要$set?

在Vue的响应式系统中,并不是所有数据变化都能被检测到。主要有以下两种情况:

1. 数组索引直接设置

var vm = new Vue({
  data: {
    items: ['a', 'b', 'c']
  }
})

// 这种方式不会触发响应
vm.items[1] = 'x'
分类: Vue标签: Vue
日期: 2025/9/26

当素材尺寸(宽和高)不是2的n次方时,贴图效果会较为模糊。 控制台会有如下警告:

THREE.WebGLRenderer: image is not power of two (1638x2166). Resized to 1024x2048

解决方案:对贴图做如下设置

texture.generateMipmaps = false;
texture.wrapS = texture.wrapT = THREE.ClampToEdgeWrapping;
texture.minFilter = THREE.LinearFilter
分类: ThreeJS标签: ThreeJS, 3D
日期: 2021/10/1
Electron:绕过B站防盗链验证

原理:将头部referer字段修改为网站信任的白名单,比如:百度

import { app, BrowserWindow, shell, session } from 'electron'

const filter = {
    urls: ['*.hdslb.com/*']
  }
  session.defaultSession.webRequest.onBeforeSendHeaders(filter, (details, cb) => {
    console.log(details)
    details.requestHeaders['referer'] = 'https://www.baidu.com'
    let data = { requestHeaders: details.requestHeaders }
    cb(data)
  })
分类: Electron标签: CSS
日期: 2021/12/21
搭建KMS服务器激活Win10和Office

安装

git clone https://github.com/myanaloglife/py-kms.git
分类: Windows标签: Windows, KMS
日期: 2021/10/8
CSS: 自定义滚动条

&::-webkit-scrollbar-button{
    background-color: #074337;
    background-size: 18px;
    background-position: center;
    background-repeat: no-repeat;
    &:horizontal {
      &:start:decrement{ // 水平左侧(垂直上侧)“减”按钮
        display: block;
        background-image: url("~@/assets/images/icon/icon_sanjiao_left.png"); 
      }
      &:start:increment{ // 水平左侧(垂直上侧)“加”按钮
        display: none;
      }
      &:end:decrement{ // 水平右侧(垂直下侧)“减”按钮
        display: none;
      }
      &:end:increment{ // 水平右侧(垂直下侧“加”按钮
        display: block;
        background-image: url("~@/assets/images/icon/icon_sanjiao_right.png");
      }
    }

  }
  &::-webkit-scrollbar {
    /*滚动条整体样式*/
    height: 2rem;
    display: block;
  }
  &::-webkit-scrollbar-thumb {
    /*滚动条里面小方块*/
    background   : #097b64;
    border-bottom: solid 2px #074337;
    border-top: solid 2px #074337;
  }
  &::-webkit-scrollbar-track {
    /*滚动条里面轨道*/
    padding: 2px 0;
    background   : #074337;
  }
分类: CSS标签: CSS
日期: 2021/10/1
方案一:多列布局

Multiple-column layout 文档

实现步骤

设置父容器(content)的column-count用来指定列数,接着将子容器的img标签宽和高均设置为100%

示例

在线示例 样式(less)

分类: CSS标签: CSS
日期: 2022/6/29
Less中使用calc()问题

height:calc(100% - 32px);
分类: CSS标签: CSS
日期: 2021/12/21
Vue中的nextTick原理详解

在Vue开发中,我们经常会遇到这样的场景:修改数据后立即操作DOM却发现DOM还未更新。这时我们就需要使用nextTick来解决这个问题。本文将深入探讨Vue中nextTick的实现原理。

什么是nextTick?

Vue在更新DOM时是异步执行的,只要侦听到数据变化,Vue将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。如果同一个watcher被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和DOM操作是非常重要的。

然后,在下一个的事件循环"tick"中,Vue刷新队列并执行实际(已去重的)工作。Vue在内部对异步队列尝试使用原生的Promise.then、MutationObserver和setImmediate,如果执行环境不支持,则会采用setTimeout(fn, 0)代替。

分类: Vue标签: Vue
日期: 2025/9/26