attr(),prop(),data()三者之间的差别

本文详细对比了jQuery中attr(), prop()和data()三种方法的使用场景和区别,包括它们如何操作DOM属性,参数书写格式,返回值类型及性能考量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.attr(),prop()会直接操作dom节点的属性,通过审查元素可以直观的看到,data()则将属性保存在内存中,审查元素不能看到。

2.参数的书写格式。attr(),prop()需要写完整的属性名,不能修改;data()必须是属性名去掉data再以驼峰方式命名。

3.返回值。

     attr(),返回String,prop()返回jQuery;

     data(),不传参数,会返回一个对象,这个对象包含了元素本身的属性以及data()操作过的属性,通过attr(),prop()操作的属性应为规范问题可能不会返回。

举个栗子:

html:

<div id="bar" data-aa-bb="'cc" ee-ff="gg" data-test="test">test</div>

jq:

$('#bar').attr('data-test','0');
$('#bar').attr('ee-ff','b');
console.log($('#bar').data());

此时可以通过审查元素看到当前的元素状态为

<div id="bar" data-aa-bb="'cc" ee-ff="b" data-test="0">test</div>

返回值为:

  1. {test: 0, aaBb: "'cc"}
    1. aaBb: "'cc"
    2. test: 0

细心的你会发现,ee-ff不会被data()筛选出来,但是在dom元素上该属性已经被重新赋值,这就是书写规范的问题,所以特别注意不要3种方式同时使用,特别容易产生混淆。

4.若要检索和更改DOM属性,比如元素的checked, selected, 或 disabled状态,请使用.prop()方法(就是当你发现attr()修改无效的时候,可以尝试prop()....)

如果设置的属性值比较复杂,尤其是包含引号双引号的数据,不建议使用attr(),prop(),应为它容易破坏dom元素的结构,使代码不能正常解析,另外性能方面个人觉得data()的性能会好一点。所以推荐大家使用data();

[TOC] ## 二、新增分区 ### 1、分区表 ``` # vendor\mediatek\proprietary\tools\ptgen\MT6739\partition_table_emmc.csv tectoy_ext Raw data 8192 EMMC_USER N N None N N N N N N AUTO ``` ### 2、分区信息 ``` # vendor\mediatek\proprietary\hardware\fstab\mt6739\fstab.in.mt6739 DEVPATH(tectoy_ext) /tectoy_ext FSTYPE_RAW FS_FLAG_DATA FSMGR_FLAG_DATA ``` ### 3、分区权限 ``` # system\core\rootdir\init.rc chown system system /tectoy_ext chmod 0755 /tectoy_ext ``` ## 三、新增开机服务 ### 1、fill_tectoy_ext ``` # Android.mk ############################################################################### # Copyright:Xchengtech # Owner:Mars.han # Date:2023-03-27 # Version V1.0 ############################################################################### LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := \ fill_tectoy_ext.c LOCAL_C_INCLUDES := \ system/core/include/cutils LOCAL_SHARED_LIBRARIES := \ libcutils LOCAL_PROPRIETARY_MODULE := true LOCAL_CFLAGS += -pie -fPIE LOCAL_LDFLAGS += -pie -fPIE LOCAL_INIT_RC := fill_tectoy_ext.rc LOCAL_MODULE := fill_tectoy_ext include $(BUILD_EXECUTABLE) ``` ``` # fill_tectoy_ext.rc service fill_tectoy_ext /vendor/bin/fill_tectoy_ext class main user root group root oneshot on property:vendor.xc.start.fill_tectoy_ext=1 start fill_tectoy_ext on property:vendor.xc.start.fill_tectoy_ext=0 stop fill_tectoy_ext ``` ``` # fill_tectoy_ext.c /* * Copyright: Xchengtech * Owner: Mars.Han * Date: 2023-03-22 * Version: v1.0 * Purpose:Convert bitmap to raw data adn write to logo_ext partiotion */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "properties.h" //#include <math.h> #define TECTOY_EXT_PARTITION "/dev/block/by-name/tectoy_ext" #define TECTOY_PROP_LOCK_STATUS "vendor.xc.status.fill_tectoy_ext" #define SYS_PROP_TECTOY_RESULT "vendor.xc.fill_tectoy_ext" typedef unsigned char uint8; typedef unsigned short uint16; typedef unsigned int uint32; uint32 main(int argc, char* argv[]) { uint32 i = 0; uint32 j = 0; uint32 k = 0; char lockPropValue[PROPERTY_VALUE_MAX] = {0}; const uint8* output_file = TECTOY_EXT_PARTITION; const char* default_lock_value = "0"; property_set(SYS_PROP_TECTOY_RESULT, "1"); int length = property_get(TECTOY_PROP_LOCK_STATUS, lockPropValue, default_lock_value); if (length == 0) { property_set(SYS_PROP_TECTOY_RESULT, "2"); return -1; } printf("property_get: %s\n", lockPropValue); FILE* out_fp = fopen(output_file, "wb"); if (!out_fp) { printf("Failed to create file: %s\n", output_file); property_set(SYS_PROP_TECTOY_RESULT, "3"); return -1; } //Write tectoy_ext header uint32 head_buffer[4] = {0x92, 1, 0, 0}; head_buffer[2] =lockPropValue[0]; fwrite(head_buffer, 1, sizeof(head_buffer), out_fp); fclose(out_fp); property_set(SYS_PROP_TECTOY_RESULT, "0"); return 0; } ``` ### 2、Selinux权限 ``` # attributes attribute xc_vendor_property_type; ``` ``` # domain.te get_prop(domain, xc_vendor_property_type) ``` ``` # file_contexts /vendor/bin/fill_tectoy_ext u:object_r:fill_tectoy_ext_exec:s0 /tectoy_ext(/.*)? u:object_r:transire_file:s0 /dev/block/platform/bootdevice/by-name/tectoy_ext u:object_r:transire_block_device:s0 ``` ``` # property.te vendor_restricted_prop(vendor_xc_fill_tectoy_ext_prop) typeattribute vendor_xc_fill_tectoy_ext_prop xc_vendor_property_type; ``` ``` # property_contexts vendor.xc.fill_tectoy_ext u:object_r:vendor_xc_fill_tectoy_ext_prop:s0 ``` ``` # fill_tectoy_ext.te ############################################################################### # Copyright:Xchengtech # Owner:yiping.huang # Date:2023-4-5 # Version V1.0 ############################################################################### # ============================================== # Policy File of /vendor/bin/fill_tectoy_ext Executable File # ============================================== # Type Declaration # ============================================== type fill_tectoy_ext_exec,exec_type,file_type,vendor_file_type; #type fill_tectoy_ext,domain; type fill_tectoy_ext,domain,xc_domain; init_daemon_domain(fill_tectoy_ext) # ============================================== # Policy Rule # ============================================== allow fill_tectoy_ext self:capability chown; allow fill_tectoy_ext self:capability dac_override; allow fill_tectoy_ext self:capability dac_read_search; allow fill_tectoy_ext mnt_user_file:dir { search }; allow fill_tectoy_ext mnt_user_file:lnk_file { read }; allow fill_tectoy_ext fuse:dir { search }; allow fill_tectoy_ext fuse:file { getattr read open }; allow fill_tectoy_ext sysfs_boot_mode:file { read open }; allow fill_tectoy_ext sysfs_boot_type:file { read open }; allow fill_tectoy_ext sysfs_mm:dir { search }; allow fill_tectoy_ext mnt_sdcard_file:lnk_file { read }; allow fill_tectoy_ext transire_file:dir { search }; allow fill_tectoy_ext transire_file:file { read open getattr }; allow fill_tectoy_ext block_device:dir { search }; allow fill_tectoy_ext transire_block_device:blk_file { open write getattr }; allow fill_tectoy_ext property_socket:sock_file { write }; allow fill_tectoy_ext init:unix_stream_socket { connectto }; #allow fill_tectoy_ext vendor_default_prop:property_service { set }; set_prop(fill_tectoy_ext, vendor_xc_fill_tectoy_ext_prop) ``` ## 四、控制下载 ### 1、增加宏开关 ``` 文件:ProjectConfig.mk 增加:FEATRUE_TRANSIRE_DOWNLOAD_LOCK=yes ``` ``` 文件:k39tv1_bsp_1g.mk 路径:vendor\mediatek\proprietary\bootable\bootloader\preloader\custom\k39tv1_bsp_1g\ 增加:FEATRUE_TRANSIRE_DOWNLOAD_LOCK=yes export FEATRUE_TRANSIRE_DOWNLOAD_LOCK ``` ``` 文件:feature.mak 路径:vendor\mediatek\proprietary\bootable\bootloader\preloader\platform\mt6739\ 增加:ifeq ("$(FEATRUE_TRANSIRE_DOWNLOAD_LOCK)","yes") C_OPTION += -DCFG_TECTOY_DOWNLOAD_lOCK endif ``` ### 2、控制代码 ``` # download.h # vendor\mediatek\proprietary\bootable\bootloader\preloader\platform\mt6739\src\core\inc\ #define XC_TECTOY_LOCK "TECTOYLOCK" extern unsigned int xc_load_tectoy_img(void); ``` ``` # download.c # vendor\mediatek\proprietary\bootable\bootloader\preloader\platform\mt6739\src\core\ //XCSW add for Block OS downgrade #define RAW_START_PREFIX 0x92 #define DOWNLOAD_UNLOCK 0x31 #define DOWNLOAD_RETRY_TIMES 4 #define HEADER_LEN 4 unsigned int xc_load_tectoy_img(void) { unsigned int tectoy_header[HEADER_LEN] = {0}; unsigned int ret = -1; unsigned int header_size = 0; unsigned int tectoy_flag = 0; unsigned int tectoy_size = 0; unsigned int tectoy_value = 0; unsigned int tectoy_retry = 0; //判断分区是否存在 if(!partition_exists("tectoy_ext")) { return 0; } header_size = sizeof(tectoy_header) * sizeof(unsigned char); //读分区 partition_read("tectoy_ext", 0, (unsigned char *)tectoy_header, header_size); tectoy_flag = tectoy_header[0]; tectoy_size = tectoy_header[1]; tectoy_value = tectoy_header[2]; tectoy_retry = tectoy_header[3]; if((RAW_START_PREFIX == tectoy_flag) && (tectoy_size > 0) && (DOWNLOAD_UNLOCK == tectoy_value)) { tectoy_header[3] = 0; ret = 0; } else if (DOWNLOAD_RETRY_TIMES == tectoy_retry) { tectoy_header[3] = 0; ret = 0; } else { tectoy_header[3] = tectoy_retry + 1; } //写分区 partition_write("tectoy_ext", 0, (unsigned char *)tectoy_header, header_size); return ret; } ``` ``` # handshake_usb.c # vendor\mediatek\proprietary\bootable\bootloader\preloader\platform\mt6739\src\core\ #ifdef CFG_TECTOY_DOWNLOAD_lOCK if (*ptr == 0xa0 && xc_load_tectoy_img() != 0) { mt_usbtty_puts(XC_TECTOY_LOCK); return FALSE; } #endif ``` ## 五、下载版本代码流程 ​ 目录:vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt6739/ ### 1、USB握手 ``` // main.c void main(u32 *arg) { ...... BOOTING_TIME_PROFILING_LOG("before bldr_handshake"); bldr_handshake(&handler); //握手 BOOTING_TIME_PROFILING_LOG("bldr_handshake"); ...... } static int bldr_handshake(struct bldr_command_handler *handler) { ...... switch (mode) { case NORMAL_BOOT: if (TRUE == isSLA) { handler->attr |= CMD_HNDL_ATTR_COM_FORBIDDEN; pal_log_info("%s META DIS\n", MOD); } if (!isLocked) { pal_log_info("%s Tool connection is unlocked\n", MOD); #if CFG_USB_TOOL_HANDSHAKE if (TRUE == usb_handshake(handler)) //USB握手 g_meta_com_type = META_USB_COM; BOOTING_TIME_PROFILING_LOG("USB handshake"); #endif #if CFG_UART_TOOL_HANDSHAKE if (TRUE == uart_handshake(handler)) //UART握手 g_meta_com_type = META_UART_COM; BOOTING_TIME_PROFILING_LOG("UART handshake"); #endif } else { pal_log_info("%s Tool connection is locked\n", MOD); bootarg.sec_limit.magic_num = SEC_LIMIT_MAGIC; bootarg.sec_limit.forbid_mode = F_FACTORY_MODE; } break; ...... } // 根据接收的命令进入不同模式 static bool bldr_cmd_handler(struct bldr_command_handler *handler, struct bldr_command *cmd, struct bldr_comport *comport) { ...... if (CMD_MATCH(cmd, ATCMD_PREFIX)) { // AT+XXX ...... } else if (CMD_MATCH(cmd, META_STR_REQ)) { // meta模式 ...... } else if (CMD_MATCH(cmd, FACTORY_STR_REQ)) { ...... } else if (CMD_MATCH(cmd, META_ADV_REQ)) { ...... } else if (CMD_MATCH(cmd, ATE_STR_REQ)) { ...... } else if (CMD_MATCH(cmd, FB_STR_REQ)) { ...... } else { pal_log_warn("%s unknown received: \'%s\'\n", MOD, cmd->data); return FALSE; } ...... } ``` ### 2、USB通讯 ``` //handshake_usb.c bool usb_handshake(struct bldr_command_handler *handler) { ...... //等待USB连接 if (usb_connect(enum_tmo) == FALSE) { //USB连接超时 pal_log_warn("%s USB enum timeout!\n", MOD); goto end; } udelay(1000); //如果连接成功,则进行usb通讯 if (FALSE == usb_handshake_handler(handler, handshake_tmo)) { goto end; } ...... } static bool usb_handshake_handler(struct bldr_command_handler *handler, uint32 tmo) { ...... if (FALSE == usb_listen(&comport, buf, HSHK_TOKEN_SZ, tmo)) { pal_log_warn("%s <USB> cannot detect tools!\n",MOD); return FALSE; } ...... return handler->cb(handler, &cmd, &comport); //即 bldr_cmd_handler } static bool usb_listen(struct bldr_comport *comport, uint8 *data, uint32 size, uint32 tmo_ms) { ...... while (1) { if (tool_is_present()) { //向工具端发送READY,可通过Bus Hound工具或GLB_xx.log查看 mt_usbtty_puts(HSHK_COM_READY); } ...... dsz = mt_usbtty_query_data_size(); if (dsz) { dsz = dsz < size ? dsz : size; mt_usbtty_getcn(dsz, (char*)ptr); #if CFG_USB_DOWNLOAD if (*ptr == 0xa0) { //下载标志位,收到此标志位,表示下载模式 pal_log_info("%s 0xa0 sync time %dms\n", MOD, get_timer(start_time)); usbdl_handler(comport, 300); //下载镜像主函数 pal_log_info("%s : ignore %d bytes garbage data\n", MOD, dsz); continue; /* ingore received data */ } #endif ptr += dsz; size -= dsz; } } ...... } ``` ### 3、USB下载 ``` //download.c int usbdl_handler(struct bldr_comport *comport, u32 hshk_tmo_ms) { u8 cmd = 0; if (usbdl_check_start_command(comport, hshk_tmo_ms) == FALSE) { printf("%s start cmd handshake timeout (%dms)\n", MOD, hshk_tmo_ms); return -1; } while (1) { platform_wdt_kick(); usbdl_get_byte(&cmd); if (cmd != CMD_GET_BL_VER) usbdl_put_byte(cmd); /* echo cmd */ switch (cmd) { ...... case CMD_SEND_DA: DBGMSG("%s CMD_SEND_DA\n", MOD); usbdl_send_da(); break; ...... } DBGMSG("\n", MOD); } return 0; } static bool usbdl_check_start_command(struct bldr_comport *comport, u32 tmo) { u8 startcmd[] = {0xa0, 0x0a, 0x50, 0x05}; ulong start = get_timer(0); u32 i = 0; u8 cmd = 0, rsp; struct comport_ops *comm = comport->ops; do { if (get_timer(start) > tmo) return FALSE; /* timeout 1 ms */ if (0 != comm->recv(&cmd, 1, 1)) { //获取命令 continue; } /* fault-tolerant additional start cmd 0xA0 */ if ((cmd == startcmd[0]) && (i > 0)) { i = 1; continue; } if (cmd == startcmd[i]) { rsp = ~cmd; //取反 i++; } else { rsp = cmd + 1; i = 0; } comm->send(&rsp, 1); //回复命令 } while(i < sizeof(startcmd)); return TRUE; } ``` 帮我解释一下这个方案是什么
最新发布
08-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值