SharePoint 2019经典站点CEWP/SEWP JS代码返回列表后失效求助
问题排查与解决方案
首先,你遇到的这个问题在SharePoint经典站点的CEWP/SEWP组合场景里挺常见,核心原因大多和脚本作用域丢失或者SharePoint客户端对象模型(CSOM)的加载时机有关,咱们一步步拆解解决:
可能的根因
- 导航后的作用域丢失:经典站点返回列表页时,可能会触发部分页面刷新或缓存复用,导致SEWP里定义的
retrieveWebSite函数没有被重新注册到全局作用域,按钮点击时找不到对应函数。 - CSOM脚本初始化异常:虽然你手动引用了
sp.runtime.js和sp.js,但页面导航后这些脚本可能未被正确重新初始化,导致SP.ClientContext无法正常创建。
针对性修复方案
方案1:强制将函数挂载到全局作用域
把你的函数明确绑定到window对象上,确保页面刷新/导航后函数始终在全局作用域可访问:
<script src="/sites/xyz/29jl2020/SiteAssets/js/jquery-3.5.1.min.js"></script> <script src="/_layouts/15/sp.runtime.js" type="text/javascript"></script> <script src="/_layouts/15/sp.js" type="text/javascript"></script> <script type="text/javascript"> // 挂载到全局window对象 window.siteUrl = 'https://somesite.com/sites/xyz/29jl2020/'; window.retrieveWebSite = function() { // 先校验SP命名空间是否存在 if (typeof SP === 'undefined') { alert("SharePoint核心脚本还未加载完成,请稍等"); return; } alert("Hello World"); var clientContext = new SP.ClientContext(window.siteUrl); this.oWebsite = clientContext.get_web(); clientContext.load(this.oWebsite); clientContext.executeQueryAsync( Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed) ); }; window.onQuerySucceeded = function(sender, args) { alert('Title: ' + this.oWebsite.get_title() + ' Description: ' + this.oWebsite.get_description()); }; window.onQueryFailed = function(sender, args) { alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace()); }; </script>
同时修改CEWP里的按钮调用方式:
<input id="btnClick" onclick="retrieveWebSite();" type="button" value="add a new item"/>
方案2:用SharePoint SOD机制确保CSOM加载完成
SharePoint自带的脚本加载器(SOD)可以自动处理依赖脚本的加载顺序,避免导航后脚本未初始化的问题,还能省去手动引用sp.runtime.js和sp.js的步骤:
<script src="/sites/xyz/29jl2020/SiteAssets/js/jquery-3.5.1.min.js"></script> <script type="text/javascript"> var siteUrl = 'https://somesite.com/sites/xyz/29jl2020/'; window.retrieveWebSite = function() { // 确保sp.js加载完成后再执行逻辑 SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function() { alert("Hello World"); var clientContext = new SP.ClientContext(siteUrl); var oWebsite = clientContext.get_web(); clientContext.load(oWebsite); clientContext.executeQueryAsync( function() { alert('Title: ' + oWebsite.get_title() + ' Description: ' + oWebsite.get_description()); }, function(sender, args) { alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace()); } ); }); }; </script>
方案3:合并脚本与按钮到同一个WebPart
分开使用SEWP和CEWP可能引发作用域隔离问题,把所有代码(包括按钮)放到同一个CEWP里,能确保脚本和按钮在同一作用域下,避免函数找不到的情况:
<script src="/sites/xyz/29jl2020/SiteAssets/js/jquery-3.5.1.min.js"></script> <script type="text/javascript"> var siteUrl = 'https://somesite.com/sites/xyz/29jl2020/'; function retrieveWebSite() { SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function() { alert("Hello World"); var clientContext = new SP.ClientContext(siteUrl); var oWebsite = clientContext.get_web(); clientContext.load(oWebsite); clientContext.executeQueryAsync( function() { alert('Title: ' + oWebsite.get_title() + ' Description: ' + oWebsite.get_description()); }, function(sender, args) { alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace()); } ); }); } </script> <input id="btnClick" onclick="retrieveWebSite();" type="button" value="add a new item"/>
调试小技巧
如果想快速验证是不是函数丢失问题,点击按钮前打开浏览器开发者工具(F12),在控制台输入retrieveWebSite,如果返回undefined,说明函数确实没在全局作用域,方案1就能直接解决。
内容的提问来源于stack exchange,提问作者Benny H.
相关产品推荐
相关产品推荐

