Java OFFSET函数详解:定位与尺寸计算

需积分: 15 3 下载量 172 浏览量 更新于2024-09-14 收藏 3KB TXT 举报
在Java编程中,OFFSET函数是一个关键的概念,主要用于处理DOM(Document Object Model)元素的位置和大小计算,它在处理页面布局和事件处理时扮演着重要角色。这个函数的主要功能是基于一个给定的参照点,通过提供特定的偏移量来获取一个新的元素位置或者坐标。它支持单个单元格或多个单元格组成的区域,并且可以指定返回的行数或列数。 OFFSET函数的核心参数包括: 1. `offsetParent`: 表示当前元素的父级元素,用于计算偏移量。 2. `offsetLeft` 和 `offsetTop`: 分别表示元素相对于其offsetParent的水平和垂直偏移量,这两个值通常用来确定元素在屏幕上的准确位置。 3. `offsetWidth` 和 `offsetHeight`: 表示元素的宽度和高度,包括padding和border,但不包括滚动条或边框之外的空间。 4. `clientWidth` 和 `clientHeight`: 返回元素在浏览器窗口中的可视部分的实际宽度和高度,这不包括滚动条占用的空间。 5. `scrollWidth` 和 `scrollHeight`: 返回元素可滚动区域的总宽度和高度,包括被隐藏的内容。 6. `scrollTop` 和 `scrollLeft`: 在某些情况下,表示滚动条在垂直和水平方向上移动的距离,可用于触发滚动事件。 在JavaScript中,例如在处理鼠标事件(如`event.clientX` 和 `event.clientY`),OFFSET函数与这些属性紧密关联,因为它们可以帮助开发者确定用户点击或滚动的确切位置,与文档的结构相对应。例如: - `event.clientX + document.documentElement.scrollTop` 给出了鼠标指针相对于视口的绝对位置。 - IE浏览器(如IE6.0和更低版本)与Firefox等现代浏览器对`clientWidth`和`clientHeight`的计算有所不同,这反映了浏览器之间的兼容性差异。 理解OFFSET函数及其相关属性对于创建响应式设计、优化用户体验以及实现跨浏览器的交互效果至关重要。熟练掌握这些概念有助于编写更高效、兼容性更好的代码,尤其是在处理复杂的网页布局和动画效果时。

这代码后输入01返回02 ,输入02返回04,输入03返回06#include "stm32f10x.h" #include "stm32f10x.h" #define BIT_TIME 104 // 9600bps对应位时间(us) #define SAMPLE_OFFSET 52 // 采样点在中段位置 // 状态机定义 typedef enum { IDLE, TRANSMITTING, RECEIVING } UART_State; volatile UART_State tx_state = IDLE; volatile UART_State rx_state = IDLE; volatile uint8_t tx_data = 0; volatile uint8_t rx_data = 0; volatile uint8_t bit_pos = 0; // GPIO初始化 void GPIO_Config(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; // TX引脚配置 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // RX引脚配置 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); } // 定时器初始化 void TIM2_Config(void) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); TIM_TimeBaseInitTypeDef TIM_InitStructure; TIM_InitStructure.TIM_Period = 103; // 72MHz/72=1MHz => 1μs分辨率 TIM_InitStructure.TIM_Prescaler = 71; // 每104μs中断 TIM_InitStructure.TIM_ClockDivision = 0; TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_InitStructure); TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); NVIC_EnableIRQ(TIM2_IRQn); } // 发送单字节 void SoftUART_Transmit(uint8_t data) { if(tx_state == IDLE) { tx_data = data; tx_state = TRANSMITTING; bit_pos = 0; GPIO_ResetBits(GPIOA, GPIO_Pin_0); // 发送起始位 TIM_Cmd(TIM2, ENABLE); } } // 接收回调函数(数据就绪时调用) __weak void SoftUART_RxCallback(uint8_t data) { SoftUART_Transmit(data); // 回传接收到的数据 } // 定时器中断服务函数 void TIM2_IRQHandler(void) { static uint8_t rx_bitpos = 0; if(TIM_GetITStatus(TIM2, TIM_IT_Update)) { TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // 发送处理 if(tx_state == TRANSMITTING) { if(++bit_pos <= 9) { GPIO_WriteBit(GPIOA, GPIO_Pin_0, (tx_data >> (bit_pos-1)) & 0x01); } else { GPIO_SetBits(GPIOA, GPIO_Pin_0); // 停止位 tx_state = IDLE; TIM_Cmd(TIM2, DISABLE); } } // 接收处理 if(rx_state == RECEIVING) { if(++bit_pos == 1) { TIM_SetAutoreload(TIM2, BIT_TIME - 1); // 后续按完整位时间采样 } if(bit_pos >=1 && bit_pos <=8) { rx_data |= (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1) << (bit_pos - 1)); } else { TIM_Cmd(TIM2, DISABLE); rx_state = IDLE; SoftUART_RxCallback(rx_data); rx_data = 0; } } } } // RX引脚外部中断(检测起始位) void EXTI1_IRQHandler(void) { if(EXTI_GetITStatus(EXTI_Line1) != RESET) { EXTI_ClearITPendingBit(EXTI_Line1); if(rx_state == IDLE) { rx_state = RECEIVING; bit_pos = 0; rx_data = 0; TIM_SetAutoreload(TIM2, SAMPLE_OFFSET - 1); // 首次延迟半位时间 TIM_Cmd(TIM2, ENABLE); } } } // 主函数 int main(void) { GPIO_Config(); TIM2_Config(); // 配置RX引脚外部中断 EXTI_InitTypeDef EXTI_InitStruct; EXTI_InitStruct.EXTI_Line = EXTI_Line1; EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStruct.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStruct); NVIC_EnableIRQ(EXTI1_IRQn); while(1) { // 主循环可执行其他任务 } }

2025-03-12 上传