IE中,select.innerHTML无法生效的解决办法

本文介绍了一种解决IE浏览器中动态更新Select元素选项时出现的Bug的方法。通过在外层添加一个Span标签,并修改innerHTML的方式,确保了在IE、Firefox及Chrome等浏览器下的一致性和兼容性。
有天遇到select动态生成options,页面部分代码如下:

<select class="selectStyle" name="act_move_target" id="act_move_target">
<common:folderOptions currentId="${curMoveFID}"/>
</select>

在FF、chrome均可以使用
$("#act_move_target").innerHTML = ${folderSelectHTML}

到了IE就不行了,据说是IE的BUG.上网查了一下,其中一种解决方法是在select上层再套一层div或span,如下示:

<span id="spn_act_move_target">
<select class="selectStyle" name="act_move_target" id="act_move_target">
<common:folderOptions currentId="${curMoveFID}"/>
</select>
</span>

这样,在IE、FF、chrome均可以使用
$("#spn_act_move_target").innerHTML = '<select class="selectStyle" name="act_move_target" id="act_move_target">' + ${folderSelectHTML} + '</select>'
完整代码如下 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <%@ page import="com.sjsemi.prms.constants.*" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html lang="zh-CN"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title><%=Global.WEB_TITLE %> </title> <% request.setCharacterEncoding("UTF-8"); %> <meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="description" content=""> <meta name="author" content=""> <link rel="stylesheet" type="text/css" href="lib/bootstrap/css/bootstrap.css"> <link rel="stylesheet" type="text/css" href="custom/global.css"> <link rel="stylesheet" type="text/css" href="stylesheets/theme.css"> <link rel="stylesheet" href="lib/font-awesome/css/font-awesome.css"> <link rel="stylesheet" type="text/css" href="stylesheets/jquery-ui.css"> <script src="lib/jquery-1.7.2.min.js" type="text/javascript"></script> <script src="lib/jquery-ui-1.10.4.js" type="text/javascript"></script> <style type="text/css"> .brand { font-family: georgia, serif; } .brand .first { color: #FF5C0D; font-style: italic; } .brand .second { color: #fff; font-weight: bold; } .table td { padding: 5px; line-height: 20px; border-top: 1px solid #dddddd; } </style> <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements --> <!--[if lt IE 9]> <script src="lib/html5.js"></script> <![endif]--> <!-- Le fav and touch icons --> <link rel="shortcut icon" href="../assets/ico/favicon.ico"> </head> <% String scanIdType = FormatUtils.parseString(request.getParameter("scanIdType")); %> <body> <%@ include file="navBar.jsp" %> <%@ include file="sideBar.jsp" %> <div class="content"> <div class="header"> <h1 class="page-title">Tally</h1> </div> <div class="container-fluid"> <div class="raw-fluid"> <div class="block span6" style="width: 100%;"> <a href="#tablewidget" class="block-heading" data-toggle="collapse">Search</a> <div id="tablewidget" class="block-body collapse in"> <form id="frmQuery"> <input type="hidden" name="pageIndex"/> <table class="table"> <thead> <tr> <td style="width: 10%">Scan ID:</td> <td><input type="text" style="width: 130px;" id="scanId" name="scanId" autocomplete="off"></td> <td style="width: 10%">Scan Id 类型:</td> <td colspan="3" style="text-align: left;"><select name="scanIdType"> </select></td> <td style="width: 10%">Rack ID:</td> <td><input type="text" style="width: 130px;" id="rackId" name="rackId" readonly/></td> <td><input type="text" id="countId" name="countId" style="color: red; font-size: 14px; width: 50px;" value="0" readonly/></td> <td style="width: 30%"></td> </thead> </table> </form> </div> </div> </div> </div> <div class="container-fluid"> <form id="frmResult" action="<%=Page.TD_MATERIAL_INFO%>"> <div class="raw-fluid"> <div class="block span6" style="width: 100%;"> <div> <a href="#tablewidget1" class="block-heading" data-toggle="collapse">Search Result List</a> </div> <div id="tablewidget1" class="block-body collapse in" style="width: 100%;"> <table border="1" cellpadding="10" style="width: 99%;" id="searchResult"> <thead> <tr> <th rowspan="2"></th> <th rowspan="2">Cabinet ID</th> <th rowspan="2">Scan ID</th> </tr> </thead> <tbody id="q"></tbody> </tbody> </table> <div style="text-align: center;"> <button id="btn_submit" style="display:none;" type="button" class="btn btn-primary" onclick="saveRackLot();">Submit </button> </div> </div> </div> </div> </form> </div> </div> <script src="lib/bootstrap/js/bootstrap.js"></script> <script language="Javascript"> $(document).ready(function () { $("#frmQuery select[name='scanIdType']").val('<%=scanIdType %>'); setScanIdType(); }); var sequence = 1; window.onload = function () { document.getElementById("scanId").focus(); } document.onkeydown = function enterserach() { if (isEnter(event)) { checkLotInfo(); } } function isEnter(e) { var keynum = 0; if (window.event) // IE { keynum = e.keyCode } else if (e.which) // Netscape/Firefox/Opera { keynum = e.which } if (keynum == 13) { return true; } else { return false; } } function trim(str) { return str.replace(/\s+/g, ""); } function getScanIdTypeDisplayName(value) { var map = { "LOTID": "Lot ID", "WAFERID": "Wafer ID", "REELID": "Reel ID", "CARRIERID": "Carrier ID", "SCANID": "Scan ID" }; return map[value] || value; } function setScanIdType() { $.ajax({ type: "POST", url: "RmsAction?accessMethod=<%=AccessMethod.AJAX %>", data: { 'actionCode': '<%=ActionCode.GET_RMS_SCAN_ID_TYPE %>', }, dataType: "json", success: function (data) { if (data.return_code == "0") { var values = data.return_value.split(','); var selectBox = $("select[name='scanIdType']"); selectBox.empty(); // 清空原有选项 // 遍历数组,生成下拉选项 $.each(values, function (index, value) { var displayName = getScanIdTypeDisplayName(value); selectBox.append( $("<option></option>") .attr("value", value) .text(displayName || value) ); }); getRmsConfig(values[0]); // 绑定 change 事件,动态加载配置 selectBox.on('change', function () { var selectedType = $(this).val(); $("#savedScanIdType").val(selectedType); // 保存当前选择 getRmsConfig(selectedType); }); } }, error: function () { alert("Ajax HTTP访问失败, 请联系IT处理!"); } }); } // 全局变量,用于存储从后台获取的配置 var lotIdConfig = { rackIdKeyword: null, lengthRequirement: 16 }; // 获取 RMS 配置 function getRmsConfig(rmsType) { let hasRackIdConfig = false; var scanIdInput = document.getElementById("scanId"); // 清除旧的配置 lotIdConfig.rackIdKeyword = null; lotIdConfig.lengthRequirement = 16; $.ajax({ type: "POST", url: "RmsAction?accessMethod=<%=AccessMethod.AJAX %>", data: { 'actionCode': '<%=ActionCode.GET_RMS_CONFIG_LIST %>', 'rmsType': rmsType }, dataType: "json", success: function (data) { if (data.return_code == "0") { if (data.return_value.length == 0) { alert("请在RMS配置维护中维护RMS配置名称:RACKID的条件!"); if (scanIdInput) scanIdInput.disabled = true; return; } // 更新全局配置 for (var i = 0; i < data.return_value.length; i++) { var item = data.return_value[i]; if (item.key === "LENGTH") { if (item.value === undefined || item.value === null || item.value === "NA") { lotIdConfig.lengthRequirement = 16; } else { var parsedValue = parseInt(item.value, 10); lotIdConfig.lengthRequirement = isNaN(parsedValue) ? 16 : parsedValue; } } else if (item.key === "CONTAIN") { hasRackIdConfig = true; lotIdConfig.rackIdKeyword = item.value; if (scanIdInput) scanIdInput.disabled = false; } } if (!hasRackIdConfig) { alert("请在RMS配置维护中维护RACKID的包含条件!"); if (scanIdInput) scanIdInput.disabled = true; } } else { alert(data.return_value); } }, error: function () { alert("Ajax HTTP访问失败, 请联系IT处理!"); } }); } var j = 1; function checkLotInfo() { var lotIdObj = document.getElementById("scanId"); lotId = trim(lotIdObj.value.toUpperCase()); if (lotId.length == 0) return; var rackIdObj = document.getElementById("rackId"); rackId = trim(rackIdObj.value.toUpperCase()); var objTable = document.getElementById("searchResult"); var rackIdKeyword = lotIdConfig.rackIdKeyword; var lengthRequirement = lotIdConfig.lengthRequirement; if (lotId.indexOf(rackIdKeyword) >= 0) { if (lotId.length === lengthRequirement) { rackIdObj.value = lotId; lotIdObj.value = ''; lotIdObj.focus(); } else { alert("库位当前不满足" + lengthRequirement + "码!"); lotIdObj.value = ''; lotIdObj.focus(); return; } } else { document.getElementById("btn_submit").style.display = ""; lotIdObj.value = ''; lotIdObj.focus(); var countIdObj = document.getElementById("countId"); countIdObj.value = objTable.rows.length; q.innerHTML = q.innerHTML + '<tr id="button' + j + '"><td style="width: 60px;text-align: center;">' + '<button type="button" class="btn btn-primary" id=' + j + ' onclick="removeLot(this);" >Remove</button></td>' + '<td style="width: 60px;text-align: center;" id="rackId' + j + '" Name="rackId" >' + rackId + '</td>' + '<td style="width: 60px;text-align: center;" id="scanId' + j + '" Name="scanId" >' + lotId + '</td></tr>'; j++; } } function removeLot(obj) { var tb = document.getElementById("searchResult"); var id = obj.id; var row = document.getElementById("button" + id); var index = row.rowIndex; tb.deleteRow(index); var countIdObj = document.getElementById("countId"); countIdObj.value = tb.rows.length - 1; } function saveRackLot() { //获取循环次数 var countId = document.getElementById("countId").value; var count = parseInt(countId); //判断次数 var isCount = parseInt(0); var strs1 = []; var strs2 = []; for (i = 1; i <= count; i++) { var scanId = ""; var rackId = ""; var searchResult = document.getElementById("searchResult"); var rows = searchResult.rows;//获取所有行 for (var i = 1; i < rows.length; i++) { var row = rows[i];//获取每一行 scanId = row.cells[1].id; rackId = row.cells[2].id; var scanIds = document.getElementById(rackId).innerHTML; var rackIds = document.getElementById(scanId).innerHTML; strs1 = strs1 + "," + scanIds; strs2 = strs2 + "," + rackIds; isCount++ } } if (count > 0) { if (isCount == count) { $.ajax({ type: "POST", url: "RmsAction?accessMethod=<%=AccessMethod.AJAX %>", data: { 'actionCode': '<%=ActionCode.CREATE_RMS_LOT %>', 'scanId': strs1, 'rackId': strs2, 'count': count }, dataType: "json", success: function (data) { if (data.return_code == "0") { alert(data.return_value); location.reload(); } else { alert(data.return_value); } }, error: function () { alert("Ajax HTTP访问失败, 请联系IT处理!"); $('#butSend').attr("disabled", false); } }); } } else { alert("请输入数据后再提交!") } } </script> </body> </html> 现在还是不能把 Scan Id 类型 变成选择的内容 因为setScanIdType吧?
最新发布
12-11
<think>我们正在讨论Vue 2中如何使用`.innerHTML`。根据引用[1]中的信息,Vue提供了`v-html`指令来更新元素的innerHTML。 在Vue 2中,我们通常使用指令来操作DOM。对于设置元素的innerHTML,Vue提供了`v-html`指令。 注意:使用`v-html`时需要小心,因为它会直接渲染HTML字符串,可能会导致XSS攻击。因此,确保内容来源可信。 使用方式:在元素上使用`v-html`指令,并将其绑定到一个返回HTML字符串的数据属性。 例如: <div v-html="htmlContent"></div> 在Vue实例的data中定义htmlContent,可以是一个字符串,包含HTML标签。 示例代码: new Vue({ el: '#app', data: { htmlContent: '<span style="color: red;">This is red text.</span>' } }) 这样,div元素的内容就会被渲染为带有红色样式的文本。 另外,引用[1]中也提到了`v-html`指令用于更新元素的innerHTML。 因此,在Vue 2中,使用`v-html`指令是官方推荐的方式来设置元素的innerHTML。 </think>在 Vue 2 中,使用 `.innerHTML` 的标准方法是 **`v-html` 指令**。这是 Vue 提供的专门用于设置元素 HTML 内容的安全方式,避免直接操作 DOM。以下是详细说明: ### 使用方法 1. **基本语法** 在模板中直接使用 `v-html` 指令绑定数据: ```html <div v-html="htmlContent"></div> ``` 2. **数据定义** 在 Vue 实例的 `data` 中声明 HTML 字符串: ```javascript new Vue({ el: '#app', data: { htmlContent: '<span style="color:red">红色文本</span>' } }) ``` 渲染结果:显示红色文本(非字符串)。 3. **动态更新** 当 `htmlContent` 的值变化时,视图会自动更新: ```javascript // 修改数据 this.htmlContent = '<b>更新后的加粗文本</b>' ``` ### ⚠️ 重要安全提示 - **XSS 风险**:`v-html` 会解析原始 HTML,若内容来自用户输入,需严格过滤(如使用 `DOMPurify` 库清洗)。 - **作用域限制**:`v-html` 中的内容**不会**编译为 Vue 模板(如不支持 `{{ }}` 插值或指令)[^1]。 ### 对比原生 JavaScript | 方式 | 原生 JavaScript | Vue 2 (`v-html`) | |--------------|-----------------------------|-------------------------------| | 操作元素 | `element.innerHTML = ...` | 声明式指令 | | 数据绑定 | 手动更新 | 响应式自动更新 | | 安全风险 | 需自行处理 XSS | 需主动清洗不安全内容 | | Vue 集成度 | 破坏响应式 | 原生支持响应式 | ### 何时使用? - ✅ 需要渲染富文本(如从 CMS 获取的带格式内容) - ✅ 动态生成 SVG 等复杂结构 - ❌ 避免用于用户输入的未过滤内容 ### 示例场景 ```html <div id="app"> <!-- 安全渲染富文本 --> <div v-html="sanitizedContent"></div> </div> <script> import DOMPurify from 'dompurify'; // 安全过滤库 new Vue({ el: '#app', data: { rawContent: '<script>alert("危险!")</script> 安全文本', }, computed: { sanitizedContent() { return DOMPurify.sanitize(this.rawContent); // 过滤 XSS } } }) </script> ``` > **关键总结**:始终使用 `v-html` 替代原生 `.innerHTML`,并结合内容过滤确保安全[^1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值