2012-12-20 51 views
4

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

第二“上下文”参数jQuery选择呼叫(例如:jQuery(selector, context))可以被提供给选择器引擎从该下降的起点。

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

如果任何JavaScript代码被加载在其利用的jQuery的IFRAME,并且是CALLED从外WINDOW的范围,然后在该代码中的任何参考$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污染角度出错的第三方HTML组件(尽管您从安全角度信任它们)。

Bootstrap.js就是一个很好的例子。它调用$(document)一个公平的位,并做其他类似的无环境选择器调用。如果jQuery可以按照我描述的方式进行重新定义,那么这个“不是最优”的书写库可以很容易被隔离。

此外,它可以使用相同的$.data(el, ...)收集来自两个框架非常有帮助的,这是相当棘手没有一些上下文管理。

+0

为什么不是iframe加载jQuery本身并使用自己的jQuery对象? – Matchu

+0

它当然可以。但是,您需要在两个窗口中创建双向管道来回呼叫。比仅仅对现有HTML + JS内容进行子框架更加困难。另外,$ .data对于每个jQuery实例都是不同的,这可能不是所希望的。 –

+1

嗯。那么内部框架是使用外部框架的jQuery,还是使用内部框架jQuery的外部框架?如果是这样,为什么?一个显式的交互API在这里似乎更合适,因为它不那么脆弱(不假设其他页面具有jQuery或者它的DOM正是我们所期望的),对于其他开发人员来说更易读,并且完全避免了这些问题。 (当然,这与我有限的信息...) – Matchu

回答

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

+2

jQuery有许多其他方法,您可以使用$ .something(而不是选择器调用)进行调用。如果这些方法在没有内容的情况下进行选择器调用(内部),这可能是有限的方法。你认为这可能是这样吗? –

+1

那么,这就是为什么我将函数重命名为'''以外的东西,所以实际的代码不会中断。但是你想强制这个默认的上下文是'$';所以插件会无缝地使用它? –

+0

是(适用于插件)。我想我真正的问题是,jQuery内部是否在非选择器方法内进行选择器调用?如果是这样,那么还需要修补。 –

相关问题