IE中document.getElementById和.getElementsByName特殊表现

HTML元素属性Id和name应该是不同的,Id犹如身份证号码,在整个页面中应该是唯一的,而name犹如姓名,在整个页面中可以重复。

 

JS中document.getElementById应该是用于捕捉具有某个id属性的一个元素,document.getElementsByName是用于捕捉具有某个name属性的多个元素。id和name不应当混淆。这一点在firefox中没有问题,而IE中的实现却不区分id和name。

EG:

<input type="text" name="t" />
<input type="text" id="t" />
 
alert(document.getElementsByName('t').length);

 在firefox中表现正确,输出长度为1,而在IE中输出却是2。

 

同样,如果使用document.getElementById('t'),在firefox中可以得到正确的id="t"的元素,而由于IE不

区分id和name,因此它将得到第一个name="t"的元素。

 

在IE中还有一个特殊点就是:IE中div和table等元素没有name属性,使用document.getElementsByName。得不到任何值,切记!

 

解决办法:
  1、元素命名id和name在一个页面中最好都不要相同(避免IE混淆id和name的bug)
  2、div和table等元素结合id和document.getElementsByTagName来使用

 

 

WEB标准下可以通过getElementById(), getElementsByName(), and getElementsByTagName()访问DOCUMENT中的任一个标签:

1、getElementById()
getElementById()可以访问DOCUMENT中的某一特定元素,顾名思义,就是通过ID来取得元素,所以只能访问设置了ID的元素。
比如说有一个DIV的ID为docid:
<div id="docid"></div>
那么就可以用getElementById("docid")来获得这个元素。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>ById</title>
<style type="text/css">
<!--
#docid{
height:400px;
width:400px;
background-color:#999;}
-->
</style>
</head>
<body><div id="docid" name="docname" onClick="bgcolor()"></div>
</body>
</html>
<script language="JavaScript" type="text/JavaScript">
<!--
function bgcolor(){
document.getElementById("docid").style.backgroundColor="#000"
}
-->
</script>

 2、getElementsByName()

这个是通过NAME来获得元素,但不知大家注意没有,这个是GET ELEMENTS,复数ELEMENTS代表获得的不是一个元素,为什么呢?
因为DOCUMENT中每一个元素的ID是唯一的,但NAME却可以重复。打个比喻就像人的身份证号是唯一的(理论上,虽然现实中有重复),但名字

重复的却很多。如果一个文档中有两个以上的标签NAME相同,那么getElementsByName()就可以取得这些元素组成一个数组。

比如有两个DIV:

<div name="docname" id="docid1"></div>
<div name="docname" id="docid2"></div>

 那么可以用getElementsByName("docname")获得这两个DIV,用getElementsByName("docname")[0]访问第一个DIV,用getElementsByName

3、getElementsByTagName()

这个呢就是通过TAGNAME(标签名称)来获得元素,一个DOCUMENT中当然会有相同的标签,所以这个方法也是取得一个数组。
下面这个例子有两个DIV,可以用getElementsByTagName("div")来访问它们,用getElementsByTagName("div")[0]访问第一个DIV,用

getElementsByTagName("div")[1]访问第二个DIV。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>Byname,tag</title>
<style type="text/css">
<!--
#docid1,#docid2{
margin:10px;
height:400px;
width:400px;
background-color:#999;}
-->
</style>
</head>
<body>
<div name="docname" id="docid1" onClick="bgcolor()"></div>
<div name="docname" id="docid2" onClick="bgcolor()"></div>
</body>
</html>
<script language="JavaScript" type="text/JavaScript">
<!--
function bgcolor(){
var docnObj=document.getElementsByTagName("div");
docnObj[0].style.backgroundColor = "black";
docnObj[1].style.backgroundColor = "black";
}
-->
</script>

 总结一下标准DOM,访问某一特定元素尽量用标准的getElementById(),访问标签用标准的getElementByTagName(),但IE不支持

getElementsByName(),所以就要避免使用getElementsByName(),但getElementsByName()和不符合标准的document.all[]也不是全无是处,它

们有自己的方便之处,用不用那就看网站的用户使用什么浏览器,由你自己决定了。

  Javascript中的getElementById十分常用,但在标准的页面中,一个id只能出现一次,如果我想同时控制多个元素,例如点 一个链接, 让多个层隐藏,该怎么做?用class,当然,同一个class是可以允许在页面中重复出现的,那么有没有getElementByClass呢?没有, 但是可以解决:

//Create an array
var allPageTags = new Array();

function hideDivWithClasses(theClass) {
//Populate the array with all the page tags
var allPageTags=document.getElementsByTagName("div");
//Cycle through the tags using a for loop
for (i=0; i//Pick out the tags with our class name
if (allPageTags[i].className==theClass) {
//Manipulate this in whatever way you want
allPageTags[i].style.display='none';
}
}
}

 1,grid.getCell(i,3).innerHTML;curobj.nextSibling.innerHTML

innerHTML InnerHtml 属性不自动对进出 HTML 实体的特殊字符进行编码。HTML 实体允许显示特殊字符(如 < 字符),浏览器通常会将这些字符解释为具有特殊含义。< 字符会被解释为标志的开头,并且不会在页面上显示。若要显示 < 字符,将需要使用实体 &lt;。

例如,如果 InnerHtml 属性设置为 "<b> Hello </b>",则 < 和 > 字符不会分别转换为 &lt; 和 &gt;。呈现的输出仍将是:<b> Hello </b>。浏览器将检测 <b> 标记并用粗体显示“Hello”文本。

警告   由于未对此文本进行 HTML 编码,因此可以在文本的 HTML 标记内嵌入脚本。如果该属性是使用用户输入动态设置的,请务必验证它的值以减少安全漏洞。
若要提供自动 HTML 编码和解码,请使用 InnerText 属性。

以上是微软的一个网站上介绍的,而我只是简单的认为取出来的是html格式。

2,typeName = temp.options[temp.selectedIndex].innerText;document.all("B1").innerText=" 关闭";name==name_other.options[i].innerText;opn.innerText=nameArray[i];

使用 InnerText 属性以编程方式修改 HTML 服务器控件的开始和结束标记之间的内容。

与 InnerHtml 属性不同,InnerText 属性自动对进出 HTML 实体的特殊字符进行编码。HTML 实体允许显示特殊字符(如 < 字符),浏览器通常会将这些字符解释为具有特殊含义。< 字符会被解释为标志的开头,并且不会在页面上显示。若要显示 < 字符,将需要使用实体 &lt;。

例如,如果 InnerText 属性设置为 "<b> Hello </b>",则 < 和 > 符号分别转换为 &lt; 和 &gt;。呈现的输出将是:&lt; b &gt; Hello &lt;/b &gt;。&lt; 和 &gt; 实体将向浏览器指示这些字符将显示在页上。浏览器将不检测 <b> 标记并用粗体显示该文本。显示在页上的文本是:<b> Hello </b>。

 

<think>好的,我现在需要解决用户在UniApp中遇到的`document.getElementById`为undefined的问题,并提供替代方案或解决方法。首先,我需要理解为什么会出现这个问题。 UniApp是一个使用Vue.js框架的跨平台开发工具,它主要支持小程序、H5以及App等平台。在传统Web开发中,我们经常使用`document.getElementById`来获取DOM元素,但在UniApp中,由于运行环境的不同(比如小程序),传统的DOM操作方法可能不可用,因为小程序没有传统浏览器的DOM模型。这就是导致`document.getElementById`返回undefined的原因。 接下来,我需要参考用户提供的引用内容来寻找可能的解决方案。引用[1]提到使用`document.getElementsByName()`的替代方案,解决了IE浏览器的一些兼容性问题,但这里的问题环境是UniApp,可能涉及小程序,所以需要考虑跨平台的兼容性。引用[2]讨论了在Vue中使用`ref`属性来引用组件或DOM元素,这可能在UniApp中同样适用,因为UniApp基于Vue.js。 首先,我需要确认UniApp中推荐的元素访问方法。在Vue中,通常使用`ref`来引用元素或组件实例。UniApp作为基于Vue的框架,应该也支持这种方式。例如,在模板中给元素添加`ref`属性,然后通过`this.$refs`来访问。这种方法不依赖于`document.getElementById`,而是利用Vue的响应式系统,更符合UniApp的设计模式。 另外,用户之前的问题涉及到微信小程序中的元素定位滚动,解决方案中使用了`wx.createSelectorQuery`来获取元素位置。UniApp是否提供了类似的API?查阅UniApp文档,发现它确实封装了各平台的API,比如使用`uni.createSelectorQuery()`来创建节点查询,类似于微信小程序的`wx.createSelectorQuery`。这可能是在UniApp中替代`document.getElementById`的正确方法,尤其是在需要获取元素位置或尺寸时。 还有,用户可能在H5环境下使用UniApp,此时可能需要兼容浏览器的DOM操作。但为了跨平台,最好使用UniApp提供的统一方法,而不是直接操作DOM。例如,在H5中,虽然可以使用`document.getElementById`,但在小程序或App中会失败,因此应避免使用。 总结可能的解决方案: 1. 使用Vue的`ref`属性来引用元素,通过`this.$refs`访问。 2. 使用UniApp提供的`uni.createSelectorQuery()`API来查询节点信息。 3. 在需要动态操作元素时,使用数据驱动的方式,而不是直接操作DOM。 接下来需要详细说明这些方法的具体实现步骤,并给出代码示例,确保用户能够理解并应用。同时,需要比较不同方法的适用场景,比如何时使用`ref`,何时使用`createSelectorQuery`,以及如何处理跨平台兼容性问题。 可能还需要考虑生命周期的问题,比如在`mounted`或`onReady`阶段确保元素已经渲染完成再进行查询。此外,错误处理也是必要的,比如元素不存在时的处理,避免应用崩溃。 最后,需要验证这些方法在UniApp的不同平台(如H5、小程序、App)中的可行性,确保提供的解决方案是跨平台有效的。同时,提醒用户避免直接使用DOM API,遵循UniApp的开发规范,以保证应用的稳定性兼容性。</think>在UniApp中,由于跨平台特性小程序环境限制,直接使用`document.getElementById`会返回`undefined`。以下是针对不同场景的解决方案: --- ### 一、基础替代方案:使用Vue ref引用 **适用场景**:需要直接操作组件/元素时 ```vue <!-- 在template中标记元素 --> <view ref="myElement">目标元素</view> <script> export default { mounted() { // 通过this.$refs访问 const element = this.$refs.myElement; // H5环境下可操作DOM(仅限浏览器环境) if (typeof window !== 'undefined') { element.$el.style.color = 'red'; } } } </script> ``` **优势**: - 支持跨平台运行 - 符合Vue响应式规范[^2] **限制**: - 无法直接获取元素布局信息(宽高、位置等) --- ### 二、高级方案:uni.createSelectorQuery **适用场景**:需要获取元素尺寸/位置信息 ```javascript // 获取元素布局信息 getElementRect() { uni.createSelectorQuery().in(this) .select('.target-class') .boundingClientRect(rect => { if (rect) { console.log('元素高度:', rect.height) console.log('离顶部距离:', rect.top) } }).exec() } // 滚动到指定位置(支持动画) scrollToElement() { uni.createSelectorQuery().select('#section2') .boundingClientRect(rect => { uni.pageScrollTo({ scrollTop: rect.top, duration: 300 }) }).exec() } ``` **特性**: - 全平台兼容(H5/小程序/App) - 支持异步查询 - 可获取精确布局数据[^1] --- ### 三、动态渲染解决方案 **适用场景**:列表渲染等动态内容操作 ```vue <template> <view v-for="(item,index) in list" :ref="'item_'+index" @click="handleClick(index)"> {{item}} </view> </template> <script> export default { data() { return { list: ['A','B','C'] } }, methods: { handleClick(index) { // 通过动态ref访问特定元素 const target = this.$refs['item_'+index][0] uni.showToast({ title: `点击了${target.$el.innerText}` }) } } } </script> ``` --- ### 四、跨平台兼容技巧 | 场景 | 解决方案 | 注意事项 | |-----------------------|-----------------------------------|-----------------------------| | 需要DOM操作 | 条件编译 + H5 API | `#ifdef H5` 包裹代码块 | | 频繁操作元素 | 数据驱动代替DOM操作 | 通过修改data触发视图更新 | | 第三方库依赖DOM | 使用uniapp插件市场替代方案 | 优先选择标有"跨平台"的插件 | | 必须使用document方法 | 封装平台判断方法 | 小程序环境需降级处理 | **示例代码(条件编译)**: ```javascript // #ifdef H5 const element = document.getElementById('fallback'); // #endif // #ifndef H5 uni.createSelectorQuery().select('#fallback').fields({...}) // #endif ``` --- ### 常见问题排查 1. **refs访问为空** - 检查元素是否存在于当前组件 - 确保在`mounted`生命周期后访问 - 动态渲染内容使用`$nextTick`等待更新: ```javascript this.$nextTick(() => { console.log(this.$refs.dynamicElement) }) ``` 2. **SelectorQuery无响应** - 添加`.in(this)`指定组件上下文 - 确保选择器在页面中存在 - 检查基础库版本(需≥1.4.0) 3. **滚动定位偏移** - 计算时考虑导航栏高度: ```javascript const systemInfo = uni.getSystemInfoSync() const scrollTop = rect.top - systemInfo.statusBarHeight ``` --- ### 性能优化建议 1. **批量查询**:单次`exec()`执行多个查询 ```javascript const query = uni.createSelectorQuery() query.select('#header').boundingClientRect() query.select('#footer').boundingClientRect() query.exec(results => { const [header, footer] = results }) ``` 2. **缓存查询结果**:对静态元素位置信息进行缓存 ```javascript let cachedPosition = null function getPosition() { return cachedPosition || new Promise(resolve => { uni.createSelectorQuery().select(...) .exec(res => { cachedPosition = res[0] resolve(cachedPosition) }) }) } ``` --- ### 平台差异对照表 | 功能 | H5 | 小程序 | App | |----------------------|-------------|--------------|--------------| | document.getElementById | 可用 | 不可用 | 不可用 | | this.$refs | 支持 | 支持 | 支持 | | createSelectorQuery | 支持 | 支持 | 支持 | | getBoundingClientRect | 原生实现 | 异步获取 | 异步获取 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值