-
-
Notifications
You must be signed in to change notification settings - Fork 51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[集] A collection of confusing problems met when developing JavaScript under IE #32
Comments
Content-Editable Elements under IE10(IE10 下的可编辑元素)In the case when we implementing an editor, we may need to consider such a case which I have met recently. Assume that there is an element which has the attribute 如果你想要实现一个编辑器,最近我所遇到的一个问题可能会引起您的注意。当一个元素设置有 <div contenteditable="true">
<table width="2000px"></table>
</div> A strange thing may happen when there is also an empty tag IE10 下奇怪的事就此发生!一个空标签 <div contenteditable="true">
<br>
<table width="2000px"></table>
</div> In order to work around such a weird occasion, we may have two ways: 为了解决该问题,我们有两种办法:
|
Detect the type of data in clipboard under IE(IE 下粘贴板数据类型检查)Recently, I have met a requirement where I need to implement a pop-up notification for suggesting users install upload plugins under IE when they are copying a picture. Under WebKit browsers, it can be easily implemented by attaching a 最近,我遇到了这样的一个需求:检查用户是否粘贴图片,并以此提醒用户安装上传插件。在 Webkit 内核的浏览器下,我可以轻松地通过对可编辑元素进行 Actually, under IE, we can only use the method 实际上,在 IE 下我们只能通过方法
After my testing between IE8 to IE11, the method should return according to the scenario above. Therefore, if we want to implement such a requirement under IE, we can just check whether 经过 IE8 到 IE11 下的验证,该方法都会按照以上情况来返回不同的结果。因此,为了实现 IE 下检测用户粘贴的是否为一张图片,我们只需要判断方法是否返回 |
Two weird scenarios when listening to a property changing under IE(IE 下监听属性改变事件的两种奇怪场景)Today, I have met a horrible thing when using 今天在 IE 下使用
To work around two weird scenarios, there are some approaches: 因此为了解决这两种奇怪的场景,我们有以下几种方法:
|
Automatically adjust table under IE8(IE8 下表格宽度自适配)Assume that there is a table with being set as 假设有一个表格设置有 To work around this problem, we can simply use the following snippet, so that we can make the table adjustable for its changing contents: 当然,我们可以简单地通过以下代码片段来解决这个问题,以使得表格能自适配宽度。 table.style.display = 'inline-block';
setTimeout(function () {
/** macrotasks executed in next event loop */
table.style.display = '';
}, 0); |
Two global functions definition ways may be different under IE8(IE8 两种全局函数定义会有所不同)As a common sense of coding JavaScript, it is not a wise choice to define functions (or variables) globally, as developers struggle with defining conflict problems when using shared functions, especially when the project has become larger and larger, like SPA. 不要定义全局函数(或变量)早已成为 JavaScript 开发中的一个常识。源于使用共享函数时,大量的全局定义可能会使得开发者深陷于变量定义冲突的问题,尤其是当项目像单页面应用(SPA,Single-page Applications)那样越来越庞大的时候,身同体会。 However, it seems to be the only choice when you have to communicate with IE add-ons. For example, I have a task needing add-ons to handle asynchronously, and tell the result to me with a callback method named 然而,当你需要跟 IE 插件进行数据交互时,定义全局函数似乎是唯一可行的方法。举个例子来说,我需要插件异步处理一个任务,并通过回调告诉我结果。这种情况下,最寻常的做法是插件开发者会使用 FireBreath 来实现,而该框架下,你需要定义一个全局函数,并把函数名以字符串的形式传递给插件。这样,插件才能把结果回调至你所定义的函数。 function scope() {
/** function scope but not global one */
document.getElementById('#ie-plugin').runJSFunc('test', result); /** nothing happens */
/** throw "Method Invoke Failed" */
function test(result) {
/** handle with result */
};
} Ooops, there is something wrong under IE8!! 不会吧,IE8 怎么这么傲娇!! You can't define the function globally with 竟不能通过 try {
document.getElementById('#ie-plugin').runJSFunc('test', result);
} catch (e) {
console.log(e.message); /** => Method Invoke Failed. */
}
/** throw "Method Invoke Failed" */
window.test = function (results) {
/** handle with results */
}; That's why I marked this with document here, in order to tell you how to solve this with following workarounds: 这就是为何我要在此进行文档记录,以告知诸位如何用下面的方式解决问题:
|
Weird phenomena during loading IE add-ons(加载 IE 插件时出现的奇象)Recently, I have met some weird things when trying to load IE add-ons under IE 8 and 9. Since the IE add-on was designed as an 最近,在 IE8 和 IE9 下尝试加载 IE 插件时,又遇到了一些奇象。既然 IE 插件是被设计成 HTML 中的
However, due to some real developing requirements, I had to dynamically inject elements into DOM, and the first plan I designed was to use 然而,基于现实中的若干开发需求,我只能动态地往 DOM 插入该对象元素。而使用 const obj = document.createElement('object');
obj.id = 'ie-addon';
obj.setAttribute('type', 'application/x-xxxplugin');
const param = document.createElement('param');
param.setAttribute('name', 'onload');
param.setAttribute('value', 'pluginLoaded');
obj.appendChild(param);
/** `pluginLoaded` has not been invoked under IE9 */
document.body.appendChild(obj); The code snippet above seemed to run well under IE8, while something wrong happened when ran it under IE9. What I found was that the 上述的代码片段在 IE8 下似乎毫无瑕疵,而在 IE9 中却发生了奇怪的事情。我当时发现, const obj = document.createElement('object');
obj.id = 'ie-addon';
obj.setAttribute('type', 'application/x-xxxplugin');
const param = document.createElement('param');
param.setAttribute('name', 'onload');
param.setAttribute('value', 'pluginLoaded');
obj.appendChild(param);
document.body.innerHTML += obj.outerHTML; Cool, it really worked under IE9, BUT the plugin has broken down under IE8, as it was loaded more than once. After some confusing inspections, I doubted that the plugin had been already initialized once the 果真,方案在 IE9 确实行得通,但 IE8 下竟由于插件被多次加载导致插件崩溃。经过多番检查,我怀疑是因为插件在 document.body.innerHTML += `
<object id="ie-addon" type="application/x-xxxplugin">
<param name="onload" value="pluginLoaded" />
</object>
`; Additionally, register a loaded event handler on the current Window will unexpectedly result in memory leak under IE11 (version 11.431.16299.0), which means that the handler will be unexpectedly triggered while sending an XHR request. The detailed stack has been shown as followed: 此外,在 IE11(版本 11.431.16299.0)下若注册一个全局的 loaded 处理事件在当前 Window 对象,将会导致内存泄漏,即在 Xhr 请求发送时会意外调用到该处理事件。详细的调用堆栈如下:
To avoid unexpected calling by IE11, we may also need to release such a loaded handler by setting it as null after callback: 为了避免这种非预期内的意外发生,我们需要在 loaded 事件回调时释放该事件注册: window.pluginLoaded = function () {
/** any callback here ... */
window.pluginLoaded = null; /** avoid memory leak */
}; |
Notify downloading JSON responses under IE8/IE9 ?(IE8/IE9 下提示下载 JSON 返回请求?)When posting a file to the server, like uploading, we usually use multipart/form-data to construct our requests and wait for responses from the server, formatted with JSON in common. However, there will be troubles when requesting under IE8/IE9, where users will receive a notification to download the response as a file after requesting. This is also one of the most common problems arisen when using jQuery-File-Upload. That's because you have received a response with setting 当我们想上传一个文件给服务器时,大多数情况下我们通用的方法是使用 multipart/form 的方式来构造请求,并等待服务器返回一个 JSON 对象以判断其响应结果。然而在 IE8/IE9 下,用户会为此收到一个下载通知,提示下载返回的信息。这也是使用 jQuery-File-Upload 最为常见的问题之一。原因在于返回头设置了其 Content-Type 头部为 Why not 为何不用 |
Unable to select text through a content-editable element under IE?(IE 下无法在可编辑元素内选择文本?)When implementing an editor, which should be compatible through different browsers, especially IEs, you may need to take this issue tracker as a consideration, as I recently found that I could not select text from bottom to top, through a content-editable element within iframes under IE11 when the area was scrollable (such like a quite long paragraph). After debugging, this issue resulted because the implementation of the editor ignored to set elements as content-editable, rather than switching on the designed mode. 倘若你要实现一个兼容不同浏览器,尤其是 IE 浏览器的编辑器,你就要考虑以下我所遇到的问题。最近,我发现在 IE11 下一个 iframe 内的可编辑元素在可滚动的情况下,无法自下而上选择文本。后来通过调试发现,该问题是因为编辑器在实现元素可编辑化时,针对 IE11 错误把元素的 var iframeBody = docuemnt.querySelector('.j-editor').contentWindow.document.body;
iframeBody.designMode = 'on'; /** result in the problem of selecting text */ Instead of setting 为了解决该问题,需要设置 iframeBody.contentEditable = true; Similarly, I also found a documented issue under the Stack Overflow here. 此外,我在 Stack Overflow 上也找到类似问题记录,详情可参考此处。 |
Some problems about option tag under IE8/IE9(IE8 / 9 下 option 标签的一些问题)
|
Naming anonymous function problems under IE8(IE8 下慎重对匿名函数进行命名)const test = s;
function s() { console.log('outside'); }
const obj = {
s: function s() { console.log('inside'); }
};
test(); /** unexpected output => "inside" */ |
Some shim may have wrong implementation around
|
Don't try to prevent default events and cancel events bubbling in another event loop under IE8(IE8 下不要尝试在另一个事件循环去禁止默认事件及事件冒泡)document.onclick = function (e) {
e = e || window.event;
setTimeout(function () {
e.returnValue = false; /** thrown error: Member Not Found. */
});
}; Due to the COM object has destroyed its members after callback, referred from "Professional JavaScript for Web Developers" 根据《Professional JavaScript for Web Developers》的描述,COM 组件会在回调后自行销毁,而导致相关异常抛出。 Of course, you cannot also access some properties of 当然你在下一事件循环也无法访问 document.onclick = function (e) {
e = e || window.event;
setTimeout(function () {
console.log(e.type); /** thrown error: Member Not Found. */
});
}; In such a case, there is a workaround: 此情况并不是无法解决: document.onclick = function (e) {
e = e || window.event;
var type = e.type;
setTimeout(function () {
console.log(type); /** => "click" */
});
}; |
Keyup events won't fire when there is a button within the same Form under IE8/IE9/IE10(IE8/IE9/IE10 下若 input 标签所属 Form 含有 button 元素则无法监听 Keyup 事件)Recently, I found that when I was focusing on an input element, the Form of which had a button element, I couldn't get it fired on listening 最近,我发现在同一个 Form 表单内,含有 button 及 input 元素的时候,input 标签输入文字后按回车并不会触发所监听的 <input type="text" class="input-wrapper" value="" />
<button>test</button> $('input.input-wrapper').on('keyup', e => {
console.log(e.keyCode); /** cannot not print 13 when pressing "enter" key */
}); It seemed like the button element had captured the event and did not propagate to the input element. 从现象来看,像是 button 元素捕获了事件而没有往 input 元素传递。 There are two ways to work around such a problem: 为了解决该问题,有两个办法:
|
Some problems around IPv6 address you may need to know under IE8/IE9 (IE8 / 9 下一些关于 IPv6 地址的问题)
So if you want to avoid those kinds of problems, the smart way to construct URL is: 为了避免各种各样的问题,最好的方法是统一使用一个函数去构造: /**
* -----------------------------------------------------------------
* | location.host | document.domain | location.port | browser |
* | ::1:8080 | [::1] | 8080 | IE8 |
* | ::1:8080 | [::1] | 8080 | IE9 |
* | [::1]:8080 | [::1] | 8080 | IE10 |
* | [::1]:8080 | [::1] | 8080 | IE11 |
* | [::1]:8080 | [::1] | 8080 | Chrome |
* | [::1]:8080 | [::1] | 8080 | Firefox |
* -----------------------------------------------------------------
*/
const {protocol, port} = location;
const fullRequest = path => `${protocol}//${document.domain}${port ? `:${port}` : ''}/${path}`; |
|
|
A pseudo-element with some scrollbar styles defined will crash IE9(IE9 下一个伪元素若含有某些 scrollbar 样式定义会导致崩溃)Recently, I have found that if there are some defined scrollbar styles, you may suddenly crash IE9 when using 最近我发现如果定义了某些滚动条样式,使用 <!doctype html>
<html lang="en">
<head>
<style>
html {
SCROLLBAR-FACE-COLOR: #E1E1E1;
SCROLLBAR-HIGHLIGHT-COLOR: #EDEDED;
SCROLLBAR-SHADOW-COLOR: #B6B6B6;
SCROLLBAR-3DLIGHT-COLOR: #FFFFFF;
SCROLLBAR-DARKSHADOW-COLOR: #FFFFFF;
SCROLLBAR-ARROW-COLOR: #FFFFFF;
SCROLLBAR-TRACK-COLOR: #F4F4F4;
}
.target:before {
content: '';
}
</style>
</head>
<body>
<!-- scrollbar-base-color / scrollbar-darkshadow-color / scrollbar-face-color
scrollbar-highlight-color / scrollbar-shadow-color / scrollbar-track-color -->
<button class="target"
onclick="alert(window.getComputedStyle(this, ':before').getPropertyValue('scrollbar-3dlight-color'))">
click to crash IE9
</button>
</body>
</html> |
Wrong base64 images with texts from the clipboard under IE11 (IE11 下图文粘贴时错误的 base64 编码图片)When I tried to copy a snippet of texts and an image from a Word document at the same time, I found that the image from the clipboard under IE11 would specify a wrong Content-Type in the image base64 code like 当从 Word 文档同时粘贴一段图文时,就会发现 IE11 粘贴板内所拿到的图片 base64 地址含有错误的 Content-Type 如 References: 引用: |
We cannot access some attributes of
|
|
If you can't generate
|
This is a task for collecting some confusing problems during developing under IE, mostly when we really get confused with IE8!! To avoid struggling with IE, it's smart to do this as early as I can.
这个 Task 主要是为了收集 IE 开发中所遇到困惑,尤其当我们被 IE8 所折腾的时候。因此,为了避免陷入与 IE 的斗争,我理应尽早地去执行该任务。
Reference Articles:
引用文章:
Console is not defined under IE8
Predefined and limit some by UglifyJS via
{pure_funcs : ['debug', 'console.debug', 'console.warn']}
引入实现并通过 UglifyJS 限制部分方法使用
Blur event is fired when clicking on the scrollbar under IE8
Calculate the position of the mouse through the event and stop the propagation when clicking on the scrollbar.
计算鼠标位置并通过阻止事件传递解决问题
Internet Explorer's CSS rules limits
Use css-split-webpack-plugin to solve.
使用 css-split-webpack-plugin 来解决
The text was updated successfully, but these errors were encountered: