我可以为jQuery提供默认的“上下文”吗?
背景:
可以提供jQuery选择器调用的第二个“context”参数(例如: jQuery(selector, context)
),以便为选择器引擎提供从中下降的起点。
如果您需要控制IFRAME中的内容(在同一个域中),这通常很有用。 您只需将iframe.contentWindow.document
作为“context”参数传递。
如果在使用jQuery的IFRAME中加载任何JavaScript代码,并且从外部窗口的范围调用,则该代码中对$
或jQuery
任何引用实际上都是来自外部窗口的jQuery
实例。
当IFRAME中的JavaScript代码(比如Bootstrap.js)执行类似$(document)
(或者没有“context”参数的其他选择器),问题就来了。 当从外部窗口调用该代码(在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
?
为什么?
有时,您希望隔离第三方HTML组件(从安全角度来看,您信任它们)从CSS / JavaScript污染角度来看是错误的。
Bootstrap.js就是一个很好的例子。 它调用$(document)
一个公平的位,并执行其他类似的无上下文选择器调用。 如果jQuery可以按照我描述的方式重新定义,那么这个“非最佳”编写的库可以很容易地被隔离。
另外,从两个框架使用相同的$.data(el, ...)
集合会非常有用,如果没有一些上下文管理,这是非常棘手的。
实际上,它会很简单:
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
参数的存在打破正常行为)。