C# JavaScript Object.create和IE8
我在做SharePoint 2013的软件开发。其中一部分涉及覆盖SharePoint的文件预览器(filepreview.debug.js变为myfilepreview.debug.js)。然而,我们遇到了IE8的问题。在IE9中一切正常 IE8中抛出的错误会在激活自定义功能的网站集中您访问的任何网站上导致错误:“对象不支持此属性或方法” 在对这个错误做了一些研究之后,IE8似乎根本不支持C# JavaScript Object.create和IE8,c#,javascript,sharepoint,internet-explorer-8,sharepoint-2013,C#,Javascript,Sharepoint,Internet Explorer 8,Sharepoint 2013,我在做SharePoint 2013的软件开发。其中一部分涉及覆盖SharePoint的文件预览器(filepreview.debug.js变为myfilepreview.debug.js)。然而,我们遇到了IE8的问题。在IE9中一切正常 IE8中抛出的错误会在激活自定义功能的网站集中您访问的任何网站上导致错误:“对象不支持此属性或方法” 在对这个错误做了一些研究之后,IE8似乎根本不支持Object.create。似乎支持这个理论。当通过在抛出错误的行之前添加polyfill代码来解决问题时
Object.create
。似乎支持这个理论。当通过在抛出错误的行之前添加polyfill代码来解决问题时,我更相信这一点:
if (typeof Object.create !== 'function') {
Object.create = function (o) {
function F() { }
F.prototype = o;
return new F();
};
}
我想这是有道理的,因为它模仿了Object.create的功能,这在IE8中是不受支持的
然而,这令人困惑,因为SharePoint的文件预览器javascript工作正常。他们的javascript还使用Object.create。更奇怪的是,在javascript中抛出错误的代码部分甚至不是我们的代码——它是SharePoint的。到那时为止,整个javascript代码实际上与SharePoint的代码相同,只是有几行
以下是默认设置,直到有问题的行:
function $_global_filepreview() {
RegisterSod("mediaplayer.js", "_layouts/15/mediaplayer.js");
RegisterSod("sp.publishing.resources.resx", "/_layouts/15/ScriptResx.ashx?name=sp.publishing.resources&culture=" + STSHtmlEncode(Strings.STS.L_CurrentUICulture_Name));
RegisterSodDep("mediaplayer.js", "sp.publishing.resources.resx");
previewBase = (function() {
ULS7RK:
;
var filePreviewUniqueId = 0;
return {
init: function(ctxT, listItem, extension) {
this.fpId = ++filePreviewUniqueId;
this.fpDomId = "FilePreviewID-" + String(this.fpId);
this.fpCtx = ctxT;
this.fpExtension = extension;
this.fpListItem = listItem;
},
getHtml: function() {
ULS7RK:
;
return ['<div class="js-filePreview-containingElement" id=', StAttrQuote(this.fpDomId), '>', this.getInnerHtml(), '</div>'].join("");
},
getDomId: function() {
ULS7RK:
;
return this.fpDomId;
},
getContainingElement: function() {
ULS7RK:
;
var containingElement = document.getElementById(this.fpDomId);
Sys.Debug.assert(m$.isElement(containingElement), "Containing element has not been rendered yet.");
return containingElement;
},
canRender: function() {
ULS7RK:
;
return true;
},
getLoadingIndicatorHtml: function(customStyle) {
if (m$.isUndefined(customStyle)) {
customStyle = "";
}
return ['<div class="js-filePreview-loading-image" style="width:', this.getWidth(), 'px; height:', this.getHeight(), 'px; line-height:', this.getHeight(), 'px; text-align:center; vertical-align:middle; display: inline-block; ' + customStyle + '">', '<img src="', "/_layouts/15/images/gears_anv4.gif", '" />', '</div>'].join("");
},
hideLoadingIndicator: function() {
ULS7RK:
;
var containingElement = document.getElementById(this.fpDomId);
((m$(containingElement)).find("div.js-filePreview-loading-image")).css({
display: "none"
});
},
getInnerHtml: function() {
ULS7RK:
;
return "";
},
getWidth: function() {
ULS7RK:
;
return null;
},
getHeight: function() {
ULS7RK:
;
return null;
},
onPostRender: function() {
},
onVisible: function() {
},
onHidden: function() {
}
};
})();
//**This is where the "fix" was added originally**
blankPreview = Object.create(previewBase); <--- error is thrown here
所以我的问题是:为什么我会遇到这样一个错误,IE8不支持Object.create,而默认javascript中相同函数的其他使用却没有问题
编辑:另一个论坛的用户建议我尝试通过sod注册我的脚本。我在代码中添加了以下内容,但未生效:
RegisterSod("MyFilepreview.debug.js", "_layouts/15/MyFilepreview.debug.js");
尝试在IE中调试,并在SharePoint的默认JavaScript文件中设置断点。您确定默认JavaScript中Object.create的实例确实被命中了吗?它们没有使用带有正确参数的
Object.create
他们使用Object.create({name:value})
当它应该是Object.create({name:{value:value}})
所以他们可能定义了自己的对象。create
并且他们的代码在你的之后使用,所以你已经有了对象。当他们的代码运行时,create
设置,他们可能会像你一样测试存在性,并假设存在的是他们的版本,而实际上它是你的
因此,检查
对象的定义。在他们的代码中创建,并检查脚本的执行顺序。歇洛克·福尔摩斯要做的事情是得出结论,这两行中的一行导致类似的垫片被导入页面。当然,如果这是真的,那么在添加回代码行后失败(导致您拥有完全相同的代码)将毫无意义。因此,人们可能会质疑这一断言:这些真的是唯一的区别吗?@Pointy确实是一个非常有效的问题。我已经检查了两次和三次,这是到目前为止唯一的区别。sharepoint服务器可能会进行浏览器嗅探,从而为不同的浏览器返回不同的JS文件。您是否使用IE8或其他浏览器保存了此javascript代码(或者您在服务器端找到了此代码)?@molnarg有趣的建议,尽管我已经确认此代码对于IE8和IE9都完全相同。我是通过F12调试找到的。此外,我已在服务器上的15个配置单元中调出该文件,并确认它也是同一个文件。@t尝试替换对象。使用简单的新建previewBase()
创建。这会引发同样的错误吗?谢谢你的评论。在探索了一点之后,我发现确实有一个SharePoint原生javascript文件,它与我所做的polyfill完全相同。使用F12调试,我可以看到它和我的一起加载——所以现在我想问题是:为什么我的javascript不能在他们的javascript上加载它?当你填充它时,你是否检查了对象.create
包含的内容?你知道这不是一个函数。试着把它打印出来。第二个参数是属性描述符,而不是第一个。第一个是所创建对象的原型对象,它与object.create({name:value})
RegisterSod("MyFilepreview.debug.js", "_layouts/15/MyFilepreview.debug.js");