关于ie浏览器发ajax请求没有数据返回的兼容性处理和ie中的innerhtml

问题描述

使用ajax发一个get请求,并将请求获取到的数据填充到table中。使用谷歌浏览器完美显示,但是使用360用兼容模式打开,table中没有数据。

分析思路

  • 第一步我直接在当前脚本第一行加上了alert,看这个脚本是不是没有执行,后来执行了,就不是这里的问题
  • 第二步直接到success方法中,alert data,发现没有数据返回,问题所在!!!用谷歌是有的,然后网上找到说ie要带一个不同的值过去,避免ie的缓存问题,我也带了。但是发现没用(这个时候由于我只带了加上时间戳一共两个参数,所以我是直接在url上面传的参数),再后来网上找到答案说是要这样写

    1
    2
    url : "${pageContext.request.contextPath}/km/xxx?",
    data: {'contractNum':name,'timeStamp':new Date().getTime()},
  • 按照上面的写法确实可以在ie里面获取到data,但是问题又出现了,没有将data填充到table中去,继续排查

  • 将js中的代码拷贝到ie浏览器控制台中运行,发现ie又不支持innerHTML,也不是说不支持,就是在一些元素上成了readonly,The property is read/write for all objects except the following, for which it is read-only: COL, COLGROUP, FRAMESET, HEAD, HTML, STYLE, TABLE, TBODY, TFOOT, THEAD, TITLE, TR.
    (source: http://msdn.microsoft.com/en-us/library/ms533897(VS.85).aspx)

    1
    2
    3
    4
    5
    6
    >> var tr1 = tbody.getElementsByTagName('tr')[1]; 
    >> var newRow = tbody.insertRow()
    >> newRow.innerHTML = tr1.innerHTML
    "未知的运行时错误"
    >> tr1.after(newRow)
    "对象不支持“after”属性或方法"
  • 这个时候我看到stackoverflow有这个类似的问题,我就直接拿来用,思路是这样的:通过document创建一个tr元素,将另一个tr中的innerhtml的内容赋值给一个变量,再讲这个变量的值赋值给创建的tr的innerhtml上,然后再通过拿到tbody,appendChild到toby上,但是这个在ie中没用,网上说需要trick一下,也没有说具体这个能不能行得通,也没有说具体怎么个trick。反正我试过是没用的。

  • 微软官网也有提到,上面有写,但是没有说td不能直接改的。于是真的在一个角落里面找到了:ie里面tr不能直接innerhtml,但是td可以所以可以通过直接用document.createElement(‘td’)或者用cell来弄,但是由于我这个有12列,所以用这种方法可能会有点鸡肋。

转换思路使用jQuery的click遇到的问题

ie使用jQuery的click事件没有反应

ie678不支持jQuery2.x版本,只有使用1.x才可以使用,但是我在ie控制台中使用jQuery1.x想直接在控制台中调用click,结果使用1.x版本直接不报错也不运行,但是在谷歌浏览器中却又可以运行,相当的郁闷,2.x不支持,1.x直接没有反应

1
$( "img[title='添加行']").click()

我自己写了一个html,测试了一下click,上面的一行代码是可以在ie中使用的,就是说问题不是这里。继续排查

问题可能又得重头那个ie的innerhtml只读问题上进行修改了

无奈最后就用了笨办法来实现这个功能

1
2
3
4
5
6
7
8
9
var newRow = tbody.insertRow(2+i)
for(var j = 0 ;j < tr1.cells.length;j++){
var x = newRow.insertCell(j)
var tds = tr1.getElementsByTagName('td')
x.innerHTML = tds[j].innerHTML
if(j == 0 || j == 1 || j ==2 || j ==11){
x.setAttribute('align','center')
}
}

问题到现在并没有真正的结束

问题又来了, 因为以前是用的input输入框,也就是手动输入合同号,但是合同号过于复杂手写容易出错,于是又要改成SQL弹出框,让用户根据合同号搜索,选择完毕之后,本以为可以直接修改table中的内容,但是令人意外的是,并没有出现,原来系统中使用系统内部的监听input框中内容是否发生变化,如果变化table就改变。也就是说这个函数不起作用了。估计这个监听函数也是根据focus和blur来操作的。最后问题变成了— 由js改变input框中的值,如何监听内容是否发生变化。又不能直接修改源码的情况下,最终在Stack Overflow上问出来了,一个大佬给出了解决方案。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$(function () {
const input = $("input[name='extendDataFormInfo.value(fd_37157d8be9876e)']")[0];
const {
get,
set
} = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value');
Object.defineProperty(input, 'value', {
get() {
return get.call(this);
},
set(newVal) {
set.call(this, newVal);
console.log('New value set by JS detected: ', newVal);
// insert desired functionality here
changestyle()
return newVal;
}
});
});

注意将input修改为需要监听的input元素。由于工作需要,又要把上面的代码改成兼容IE9的,于是又在 https://babeljs.io 上面将代码改成了兼容es5的。

问题到这里就结束了吗,并没有

很崩溃,在IE9浏览器中使用,直接给我报了一个错 HTMLInputElement was not defined 最后尝试改浏览器的版本(在ie f12中观察各个版本之间的兼容性),发现在ie9中文档模式为ie9标准的时候是可以正常显示的。于是在head中添加了下面的代码

1
<meta http-equiv="X-UA-Compatible" content="IE=9,IE=8,IE=edge,chrome=1">

后来还修改过页面的doctype,后来发现其实不用改就用上面一行代码就可以了,至此ie9文档的怪异模式终于显示为标准了。

0%