我可以为jQuery提供默认的“上下文”吗?

时间:2012-12-20 03:24:58

标签: javascript jquery iframe

背景:

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

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

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

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

问题:

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

示例:

document

问题是,是否可以在上面写上// 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'; 之类的内容?

为什么?

有时候你想要隔离第三方HTML组件(从安全角度来看你相信它们)从CSS / JavaScript污染的角度来看是不正常的。

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

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

1 个答案:

答案 0 :(得分:6)

实际上,这很简单:

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参数的存在都会破坏正常行为)。