小编Šim*_*das的帖子

是否可以执行异步跨域文件上传?

有可能的!参见下文.


首先,让我使用此图解释如何实现异步文件上传:


抱歉.我关闭了我的一个域名,图像现在已经消失了.这是一个非常好的形象.这是在我发现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响应.

好像这个问题不够无法解决,让我排除这些解决方案:

  1. easyXDM和类似技术需要远程域上的端点,

  2. 改变XML响应(包括SCRIPT元素),

  3. 服务器端代理 - 我知道我的域可以有一个服务器端脚本,可以作为代理.

那么,除了这两个解决方案,这可以做到吗?


可以办到!!

事实证明,可以伪造一个模仿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)

html javascript iframe file-upload cross-domain

47
推荐指数
1
解决办法
2万
查看次数

当子元素水平溢出时,为什么忽略父元素的右边距?

鉴于这种简单的结构:

<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,这是唯一一个不会忽略正确填充的浏览器.)

html css browser overflow

47
推荐指数
4
解决办法
1万
查看次数

为什么y.innerHTML = x.innerHTML; 要避免吗?

假设我们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,但是我的答案是如此惊人,以至于我不得不接受它.

html javascript browser jquery

46
推荐指数
4
解决办法
3978
查看次数

Chrome的开发工具或Firebug中是否存在"设置下一个语句"功能?

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中注意到它.这些调试器中是否存在此功能?

javascript debugging firebug google-chrome-devtools

44
推荐指数
1
解决办法
7976
查看次数

通过索引检索JSON对象的属性?

假设这个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文字/字符串定义的"原始"顺序.

javascript json

38
推荐指数
6
解决办法
13万
查看次数

如何提供ECMAScript 5(ES 5)-shim?

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的好方法?有没有更好的方法呢?

html javascript browser ecmascript-5 es5-shim

37
推荐指数
3
解决办法
2万
查看次数

page-break-inside在Chrome中不起作用?

我在页面上有一堆段落:

<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中完成此工作?


html css google-chrome

36
推荐指数
6
解决办法
5万
查看次数

如何检测按下的键是否会在<input>文本框中产生一个字符?

我有一个常规的文本框:

<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)

javascript jquery keyboard-events

34
推荐指数
4
解决办法
4万
查看次数

多行字符串,不会破坏缩进

根据这个讨论,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东西以删除用于缩进的空格?

javascript ecmascript-6 template-strings

32
推荐指数
4
解决办法
6276
查看次数

Deferred对象和它自己的promise对象之间有什么区别?

让我们创建一个简单的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 jquery deferred

28
推荐指数
1
解决办法
4534
查看次数