You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MSPO新建项目页面People Picker报错:SPClientPeoplePickerDict未定义原因?

为什么在MSPO新建项目页面的iframe中SPClientPeoplePickerDict未定义?

核心原因

  • 上下文隔离限制:iframe是独立的浏览器执行上下文,主页面加载的clientpeoplepicker.js等SharePoint组件脚本不会共享到iframe内部。你的脚本在主页面加载这些资源,但实际要操作的DOM和需要的全局对象都在iframe中,导致iframe的window里不存在SPClientPeoplePicker相关对象,自然找不到SPClientPeoplePickerDict。
  • 脚本加载目标错误:原代码在主页面的myJQueryCode中加载PeoplePicker依赖脚本,但这些脚本被加载到主页面而非iframe的上下文中,iframe无法访问这些全局方法和对象。
  • DOM操作上下文混淆:你在主页面的函数中操作iframe的DOM,但初始化PeoplePicker时调用的SPClientPeoplePicker_InitStandaloneControlWrapper是主页面的全局方法,无法在iframe的DOM元素上正确初始化组件,因此不会生成SPClientPeoplePickerDict对应的条目。

修复方案

关键修改思路

  1. 必须将PeoplePicker的依赖脚本注入到iframe内部的上下文,而非主页面
  2. 等待iframe完全加载完成后再执行DOM操作和脚本初始化
  3. 所有针对iframe的操作,都要使用iframe的window和document对象,而非主页面的全局上下文

修改后的完整脚本

$(document).ready(function () { 
    ExecuteOrDelayUntilScriptLoaded(CustomAction, "sp.js"); 
});

function CustomAction() {
    var targetFields = ['Project Sponsor'];
    var iframe = document.querySelector('iframe.pwa-animate-in');

    // 等待iframe完全加载完成
    iframe.addEventListener('load', function() {
        var innerWindow = iframe.contentWindow;
        var innerDoc = innerWindow.document;

        // 向iframe注入jQuery(如果未加载)
        if (typeof innerWindow.jQuery == 'undefined') {
            var s = innerDoc.createElement("script");
            s.src = '//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js';
            s.addEventListener("load", function () { 
                loadPeoplePickerScripts(innerWindow, innerDoc, targetFields); 
            }, false);
            innerDoc.getElementsByTagName('head')[0].appendChild(s);
        } else {
            loadPeoplePickerScripts(innerWindow, innerDoc, targetFields);
        }
    });
}

function loadPeoplePickerScripts(innerWindow, innerDoc, targetFields) {
    var $ = innerWindow.jQuery;
    var scriptRoot = innerWindow._spPageContextInfo.siteAbsoluteUrl + '/_layouts/15/';
    
    // 在iframe内部加载PeoplePicker依赖脚本
    $.when(
        $.getScript(scriptRoot + "clienttemplates.js"),
        $.getScript(scriptRoot + "clientforms.js"),
        $.getScript(scriptRoot + "clientpeoplepicker.js"),
        $.getScript(scriptRoot + "autofill.js")
    ).done(function () {
        renderPeoplePickers(innerWindow, innerDoc, $, targetFields);  
    }).fail(function (message) {
        innerWindow.console && console.error('加载脚本失败: ' + message);
    });
}

function renderPeoplePickers(innerWindow, innerDoc, $, targetFields) {
    var $innerDoc = $(innerDoc);
    for (var fieldIndex = 0; fieldIndex < targetFields.length; fieldIndex++) {
        $innerDoc.find("input[type='text'][title='" + targetFields[fieldIndex] + "']").each(function () {
            this.style.color = "green";
            renderPeoplePicker(innerWindow, $, this);
            innerWindow.console && console.log('PeoplePicker已渲染: ' + targetFields[fieldIndex]);
        });
    }
}

function renderPeoplePicker(innerWindow, $, targetInput) {  
    var divPeoplePicker = innerWindow.document.createElement('div');
    var idPeoplePicker = targetInput.id + '_PeoplePicker';
    var targetValue = $(targetInput).attr('value');
    divPeoplePicker.id = idPeoplePicker;
    $(targetInput).parent().append(divPeoplePicker);

    // 使用iframe的window上下文初始化PeoplePicker
    innerWindow.SPClientPeoplePicker_InitStandaloneControlWrapper(idPeoplePicker, null, {
        'PrincipalAccountType': 'User',
        'SearchPrincipalSource': 15,
        'ResolvePrincipalSource': 15,
        'AllowMultipleValues': false,
        'MaximumEntitySuggestions': 50,
        'Width': '360px'
    });

    // 从iframe的全局对象中获取PeoplePicker实例
    var newPeoplePicker = innerWindow.SPClientPeoplePicker.SPClientPeoplePickerDict[idPeoplePicker + '_TopSpan'];
    $(targetInput).hide();

    if (typeof targetValue !== "undefined" && targetValue !== "") {
        var selectedUsers = targetValue.split(";");
        for(var i=0;i<selectedUsers.length;i++) {
            if(selectedUsers[i] && selectedUsers[i] != "") {
                newPeoplePicker.AddUnresolvedUser( {
                    Key: selectedUsers[i],
                    DisplayText: selectedUsers[i]
                }, true);
            }
        }
    }

    newPeoplePicker.OnControlResolvedUserChanged = function () {
        if (this.TotalUserCount > 0) {
            var fieldVal = '';
            for(var i=0;i<this.GetAllUserInfo().length;i++) {
                var resolvedUser = this.GetAllUserInfo()[i];
                fieldVal = fieldVal + resolvedUser.DisplayText + ";";
            }
            $('input#' + (this.TopLevelElementId.split("_PeoplePicker_TopSpan")[0])).attr('value', fieldVal);
            
            // 标记页面为脏状态(适配MSPO新建页面逻辑)
            if ($('input#' + (this.TopLevelElementId.split("_PeoplePicker_TopSpan")[0])).attr('origvalue') !== $('input#' + (this.TopLevelElementId.split("_PeoplePicker_TopSpan")[0])).attr('value')) {
                innerWindow.WPDPParts?.[0]?.IsDirty = true;
            }
        } else {
            $('input#' + (this.TopLevelElementId.split("_PeoplePicker_TopSpan")[0])).attr('value', '');
        }
    }
}

修改说明

  • 监听iframe的load事件,确保iframe内部DOM和基础脚本完全就绪后再执行操作
  • 所有脚本注入、API调用都使用iframe的window和document上下文,避免跨上下文访问问题
  • 直接调用iframe全局对象中的SPClientPeoplePicker_InitStandaloneControlWrapper方法初始化组件
  • 从iframe的SPClientPeoplePicker.SPClientPeoplePickerDict中获取正确的PeoplePicker实例

内容的提问来源于stack exchange,提问作者Provira

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 18:54:53