首先,让我使用此图解释如何实现异步文件上传:
抱歉.我关闭了我的一个域名,图像现在已经消失了.这是一个非常好的形象.这是在我发现Stack Overflow允许通过Imgur上传图像之前.
正如您所看到的,诀窍是让HTTP响应加载到隐藏的IFRAME元素而不是页面本身.(这是通过target在使用JavaScript提交FORM时设置FORM元素的属性来完成的.)
这有效.但是,我面临的问题是服务器端脚本位于不同的域上.FORM-submit是一个跨域HTTP请求.现在,服务器端脚本启用了CORS,这使我的网页有权读取从我的页面到该脚本发出的HTTP请求的响应数据 - 但这只有在我通过Ajax接收HTTP响应时才有效, ergo,JavaScript.
但是,在这种情况下,响应指向IFRAME元素.一旦XML响应进入IFRAME,其URL将是删除脚本 - 例如http://remote-domain.com/script.pl.
不幸的是,CORS没有涵盖这种情况(至少我认为) - 我无法读取IFRAME的内容,因为它的URL与页面的URL(不同的域)不匹配.我收到此错误:
不安全的JavaScript尝试使用URL hxxp://my-domain.com/outer.html从具有URL hxxp://remote-domain.com/script.pl的框架访问框架.域,协议和端口必须匹配.
由于IFRAME的内容是一个XML文档,因此IFRAME中没有可以使用的JavaScript代码postMessage.
所以我的问题是:如何从IFRAME获取XML内容?
正如我上面所说,我能够直接检索跨域HTTP响应(启用CORS),但似乎我无法在加载到IFRAME后读取跨域HTTP响应.
好像这个问题不够无法解决,让我排除这些解决方案:
easyXDM和类似技术需要远程域上的端点,
改变XML响应(包括SCRIPT元素),
服务器端代理 - 我知道我的域可以有一个服务器端脚本,可以作为代理.
那么,除了这两个解决方案,这可以做到吗?
事实证明,可以伪造一个模仿multipart/form-dataFORM提交的XHR请求(Ajax请求)(在上面的图像中用于将文件上传到服务器).
诀窍是使用FormData构造函数 - 阅读此Mozilla Hacks文章以获取更多信息.
这是你如何做到的:
// STEP 1
// retrieve a reference to the file
// <input type="file"> elements have a "files" property
var file = input.files[0];
// STEP 2
// …Run Code Online (Sandbox Code Playgroud) 鉴于这种简单的结构:
<div id="parent">
<div id="child">Lorem ipsum</div>
</div>
Run Code Online (Sandbox Code Playgroud)
用这个CSS:
#parent {
width: 200px;
height: 200px;
padding: 20px;
overflow-x: scroll;
}
#child {
width: 500px;
}
Run Code Online (Sandbox Code Playgroud)
现场演示: http ://jsfiddle.net/523me/5/
请注意,父级有一个20px填充,并且子级水平溢出(因为它更宽).如果您将父级一直向右滚动,您将看到孩子触摸父级的右边缘.
因此,父级应该有一个正确的填充,但它被忽略.看起来当孩子有一个固定的宽度时,父母的右边填充不适用.(这是用标准规定的吗?我很想知道.如果你发现什么,请告诉我!)
有没有办法强制在这种情况下应用正确的填充,而不必从流中删除任何元素(通过浮动或定位)?

屏幕截图1 - 忽略右边距.这就是当前所有浏览器的行为方式.
屏幕截图2 - 适用于右侧填充.这就是我想要完成的.(顺便说一句,截图来自IE7,这是唯一一个不会忽略正确填充的浏览器.)
假设我们x在页面上有一个DIV ,我们想要将该DIV的内容复制("复制粘贴")到另一个DIV中y.我们可以这样做:
y.innerHTML = x.innerHTML;
Run Code Online (Sandbox Code Playgroud)
或者使用jQuery:
$(y).html( $(x).html() );
Run Code Online (Sandbox Code Playgroud)
但是,看起来这种方法不是一个好主意,应该避免.
(1)为什么要避免这种方法?
(2)应如何做呢?
更新:
为了这个问题,让我们假设DIV中没有ID的元素x.
(对不起,我忘了在原来的问题中报道这个案子.)
结论:
我已经在下面发布了我自己的答案(正如我原先的意图).现在,我也计划接受我自己的答案:P,但是我的答案是如此惊人,以至于我不得不接受它.
IE的开发工具,更具体地说是它的JavaScript调试器,提供了"Set next statement"命令,使您可以指定下一个应该执行的语句.这样,您可以有效地跳过函数的某些部分,甚至(再次,有效地)提前从函数返回.
所以,对于这个功能......
function test () {
alert(1);
alert(2);
alert(3);
}
Run Code Online (Sandbox Code Playgroud)
如果我们在第一个警报上设置断点,然后调用该函数,我们可以执行第一个警报(F10),然后右键单击第三个警报并选择"设置下一个语句".现在,如果我们按F10,将执行第三个警报,因此,有效地,跳过了第二个警报.
(测试在IE 这里:---打开IE与F12工具,切换到"脚本"选项卡,设置断点,按"开始调试"按钮,必要时刷新页面)
我喜欢这个"set next statement"功能.但是,我没有在Chrome的开发工具或Firebug中注意到它.这些调试器中是否存在此功能?
假设这个JSON对象:
var obj = {
"set1": [1, 2, 3],
"set2": [4, 5, 6, 7, 8],
"set3": [9, 10, 11, 12]
};
Run Code Online (Sandbox Code Playgroud)
可以像这样检索"set2"属性:
obj["set2"]
Run Code Online (Sandbox Code Playgroud)
有没有办法通过索引检索"set2"属性?它是JSON对象的第二个属性.这当然不起作用:
obj[1]
Run Code Online (Sandbox Code Playgroud)
所以,让我们说我想要检索JSON对象的第二个属性,但我不知道它的名字 - 那我该怎么做呢?
更新:是的,我知道对象是无序属性的集合.但我不认为浏览器会混淆JSON文字/字符串定义的"原始"顺序.
ECMAScript第五版(2009年12月发布)介绍了一系列新方法(详见此表).但是,仍然存在那些没有实现这些新方法的旧浏览器.
幸运的是,存在一个方便的脚本(用JavaScript编写) - ES5-shim - 它在不存在的环境中手动实现这些方法.
但是,我不确定如何提供ES5-shim ...我应该只是"给"所有浏览器,如下所示:
<script src="es5-shim.js"></scipt>
Run Code Online (Sandbox Code Playgroud)
或者我应该包括一个检查,以便"打扰"那些真正需要它的浏览器,如下所示:
<script>
if ( !Function.prototype.hasOwnProperty( 'bind' ) ) {
(function () {
var shim = document.createElement( 'script' );
shim.src = 'es5-shim.js';
var script = document.getElementsByTagName( 'script' )[0];
script.parentNode.insertBefore( shim, script );
}());
}
</script>
Run Code Online (Sandbox Code Playgroud)
(我Function.prototype.bind用来检查浏览器是否实现了所有新的ECMAScript 5方法.根据我上面链接的兼容性表,bind它是实现ECMAScript 5方法的"最后堡垒".)
当然,为了使这个垫片有效,它必须在所有其他脚本之前执行,这意味着我们希望在页面的早期包含上述SCRIPT元素(在HEAD中,在所有其他SCRIPT元素之前).
那么,第二个例子是否是向浏览器提供ECMAScript 5-shim的好方法?有没有更好的方法呢?
我在页面上有一堆段落:
<p> ... </p>
<p> ... </p>
<p> ... </p>
Run Code Online (Sandbox Code Playgroud)
这些段落的CSS规则是:
p {
margin: 20px 0;
page-break-inside: avoid;
}
Run Code Online (Sandbox Code Playgroud)
现场演示: http ://jsfiddle.net/KE9je/2/show/
如果我page-break-inside正确理解了属性,上面应该确保在两个页面之间没有分割段落.(段落显示在"当前"页面上,或者如果它不完全适合,则会移到下一页.)
这在Chrome中似乎不起作用.打开演示,右键单击页面,选择"打印...".您将看到打印预览 - 第五段在第1页和第2页之间分开.
我究竟做错了什么?如何在Chrome中完成此工作?

我有一个常规的文本框:
<input type="text">
Run Code Online (Sandbox Code Playgroud)
我使用jQuery来处理与键相关的事件:
$("input:text").keydown(function() {
// keydown code
}).keypress(function() {
// keypress code
}).keyup(function() {
// keyup code
});
Run Code Online (Sandbox Code Playgroud)
用户专注于文本框并按下键盘上的各种键(通常的键:字母,数字,SHIFT,BACKSPACE,SPACE,......).我需要检测用户何时按下将增加文本框值长度的键.例如,"A"键会增加它,"SHIFT"键不会.
我记得看过PPK的讲座,他提到了这两者之间的区别.它与事件有关 - keydown与keypress - 可能还有事件属性 - key,char,keyCode.
更新!
我需要在keydown或keypress处理程序中知道这些信息.我不能等待keyup事件发生.
为什么我需要这个:
我有一个文本框,其大小根据用户输入动态变化.你可以看看这个演示:http://vidasp.net/tinydemos/variable-size-text-box.html
在演示中,我有一个keydown和keyup处理程序.keyup处理程序根据输入值调整文本框大小.但是,keydown处理程序将大小设置为比输入值大1个字符.我这样做的原因是,如果我没有,那么角色将溢出文本框外,只有当用户放开键时,文本框才会展开.这看起来很奇怪.这就是我必须预测新角色的原因 - 在文字框中出现角色之前,我会在每个keydown上放大文本框.正如您在演示中看到的,这种方法看起来很棒.
然而,问题是BACKSPACE和ARROW键 - 它们还将扩展keydown上的文本框,并且只有在keyup上才会更正文本框大小.
解决方法:
解决方法是手动检测BACKSPACE,SHIFT和ARROW键,并根据:
// keydown handler
function(e) {
var len = $(this).val().length;
if (e.keyCode === 37 || e.keyCode === 39 ||
e.keyCode === 16) { // ARROW LEFT or ARROW RIGHT or SHIFT key
return;
} else if (e.keyCode === …Run Code Online (Sandbox Code Playgroud) 根据这个讨论,ECMAScript 6中可以定义多行字符串,而不必将字符串的后续行放在行的最开头.
Allen Wirfs-Brock的帖子包含一个代码示例:
var a = dontIndent
`This is a template string.
Even though each line is indented to keep the
code neat and tidy, the white space used to indent
is not in the resulting string`;
Run Code Online (Sandbox Code Playgroud)
有人可以解释一下如何实现这一目标吗?如何定义这个dontIndent东西以删除用于缩进的空格?
让我们创建一个简单的Deferred对象:
defer = $.Deferred( function ( defer ) {
setTimeout( defer.resolve, 3000 );
});
Run Code Online (Sandbox Code Playgroud)
上面的Deferred对象将处于"pending"状态3秒,然后切换到"已解决"状态(此时将调用绑定到它的所有回调).
我们还检索该Deferred对象的承诺:
promise = defer.promise();
Run Code Online (Sandbox Code Playgroud)
现在,要添加在解析Deferred对象后将要调用的回调,我们可以使用.done()或.then().不过,我们可以调用这个方法既递延对象本身或者它自己的诺言对象.
defer.then( handler );
Run Code Online (Sandbox Code Playgroud)
要么
promise.then( handler );
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,handler都将调用该函数(在这种情况下3秒后).
如果我们使用$.when,我们可以再次传递Deferred对象本身或其promise对象:
$.when( defer ).then( handler );
Run Code Online (Sandbox Code Playgroud)
要么
$.when( promise ).then( handler );
Run Code Online (Sandbox Code Playgroud)
同样,上面两行代码之间没有区别.
现场演示: http ://jsfiddle.net/G6Ad6/
所以,我的问题是因为我们可以在Deferred对象本身上调用.then(),.done()等等,因为我们可以将Deferred对象传递给$.when(),.promise()并且检索promise对象的意义是什么?promise对象的目的是什么?为什么功能上有这种冗余?
javascript ×8
html ×5
browser ×3
jquery ×3
css ×2
cross-domain ×1
debugging ×1
deferred ×1
ecmascript-5 ×1
ecmascript-6 ×1
es5-shim ×1
file-upload ×1
firebug ×1
iframe ×1
json ×1
overflow ×1