解决javascript中循环给组件添加事件,只有一个最后一个组件添加成功。或者?全部添加失败。

本文探讨了JavaScript中闭包的使用,特别是在for循环中处理事件绑定时避免常见陷阱的方法。通过实例说明如何利用闭包保存变量状态,确保每个事件处理器都能正确获取预期的变量值。

问题产生的原因

页面加载---->for循环执行(结束条件:i<6为例),执行完之后,i最后的值是6---->这时候事件要触发了,事件触发调用的这个function,它拿到的值是i=6–>导致最后一个事件都没有成功被触发。

问题解决方法

第一种:常用的方法是:使用闭包把i值封存

for(var i =0 ; i < 6 ; i++){
(function(i){添加事件的代码}(i);
}

上面用到的解决方法是使用闭包把i值封存了。

第二种:IE11以前不支持的方法是:用let块作用域变量,原理也是闭包

for(var i =0 ; i < 6 ; i++){
let j = i;
添加事件的代码(里面用j就OK了);
}

这是我在做东西时候的部分代码,就是这段代码让我在坑了栽了。ahh

<script>
        var name;
        var gender;
        var age;
        var nativeplace;
        var qq;
        var email;
        var email_old;

        for (var i = 0; i < 6; i++) {

            var update = document.getElementById("update" + i);
            (function(i){
            update.onclick = function () {
    
                name = document.getElementById("name" + i).innerText;
                gender = document.getElementById("gender" + i).innerText;
                age = document.getElementById("age" + i).innerText;
                nativeplace = document.getElementById("nativeplace" + i).innerText;
                qq = document.getElementById("qq" + i).innerText;
                email = document.getElementById(i + "").innerText;

                email_old = email;

                var update = document.getElementById("update" + i);

                update.innerText = "提交";
                update.setAttribute("class", "btn btn-success");

                var name_ele = document.getElementById("name" + i);
                var gender_ele = document.getElementById("gender" + i);
                var age_ele = document.getElementById("age" + i);
                var nativeplace_ele = document.getElementById("nativeplace" + i);
                var qq_ele = document.getElementById("qq" + i);
                var email_ele = document.getElementById("" + i);

                var name_input = document.createElement("input");
                var gender_input = document.createElement("input");
                var age_input = document.createElement("input");
                var nativeplace_input = document.createElement("input");
                var qq_input = document.createElement("input");
                var email_input = document.createElement("input");

                name_input.value = name;
                gender_input.value = gender;
                age_input.value = age;
                nativeplace_input.value = nativeplace;
                qq_input.value = qq;
                email_input.value = email;

                name_ele.innerText = "";
                gender_ele.innerText = "";
                age_ele.innerText = "";
                nativeplace_ele.innerText = "";
                qq_ele.innerText = "";
                email_ele.innerText = "";

                name_ele.appendChild(name_input);
                gender_ele.appendChild(gender_input);
                age_ele.appendChild(age_input);
                nativeplace_ele.appendChild(nativeplace_input);
                qq_ele.appendChild(qq_input);
                email_ele.appendChild(email_input);

                update.onclick = function () {
                    name = name_input.value;
                    gender = gender_input.value;
                    age = age_input.value;
                    nativeplace = nativeplace_input.value;
                    qq = qq_input.value;
                    email = email_input.value;

                    update.href = "UpdateTableServlet?email_old="
                        + email_old + "&name="
                        + name + "&gender="
                        + gender + "&age="
                        + age + "&nativeplace="
                        + nativeplace + "&qq="
                        + qq + "&email="
                        + email;
                }
            }
        })(i);
        }
    </script>
<think> 我们参考用户提供的引用内容,并结合用户的问题"如何使用HBuilder X制作一个可以添加组件功能的app"来组织答案。 用户的问题是关于制作一个可以添加组件功能的app,这里的“添加组件功能”可能指的是在应用中动态使用和集成UI组件库(如uView)或自定义组件(如自定义搜索框)。 根据引用内容: 引用[1]提到了集成UView UI组件库的基本方法。 引用[2]提到了在HBuilder中制作app底部导航栏的两种方法。 引用[3]详细介绍了uni-app组件支持的生命周期,与Vue标准组件的生命周期相同。 引用[4]则展示了如何在uni-app中创建自定义搜索组件,包括使用props来定制样式。 因此,我们可以将回答分为以下几个步骤: 1. 创建uni-app项目(使用HBuilder X) 2. 集成UI组件库(以uView为例)或创建自定义组件 3. 在页面中使用组件(包括全局注册和局部注册) 4. 通过props实现组件的可配置性(如自定义样式、功能) 5. 利用uni-app的生命周期管理组件 我们按照这些步骤来回答,并在适当的地方引用提供的参考内容。 注意:用户的问题中“添加组件功能”可能有两种理解: a) 在开发过程中,如何添加和使用组件(静态添加) b) 在应用运行时,让用户能够动态添加组件(如插件化) 根据提供的引用内容,引用[1][2][3][4]都是关于开发过程中如何使用组件,因此我们主要回答开发过程中如何添加组件。 如果用户指的是运行时动态添加组件,那么需要更高级的技术(如插件化、动态加载等),这在uni-app中可能涉及复杂的技术,且引用内容未提及,所以我们先按常规开发方式回答。 步骤分解: 步骤1:创建uni-app项目 - 使用HBuilder X新建项目,选择uni-app模板。 步骤2:添加组件 a) 使用现有的UI组件库(如uView): 引用[1]提到,我们可以集成UView UI组件库,通过npm安装或下载组件库,然后在项目中引入。 b) 自定义组件: 引用[4]给出了自定义搜索组件的例子,我们可以创建自己的组件。 步骤3:注册组件 - 全局注册:在main.js中注册,这样所有页面都可以使用。 - 局部注册:在具体页面的vue文件中注册,仅在该页面使用。 步骤4:在页面中使用组件 - 在template中添加组件的标签,并通过props传递参数(如引用[4]中自定义搜索组件的背景颜色和圆角)。 步骤5:管理组件的生命周期(如果需要) - 引用[3]详细介绍了组件生命周期,我们可以利用这些生命周期钩子函数来管理组件的行为。 下面我们详细展开: </think> ### 如何在 HBuilder X 中制作可添加组件功能的 App 以下步骤结合引用内容,详解如何通过 **组件化开发** 实现 App 的灵活功能扩展。核心逻辑:**创建可复用的自定义组件 ➜ 通过 Props 控制组件行为 ➜ 在页面中动态集成**。 --- #### 一、创建自定义组件(以搜索组件为例) 引用[4]展示了创建可定制化搜索框的方法: 1. **新建组件文件**: 在 `components` 目录创建 `my-search.vue` 文件 2. **声明 Props 接收参数**: ```vue <script> export default { props: { // 背景色(默认值 #C00000) bgcolor: { type: String, default: '#C00000' }, // 圆角尺寸(默认 18px) radius: { type: Number, default: 18 } } } </script> ``` 3. **绑定动态样式**: ```vue <template> <view :style="{ backgroundColor: bgcolor, borderRadius: radius + 'px' }" class="search-box" > <!-- 搜索图标和输入框 --> </view> </template> ``` 通过 `:style` 动态绑定 Props 参数,实现样式自定义(替代硬编码 CSS)[^4]。 --- #### 二、集成 UI 组件库(如 uView) 引用[1]强调了组件库对开发效率的提升: 1. **安装 uView**: ```bash npm install uview-ui ``` 2. **全局注册**(在 `main.js` 中): ```javascript import uView from 'uview-ui' Vue.use(uView) ``` 3. **使用预制组件**: ```vue <template> <u-button type="primary">添加组件</u-button> </template> ``` 通过组件库快速构建按钮、导航等基础功能[^1]。 --- #### 三、动态添加组件到页面 ##### 场景示例:点击按钮新增搜索组件 1. **页面逻辑**(`index.vue`): ```vue <script> import MySearch from '@/components/my-search.vue' export default { components: { MySearch }, data() { return { componentsList: [] // 存储动态添加组件 } }, methods: { addSearchComponent() { this.componentsList.push({ id: Date.now(), bgcolor: '#4CD964', // 自定义参数 radius: 10 }) } } } </script> ``` 2. **动态渲染组件**: ```vue <template> <view> <button @click="addSearchComponent">添加搜索框</button> <my-search v-for="item in componentsList" :key="item.id" :bgcolor="item.bgcolor" :radius="item.radius" /> </view> </template> ``` **关键点**: - `v-for` 循环渲染组件列表 - 通过 `:bgcolor` 等 Props 传递配置参数 --- #### 四、利用生命周期管理组件(引用[3]) 在自定义组件中使用 Vue 生命周期钩子: ```vue <script> export default { mounted() { console.log('组件已挂载,可操作DOM') }, beforeDestroy() { console.log('组件销毁前,清除定时器等资源') } } </script> ``` 生命周期函数确保组件状态可控,避免内存泄漏[^3]。 --- #### 五、完整流程示意图 ```mermaid graph LR A[创建自定义组件] --> B[定义Props接收参数] B --> C[绑定动态样式/行为] D[页面引入组件] --> E[通过v-for动态渲染] E --> F[用户交互添加组件] F --> G[更新组件列表数据] ``` > **注意事项**: > 1. 跨平台兼容:使用 `uni-app` 规范,确保 iOS/Android/小程序一致性 > 2. 性能优化:动态组件较多时,用 `v-if` 替代 `v-show` 减少 DOM 节点 > 3. 全局状态:复杂场景用 Vuex 管理组件状态
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值