4

背景:

可以提供jQuery 选择器调用的第二个“上下文”参数(例如:)jQuery(selector, context),为选择器引擎提供一个下降的起点。

如果您需要控制 IFRAME(在同一域中)中的内容,这通常很有用。您只需iframe.contentWindow.document作为“上下文”参数传递。

如果在使用 jQuery 的 IFRAME 中加载了任何 JavaScript 代码,并且从外部窗口的范围调用,那么对该代码的任何引用$jQuery在该代码中实际上都是jQuery来自外部窗口的实例。

当 IFRAME 中的 JavaScript 代码(例如 Bootstrap.js)执行类似操作$(document)(或执行其他没有“上下文”参数的选择器)时,问题就出现了。当从外部窗口调用该代码(在 iframe 内定义)时,document指的是外部窗口中的 HTMLDocument 元素——这通常不是预期的结果。

问题:

能够创建具有默认“上下文”参数的 jQuery 的词法范围副本/包装器将非常有用,该参数由创建它的人提供。

例子:

// jQuery already exists out here
var iframe = document.createElement('IFRAME');
iframe.addEventListener('DOMContentLoaded', function(){

    // code in here can already refer to $ for 'outer' jQuery

    // code in here can refer to $local for 'inner' jQuery by virtue of...
    var $local = jQueryWithContext($, iframe.contentWindow.document);

    // code loaded with IFRAME will use $local by virtue of ...
    iframe.contentWindow.jQuery = iframe.contentWindow.$ = $local;

});
iframe.src = '/path/to/iframe/content.html';

问题是,是否可以编写类似jQueryWithContext上面的内容?

为什么?

有时您想隔离从 CSS / JavaScript 污染的角度来看行为不端的 3rd 方 HTML 组件(虽然您从安全角度信任它们)。

Bootstrap.js 就是一个很好的例子。它调用$(document)了一个公平的位,并执行其他类似的无上下文选择器调用。如果可以按照我描述的方式重新定义 jQuery 的范围,那么这个“非最佳”编写的库可以很容易地被隔离。

此外,从两个框架中使用相同的集合会非常有帮助,$.data(el, ...)如果没有一些上下文管理,这将非常棘手。

4

1 回答 1

7

实际上,它会很简单:

function jQueryWithContext( selector, context ) {
  // I added the possibility to overwrite the context here, but you could delete
  return $( selector, context || iframe.contentWindow.document );
}
jQueryWithContext( '#main' ).show();

但是要将其强制插入插件,您可能需要这样做:

jQuery.noConflict(); // keep the real jQuery for now
$ = function( selector, context ){
  return new jQuery.fn.init( selector, context || iframe.contentWindow.document );
};
$.fn = $.prototype = jQuery.fn;
jQuery.extend( $, jQuery ); // copy static method
// Then override default jQuery
jQuery = $;

这有点工作,但它可能会破坏某些用法$()(也许现在不是,但在未来的 jQuery 版本中可能,或者任何时候context参数的存在都会破坏正常行为)。

于 2012-12-20T03:29:30.083 回答