使用标注控件突出显示内容并改进 SharePoint 托管的 SharePoint 加载项的功能

SharePoint 标注控件可提供灵活的方式来吸引用户,并展示 SharePoint 托管的加载项的功能。 可以使用多种方法进行配置,以符合加载项的 UI。 可以构造此控件、将其添加到页面和自定义其外观和行为。

在 SharePoint 网站中搜索时,会看到运行中的标注控件示例,因为每次将鼠标悬停在搜索结果上时,就会显示标注控件。

下图显示了单个搜索结果的标注,还显示了内容控件中的几个典型部分:标题、关于页面上项目的一些信息以及可以对项目执行的操作(“打开”和“发送”)。

在本例中,信息和操作相对简单,但你已看到使用它的两个优点。 首先,使用它可以显示关于页面上元素的其他信息(如果需要);其次,使用它可以轻松地向页面添加功能。

SharePoint 搜索结果页面上标注控件的示例

SharePoint 搜索结果页面上标注控件的示例

通过加入 callout.js 文件使控件对 HTML 页面可用

本示例使用 SP.SOD.executeFunc 方法确保脚本文件在你运行依赖于它的任何代码之前进行加载。

SP.SOD.executeFunc("callout.js", "Callout", function () {
    });

传递到 SP.SOD.executeFunc 函数的函数包含你要在 callout.js 文件加载后运行的代码。 加载这些文件后,可以使用 CalloutManager 对象为每个需要关联标注控件的页面元素创建 Callout 对象。

CalloutManager 是一个单一实例,它会在关联阵列中的页面上存储对每个 Callout 对象的引用。

Callout 对象只有两个必需的成员:IDlaunchPointID 成员是映射到 CalloutManager 中的 Callout 对象的关键字:CalloutManager["value of the callout's ID member"]launchPoint 成员是 HTML 页面元素。

例如,可以创建或获取页面上的 div 元素,并将其作为 Callout 对象的成员进行传递。 默认情况下,每当用户选择 launchPoint 元素时,都会显示标注控件。

本示例演示如何仅使用两个必需的成员和一个标题字符串,创建尽可能简单的标注控件。

var calloutPageElement = document.createElement("div");
var callout = CalloutManager.createNew({
   ID: "unique identifier",
   launchPoint: calloutPageElement,
   title: "callout title"
});

每当用户选择页面元素时,此特定标注都会在控件顶部显示标题。 使用可选成员,以某些非常强有力的方式自定义控件的外观、行为、定位和操作。 标注控件还有一种设置方法,在创建控件的实例后,可以使用此方法设置任意参数的值。

callout.set({openOptions:{event: "hover"}});

也可以为 CalloutOptions 对象中的所有标注成员设置值,然后将该对象传递给 createNew 方法。

var calloutPageElement = document.createElement("div");
var calloutOptions = new CalloutOptions();
calloutOptions.ID = unique identifier;
calloutOptions.launchPoint = calloutPageElement;
calloutOptions.title = callout title;
var callout = CalloutManager.createNew(calloutOptions);

自定义标注控件的外观

可以使用以下成员来控制标注的显示。

成员 用途 有效值(默认以粗体显示)
title 在控件顶部显示标题。 字符串, null ,包含 HTML 的字符串
content 每当成员没有值 contentElement 时,在控件内显示 HTML。 包含 HTML 的字符串, null ,如果 contentElement 具有值则必须为空。
contentElement 当成员没有值 content 时,在控件内显示 HTML 元素。 任何 HTML 元素,null,如果 content 具有值,则必须为 null。
contentWidth 指定标注正文容器的宽度(像素)。

容器每侧还有 1 像素的边框和 15 像素的边距,因此,控件比你指定的正文宽度宽 32 像素。

控件的 CSS overflow 属性设置为 hidden,因此,如果内容不适合指定的宽度,则会对其进行剪裁。

如果在打开的标注中设置此成员,更改会立即生效。

其他成员并非如此。
240 和 610 之间的任意数字,350(默认情况下,控件宽度设为 382 像素)
beakOrientation 指定标注控件的尖角或指针方向。 上下方向

标注控件的嘴以顶部机器人方向显示的位置

左右方向

标注控件的嘴以左方向显示的位置

自定义标注控件的行为

可以使用以下成员控制标注的行为。 从重要的 openOptions 成员开始,因为当用户在页面上与控件交互时,可使用它指定控件的打开和关闭方式。

openOptions 成员使用这些值 用途
{event: "click", closeCalloutOnBlur: true} 当用户用鼠标选择 launchPoint 元素时,显示标注控件,当用户将鼠标从 launchPoint 元素移开时,关闭标注控件。

由于 event 的值为 click,默认情况下,showCloseButton 选项的值为 true,且无法更改。

这是默认的值组合。
{event: "hover", showCloseButton: true} 当用户将鼠标悬停在 launchPoint 元素上时,显示标注控件;当用户选择控件右上角的“X”按钮时,关闭标注控件。

由于 event 的值为 hovercloseCalloutOnBlur 的值不适用且无法设置。
{event: "click", closeCalloutOnBlur: false} 当用户将鼠标悬停在 launchPoint 元素上时,显示标注控件;只有在用户选择控件右上角的“X”按钮时,才关闭标注控件。

由于 event 的值为 click,默认情况下,showClosebutton 选项的值为 true,且无法更改。

以下是可以进行设置以控制标注的行为的其他成员。

使用此成员 用途 有效值(默认以粗体显示)
onOpeningCallback 执行标注控件在页面上呈现之前必须发生的操作。

Callout由于 对象必须作为参数传递给你提供的函数,因此可以使用此成员在呈现控件之前设置控件的任何属性的值。

还可以使用此成员开始异步操作,添加或更改控件的内容。

只能为此成员设置一次值。
function(callout /*=Callout*/) {...}

null
onOpenedCallback 执行标注控件在页面上呈现并完全动画后必须发生的操作。

可以使用此成员操作控件的文档对象模型 (DOM)。

只能为此成员设置一次值。
function(callout /*=Callout*/) {...}

null
onClosingCallback 执行在标注控件正在关闭但还未从页面中完全删除之前必须发生的操作。

只能为此成员设置一次值。
function(callout /*=Callout*/) {...}

null
onClosedCallback 执行在标注控件已经关闭并从页面中完全删除之后必须发生的操作。

只能为此成员设置一次值。
function(callout /*=Callout*/) {...}

null

使用标注控件方法

可以使用这些方法来自定义标注控件的行为。

使用此方法 用途 有效参数值
set({member:value}) 构建了控件的实例后设置成员值。 一个名称/值对,用于为任何标注控件成员定义值。

var callout = new Callout({openOptions:{event: "click"}});callout.set({openOptions:{event: "hover"}});
getOrientation() 返回一个 CalloutOrientation 对象,该对象指示标注控件的指向方式。

此对象具有四个布尔成员: updownleftright

控件打开时,其中两个值将为 true ,另外两个为 false(例如,upright)。
无参数
addEventCallback(字符串 eventName,CalloutCallback 回调 注册一个回调函数,每当标注控件更改为 参数指定的状态时,将调用该 eventName 回调函数。 参数 eventName 必须是以下值之一: openingopenclosingclosed

参数 callback 必须是采用标注控件实例作为其第一个参数的函数。
open() 显示控件。

如果该控件已打开或正在打开,此方法返回 false 且不执行任何操作。
无参数
close(bool useAnimation) 隐藏控件。

如果该控件已关闭或正在关闭,此方法返回 false 且不执行任何操作。
一个布尔值,指定控件是否随动画关闭。

动画默认关闭。
toggle() 切换控件的打开/关闭状态。 无参数
addAction(CallOutAction calloutAction) 向标注控件的对象数组CalloutAction添加一个新的 CalloutAction

这些对象会定义要在控件的页脚中显示的操作。

向标注控件添加操作部分介绍了如何构造这些对象。

只有在创建了控件的实例后,才能添加操作。

控件的操作不能超过三个,如果尝试添加更多操作,会发生异常。
CalloutAction 对象。
refreshActions() 重新加载已添加到控件的所有操作。

控件打开时,可以使用此方法更改、启用或禁用操作。
无参数

向标注控件添加操作

创建标注控件的实例后添加操作。 标注操作可以由单一操作或操作菜单组成。 可以向标注控件添加最多三个操作。 创建标注操作后,使用它的 addAction 方法将其添加到 CalloutControl 对象中。 用户选择文本后,此示例操作会在浏览器中打开新窗口。

//Create CalloutAction
var calloutAction = new CalloutAction({
            text: "Open window"
            onClickCallback: function() {                
                window.open(url);
            }
        });

//Add Action to an instance of the CalloutControl        
        myCalloutControl.addAction(calloutAction);

也可以为 CalloutActionOptions 对象中的所有 CalloutAction 成员设置值,并将该对象传递给 CalloutAction 构造函数。

//Create CalloutAction
var calloutActionOptions = new CalloutActionOptions();
calloutActionOptions.text = "Open window";
actionOptions.onClickCallback = function() {
    window.open(url);
};
var calloutAction = new CalloutAction(calloutActionOptions);

//Add Action to an instance of the CalloutControl        
        myCalloutControl.addAction(calloutAction);

可以使用以下成员来定义标注操作的行为。

使用此成员 用途 有效值(默认以粗体显示)
text (required) 为操作显示文本标签。 字符串,null
onClickCallback 定义用户选择标注操作标签时执行的操作。 function(calloutAction /*=CalloutAction*/) {...}

null
isEnabledCallback 定义标注显示之前运行的回调函数,并确定是否启用操作。

如果此函数返回 true,标注会显示已启用的操作。

如果它返回 false,标注会显示操作文本,但禁用操作。
function(calloutAction /*=CalloutAction*/) {...}

null
isVisibleCallback 定义在标注显示前运行的回调函数,并确定是否显示操作文本。

如果此函数返回 true,标注会显示操作文本。

如果它返回 false,标注会隐藏操作文本。

启动操作向左移动,代替隐藏的操作。
function(calloutAction /*=CalloutAction*/) {...}

null
tooltip 在用户将鼠标悬停在标注操作文本上时显示文本。 字符串,null
disabledTooltip 在用户将鼠标悬停在标注操作文本上时显示文本,并且标注操作已被禁用(当 isEnabledCallback函数返回 false 时)。 字符串,null
menuEntries 定义操作菜单,而不是单一操作。 [ CalloutActionMenuEntry, ...]

null

下一节介绍如何创建 CalloutActionMenuEntry 并将它添加到 CalloutAction 对象。

向标注控件添加操作菜单

当一个标注操作包含一个菜单而不是单个操作时,用户可以看到标注操作文本旁边有一个下拉箭头,如下图所示。

用户选择操作标签旁的箭头时,标注操作将显示菜单

用户单击操作标签旁的箭头时,标注操作将显示菜单。

可以创建任意多个菜单项,并通过将它们作为 CalloutAction 对象的 menuEntries 成员的值传递到数组中,将其添加到标注操作。

//Create two menu entries.
var menuEntry1 = new CalloutActionMenuEntry("Entry One", calloutActionCallbackFunction, "/_layouts/images/DOC16.GIF");
var menuEntry2 = new CalloutActionMenuEntry("Some Other Entry", calloutActionCallbackFunction, "/_layouts/images/XLS16.GIF");

//Add the menu entries to the callout action.
var calloutAction = new CalloutAction({
   text: "MENU W/ ICONS",
   menuEntries: [menuEntry1, menuEntry2]
})

//Add the callout action to the callout control.
callout.addAction(calloutAction);


CalloutActionMenuEntry 构造函数采用三个参数。 前两个是必需参数。 第三个是可选参数,但非常有用,因为使用它可以显示包含文本的图标。

  • 将字符串作为第一个参数传递,以显示每个菜单项的文本标签。

  • 传递一个函数作为第二个参数以定义当用户单击菜单项文本时发生的操作。

  • 将一个包含要显示的图标的 URL 的字符串传递到文本标签的左边。

使用 CalloutManager 来创建和管理标注控件的实例

CalloutManager 单一实例对象存储对页面上的每个 Callout 对象的引用。 它会在关联阵列中存储标注控件的每个实例,其中,每个控件的 ID 值是键。 CalloutManager 包含可帮助你创建和管理它存储的 Callout 对象的方法。

使用此方法 用途 有效参数值
createNew(members) 创建一个新的 Callout 对象。

执行此操作时,CalloutManager 在其关联数组中添加该控件的条目,并使用所需成员 ID 的值作为关键字。
将值分配给想要使用的每个成员的关联阵列。

IDlaunchPoint 成员是必需的。
createNewIfNecessary (members) Callout如果launchPoint作为参数传递的 尚未分配标注控件,则创建对象。 将值分配给想要使用的每个成员的关联阵列。

IDlaunchPoint 成员是必需的。
getFromLaunchPoint: function (/@type(HTMLElement)/launchPoint) 获取与函数中提供的 launchPoint 关联的 Callout 对象。

如果没有为 launchPoint 分配 Callout 对象,此对象会引发异常。
无参数
getFromLaunchPointIfExists: function (/@type(HTMLElement)/launchPoint) 获取与函数中提供的 launchPoint 关联的 Callout 对象。

如果没有为 launchPoint 分配 Callout 对象,此方法会返回 null。
无参数
getFromCalloutDescendant: function (/@type(HTMLElement)/descendant) 获取与函数给定元素中提供的 HTML 元素关联的 Callout 对象。

此元素可以是标注元素的任意后代。

例如,创建 Callout 对象时,可以传递分配的 contentElement 成员的值。

如果后代没有关联的 Callout 对象,此方法会引发异常。
无参数
closeAll() 关闭所有打开 Callout 的对象。

如果至少关闭一个标注,则此方法返回 true。
无参数
isAtLeastOneCalloutOpen() 检查是否还有 callout 是打开的。 无参数

定位页面上的标注控件

使用此成员 用途 有效值(默认以粗体显示)
boundingBox 指定将用作标注控件的 等效 offsetParent 项的 HTML 元素。

默认情况下,它的默认值是标注控件的 offsetParent,但可以使用此成员确保正确定位该控件。

标注控件会尝试定位自身,使其在此框中可见。 它会改变方向(从上到下或从左到右,具体取决于尖角方向)使其保持可见。
任意 HTML 元素,包含标注控件的 HTML 元素的 offsetParent
positionAlgorithm 替代标注控件的默认定位算法。 CalloutOptions.prototype.defaultPositionAlgorithm

function(calloutPositioningProxy) { ... }

下一节介绍如何使用 calloutPositioningProxy 对象编写标注控件的定位算法。

使用 calloutPositioningProxy 编写定位算法

calloutPositioningProxy 对象包含可用于替代标注控件默认使用的定位逻辑的方法和属性。 例如,如果要始终在 launchPoint 元素的下方和右侧显示控件,需要编写如下定位算法。

function alwaysGoDownAndRight(calloutPositioningProxy)  {
    calloutPositioningProxy.moveDownAndRight();
} 

然后,将该函数作为对象positionAlgorithm成员的值Callout传递。 在创建 或更高版本时 Callout,可以通过设置 值来执行此操作。

callout.set({positionAlgorithm: alwaysGoDownAndRight});

您始终可以通过启动浏览器的 JavaScript 控制台(如 Internet Explorer F12 开发人员工具)查看默认定位逻辑。

CalloutOptions.prototype.positionAlgorithm.toString()

可以在 对象中 CalloutPositioningProxy 使用这些方法来编写自己的定位逻辑。

方法 说明
isCalloutTooFarTop() 返回 Boolean 类型的值。
isCalloutTooFarRight() 返回 Boolean 类型的值。
isCalloutTooFarBottom() 返回 Boolean 类型的值。
isCalloutTooFarLeft() 返回 Boolean 类型的值。
isCalloutLeftOfHardBoundingBox() 返回 Boolean 类型的值。

如果为 true,控件的左侧会位于容器元素的外部。 它的状态为不可见,且用户无法滚动到该位置。
isCalloutRightOfHardBoundingBox() 返回 Boolean 类型的值。

如果为 true,控件的右侧会位于容器元素的外部。 它的状态为不可见,且用户无法滚动到该位置。
isCalloutAboveHardBoundingBox() 返回 Boolean 类型的值。

如果为 true,控件的顶部会位于容器元素的外部。 它的状态为不可见,且用户无法滚动到该位置。
isCalloutBelowHardBoundingBox() 返回 Boolean 类型的值。

如果为 true,控件的底部会位于容器元素的外部。 它的状态为不可见,且用户无法滚动到该位置。
isOrientedUp() 返回 Boolean 类型的值。
isOrientedDown() 返回 Boolean 类型的值。
isOrientedLeft() 返回 Boolean 类型的值。
isOrientedRight() 返回 Boolean 类型的值。
moveUpAndRight() 不返回任何值。

改变控件的方向。
moveUpAndLeft() 不返回任何值。

改变控件的方向。
moveDownAndRight() 不返回任何值。

改变控件的方向。
moveDownAndLeft() 不返回任何值。

改变控件的方向。
moveTowardsOppositeQuadrant() 不返回任何值。

改变控件的方向。
flipHorizontal() 不返回任何值。

改变控件的方向。
flipVertical() 不返回任何值。

改变控件的方向。
numberOfEdgesCollidingWithBoundingBox() 返回一个 0 到 4 之间的整数,代表标注与可见的边界框发生冲突的边缘数。

例如,如果在调用 moveUpAndRight() 方法后,控件的顶端被文档正文的顶端截断,则 numberOfEdgesCollidingWithBoundingBox() 方法返回一个大于 1 的数字。

这种定位算法使得控件位于文本的上方或下方。 isRTLCalloutPositioningProxy 属性指示文本是否显示从右到左的语言。 检查此属性以确保该控件相对于页面上文本的定位始终正确。

function examplePositionAlgorithm(calloutPositioningProxy) {
    if (!calloutPositioningProxy.isRTL) {
        calloutPositioningProxy.moveDownAndRight();
        if (calloutPositioningProxy.isCalloutTooFarBottom()) {
            calloutPositioningProxy.moveUpAndRight();
        }
    }
    else {
        calloutPositioningProxy.moveDownAndLeft();
        if (calloutPositioningProxy.isCalloutTooFarBottom()) {
            calloutPositioningProxy.moveUpAndLeft();
        }
    }
}
callout.set({positionAlgorithm: examplePositionAlgorithm});

这种定位算法将控件的默认方向更改为 downAndRight 而不是 upAndRight,但如果有任何冲突,它将使用默认算法。

function tryDownAndRightThenGoDefault(calloutPositioningProxy) {
    if (!calloutPositioningProxy.isRTL)
        calloutPositioningProxy.moveDownAndRight();
    else
        calloutPositioningProxy.moveDownAndLeft();
    
    if (calloutPositioningProxy.numberOfEdgesCollidingWithBoundingBox() > 0)
        return CalloutOptions.prototype.positionAlgorithm.apply(this, arguments);
};
callout.set({positionAlgorithm: tryDownAndRightThenGoDefault});

另请参阅