注册SharePoint 2013中的自定义字段类型的JS
-
10-12-2019 - |
题
我有一个自定义字段类型为SharePoint 2010/2007,但在迁移到SharePoint 2013之后,我遇到了一个问题。
这是我在fldtypes_myfield.xml中为“renderPattern”定义的内容
<RenderPattern Name="DisplayPattern">
<HTML><![CDATA[<script type="text/javascript" src="/_layouts/myfield/myjs.js"></script>]]></HTML>
<HTML><![CDATA[<img src="/_layouts/images/myfield/pic.png" onload="myfun()">]]></HTML>
</RenderPattern>
.
myfun()在myjs.js中定义,因此加载pic.png时,它将执行该函数。它在2010/2007年和2010年的SharePoint 2013中的用户体验工作正常。
2013年,根据2013年的用户体验,当我查看包含MyField的列表时,它会抛出错误:
myfun is not defined
.
所以,原因很明显,myjs.js未添加到页面上。 (js链接是正确的,复制到地址栏和浏览器的链接可以显示它)
所以,我的问题是:为什么myjs.js没有注册?
有任何想法吗?提前致谢。
更新:
它不起作用在“ListView”页面中,但它适用于“显示格式”页面。 “CamlRendering”设置为真实。在“ListView”页面下,如果使用Web Developer工具检查字段,则为:中的HTML标记
.
<SCRIPT type=text/javascript src="/_layouts/myfield/myjs.js"></SCRIPT>
<DIV><IMG src="/_layouts/images/myfield/pic.png" onload="myfun()"></DIV>
SharePoint 2013禁止JS加载?
解决方案
在调试后,我发现有一个名为“wpq2listdata”的变量,可以存储列表数据内容,它的格式是:
var WPQ2ListData = {
"Row": [{
"ID": "1",
"PermMask": "0x7fffffffffffffff",
"FSObjType": "0",
"Title": "A",
"FileLeafRef": "1_.000",
"Created_x0020_Date.ifnew": "1",
"FileRef": "\u002ftest\u002fLists\u002fRatingList\u002f1_.000",
"File_x0020_Type": "",
"File_x0020_Type.mapapp": "",
"HTML_x0020_File_x0020_Type.File_x0020_Type.mapcon": "",
"HTML_x0020_File_x0020_Type.File_x0020_Type.mapico": "icgen.gif",
"ContentTypeId": "0x01008AD43674D321D3428ACAFC1C3BD2971E",
"MyField": "<script type=\"text/javascript\" src=\"/_layouts/myfield/myjs.js\"></script><img src=\"/_layouts/images/myfield/pic.png\" onload=\"myfun()\">"
}],
"FirstRow": 1,
"LastRow": 1,
"FilterLink": "?",
"ForceNoHierarchy": "1",
"HierarchyHasIndention": ""
.
}
注意“myfield”,它具有应该呈现的内容。
在页面中,“WPQ2LISTDATA”用于一个地方:
ctx = new ContextInfo();
//other assignments
ctx.ListData = WPQ2ListData;
.
然后“CTX”将传递给函数“renderListView”,这负责呈现列表视图。此函数在“clientTemplates.js”中定义。如果您潜入其中,您会发现它会调用另一个名为“spclientRender.render”的函数,在此函数中,它将为列表数据生成整个HTML内容,并将其插入TD(也许是DIV)。 innerhtml。
var result = SPClientRenderer.RenderCore(renderCtx);
if (result != null && result != '') {
if (node.tagName == "DIV" || node.tagName == "TD") {
if (renderCtx.fHidden)
if (renderCtx.fHidden)
node.innerHTML = result;
}else{
//create div element, and insert result as innerHTML
}
}
.
注意“node.innerhtml=结果”,因为如果将某个字符串内容插入一个元素作为innerhtml并且内容包含javascript代码,则不会执行js代码。这就是为什么“myjs.js”未添加到页面! 我认为这是2010年和2013年渲染列表视图的巨大差异之一,2010年,列表数据HTML直接输出页面,而在2013年动态插入页面。
解决方案:
实际上,仍然存在一个包含JS代码的地方,可以执行代码。它是IMG中的“onload”。那么,为什么我们不在这里注册我们的JS文件?在加载myjs.js后,让它调用myfun()!
.
var head = document.getElementsByTagName("head")[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = '/_layouts/myfield/myjs.js';
script.onload = script.onreadystatechange = function() {
myfun();
};
head.appendChild(script);
而对于更好的性能,我们不必为每行注册myjs.js,我们应该检查它是否首先存在。