d3.selection类型检查IE [英] d3.selection type check in IE
问题描述
如何检查给定对象是否是 d3
选择?
How to check if a given object is a d3
selection?
$ c> true 在Chrome和Firefox中,但在Internet Explorer中 false
:
The following code prints true
in Chrome and Firefox, but false
in Internet Explorer:
console.log(d3.select(document.body) instanceof d3.selection)
推荐答案
更新2017-01-17
随着D3 v4 问题已消失( changelog ):
使用 not-allow-to-subclass-an-array /#wrappers_prototype_chain_injectionrel =nofollow noreferrer>原型链注入;
Selections no longer subclass Array using prototype chain injection; they are now plain objects, improving performance.
并且API docs 显式声明:
And the API docs explicitly state:
[…] 此函数也可用于测试选择( instanceof d3.selection
)
[…] This function can also be used to test for selections (instanceof d3.selection
)
使用新版本,以下代码将在所有浏览器中实际计算为true:
Using the new version, the following code will actually evaluate to true in all browsers:
d3.select() instanceof d3.selection // true in Chrome, FF, IE
由于D3的每个浏览器的内部工作,它支持 将会打印 true
/ Object / protorel =nofollow noreferrer> Object.prototype .__ proto __
,而不支持 __ proto __
的浏览器将打印 false
。检查兼容性列表很明显,那么IE< 11将评估表达式到 false
。因此,您将无法使用 instanceof d3.selection
来检查IE <11中的D3选择。这是使用D3的已知问题,但它已关闭,无法修复。
Due to the inner workings of D3 every browser which supports Object.prototype.__proto__
will print true
, whereas browsers lacking support for __proto__
will print false
. Checking the compatibility list it's obvious, that IE<11 will evaluate the expression to false
. For this reason, you won't be able to use instanceof d3.selection
to check for a D3 selection in IE<11. This is a known issue with D3, but it was closed and will not get fixed.
从D3的github存储库:
From D3's github repository:
-
selection / selection.js
查看 d3.select()
这是您的通话入口点:
Looking at the definition of d3.select()
which is the entry point of your call:
d3.select = function(node) {
// ... removed for brevity
return d3_selection([group]);
};
这将最终返回对 d3_selection()
,其又将子类化 d3_selectionPrototype = d3.selection.prototype
。
function d3_selection(groups) {
d3_subclass(groups, d3_selectionPrototype);
return groups;
}
- code> core / subclass.js
最后, a href =https://github.com/d3/d3/blob/9cc9a875e636a1dcf36cc1e07bdf77e1ad6e2c74/src/core/subclass.js =nofollow noreferrer> d3_subclass()
提供了问题的答案:
Finally, the implementation of d3_subclass()
provides the answer to the problem:
var d3_subclass = {}.__proto__?
// Until ECMAScript supports array subclassing, prototype injection works well.
function(object, prototype) {
object.__proto__ = prototype;
}:
// And if your browser doesn't support __proto__, we'll use direct extension.
function(object, prototype) {
for (var property in prototype) object[property] = prototype[property];
};
如果浏览器支持 Object.prototype .__ proto __
通过检查空对象 {}
上是否存在 __ proto __
访问器属性。如果浏览器支持它,D3将直接分配原型,从而使其成为 d3.selection
的一个实例。否则,原型的所有属性将被复制到要返回的对象,而不用明确地设置原型。在这种情况下,您的表达式将求值为 false
。
It checks, if the browser supports Object.prototype.__proto__
by checking for the existence of the __proto__
accessor property on an empty object {}
. If the browser supports it, D3 will directly assign the prototype, thus making it an instance of d3.selection
. Otherwise, all properties of the prototype will be copied over to the object to be returned without explicitely setting the prototype. In this case your expression will evaluate to false
.
因为 d3.selection
作为扩展选择功能的手段,您可以通过向 d3.selection $添加新属性来实施解决方法c $ c>如上所述,通过任何选择,通过原型或通过复制属性可以访问。
Because d3.selection
is provided as a means to extend the selection's functionality you could implement a workaround by adding a new property to d3.selection
which will, as was explained above, be made accessible by any selection, wether by prototyping or by copying properties.
// Include this at the start of your script to include the
// property in any selection created afterwards.
d3.selection.prototype.isD3Selection = true;
console.log(d3.select(document.body).isD3Selection); // true in any browser
这篇关于d3.selection类型检查IE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!