Командный пользовательский интерфейс
Всплывающие элементы и меню
Возвращаясь к дискуссии о том, где размещать командные элементы управления, напомним, что всплывающий элемент управления WinJS.UI.Flyout – используется для целей подтверждения действий, сбора информации и получения ответов на вопросы при реакции на действия пользователя. Меню – элемент управления WinJS.UI.Menu – это, в свою очередь, особый вид всплывающего элемента, который содержит элементы управления WinJS.UI.MenuCommand вместо произвольного HTML-кода. На самом деле, WinJS.UI.Menu является, благодаря использованию WinJS.Class.define, прямым наследником WinJS.UI.Flyout , поэтому у них много общего. Что касается всплывающих элементов, они так же имеют общие черты с панелью приложения. (Классы панели приложения и всплывающего элемента являются наследниками базового класса WinJS.UI._Overlay , который является внутренним классом WinJS).
Совет. В дополнение к объекту WinJS.UI.Flyout, который вы можете использовать из приложения, существует и системный всплывающий элемент, который отображается в ответ на некоторые вызовы API, такие, как создание или удаление дополнительных плиток (смотрите Главу 2 курса "Программная логика приложений для Windows 8, созданных с использованием HTML, CSS и JavaScript и их взаимодействие с системой"). Хотя выглядят эти элементы одинаково, системный всплывающий элемент вызывает для приложения событие blur , в то время, как всплывающий элемент WinJS является частью приложения и не делает этого. В результате, показ системного всплывающего элемента приводит к скрытию панели приложения, которая не находится в режиме залипания. Для того, чтобы это предотвратить, необходимо устанавливать свойство панели приложения sticky в значение true перед вызовом API, использующими системные всплывающие элементы. Это показано в Сценарии 7 примера "Дополнительные плитки" (http://code.msdn.microsoft.com/windowsapps/Secondary-Tiles-Sample-edf2a178).
Прежде чем мы рассмотрим подробности, взглянем на некоторые изображения из примера "Всплывающий элемент управления HTML" (http://code.msdn.microsoft.com/windowsapps/Flyout-sample-258757b3), где мы уже видели меню, которое всплывает по команде элемента управления панели приложения. Элементы управления WinJS.UI.Flyout, использованные в сценариях 1-4 показаны на рис. 1.1. Обратите внимание на использование разного содержимого во всплывающих элементах и на то, что всплывающий элемент всегда расположен около элемента управления, который вызвал его, например, у кнопок Buy, Login, Format output text и около текста гиперссылки Lorem ipsum. Эти примеры показывают, что всплывающий элемент может содержать простое сообщение с кнопкой (Сцераний 1, для предупреждений и подтверждений), может содержать поля для ввода информации или изменения параметров (Сценарии 2 и 3), и может иметь заголовок (Сценарий 4). Сценарий 5, в свою очередь, содержит пример всплывающего меню заголовка WinJS.UI.Menu, которое мы увидим немного позже.
Существуют две ключевые характеристики всплывающего элемента управления, включая меню. Первая заключается в том, что всплывающий элемент может быть скрыт программно, как панель приложения, когда активирован соответствующий элемент управления внутри него. Подобное поведение характерно для кнопки Complete order в Сценарии 1, для кнопки Login в Сценарии 2.
Вторая характеристика, так же актуальная для панели приложения, это закрытие неактивных всплывающих окон (light dismiss): щелчок мышью или прикосновение к области вне элемента управления скрывает его, как при нажатии клавиши Escape, что означает, что такое закрытие аналогично нажатию на кнопку Cancel (Отмена) или на кнопку закрытия в традиционном диалоговом окне. Преимущество такого подхода заключается в том, что нам не нужны видимые кнопки для этой цели, что помогает упрощению пользовательского интерфейса. В то же время, обратите внимание на то, что в Сценарии 3 рис. 1.1 нет кнопки OK или другого элемента управления, подтверждающего изменения, которые вы могли внести во всплывающем элементе. При рассматриваемой модели взаимодействия, изменения немедленно вступают в силу, таким образом ,закрытие всплывающего элемента не возвращает их к исходному состоянию и не отменяет. Если вас такое поведение не устраивает, вы можете разместить что-то вроде кнопки "Применить изменения" во всплывающем элементе и не вносить изменения до тех пор, пока кнопка не будет нажата. В таком случае, закрытие всплывающего элемента отменит изменения.
Я снова предлагаю вам почитать "Руководство и контрольный список для всплывающих элементов" (http://msdn.microsoft.com/library/windows/apps/hh465341.aspx), который в подробностях рассматривает разные варианты дизайна и размещения, которые возможны для этого элемента управления. В нем так же говорится о том, где не следует использовать этот элемент управления: например, для вывода сведений об ошибках, не связанных с действиями пользователя (вместо этого используйте окна сообщений), для основных команд (используйте панель приложения), для контекстных меню, связанных с выделением текста, и для элементов пользовательского интерфейса, которые являются частью рабочего процесса и которые следует размещать на полотне приложения. Описываемые принципы так же предполагают использование всплывающих элементов небольших размеров, целенаправленное их использование (без лишних элементов управления), и их расположение около объекта, который их вызывает. Посмотрим теперь, как все это работает в коде.
Примечание. В дополнение к приложениям, которые могут отображать собственные элементы WinJS.UI.Flyout, некоторые системные API (например, при создании дополнительных плиток) создают системные всплывающие элементы. В подобных случаях приложение получает событие blur, что ведет к закрытию панелей приложения. Для предотвращения подобного поведения, переведите панель приложения в режим залипания (sticky) при вызове этих API.
Свойства, методы и события WinJS.UI.Flyout
Большинство свойств, методов и событий элемента управления WinJS.UI.Flyout – это те, что мы уже рассматривали для панели приложения. Методы show и hide управляют его видимостью, свойство hidden показывает состояние видимости, в соответствующие моменты вызываются события beforeshow, aftershow, beforehide , и afterhide . Событие afterhide обычно используют для определения момента закрытия элемента.
Как и панель приложения, всплывающий элемент имеет свойство placement, но оно имеет другие значения, которые имеют смысл лишь в контексте свойств всплывающего элемента alignment и anchor . На самом деле, все три свойства – это необязательные параметры для метода show, так как они определяют позицию, в которой всплывающий элемент отобразится на экране. Значения placement и alignment могут быть установлены на сам элемент управления, так как они не обязательны при вызове show . (Заметим, что если вы не установите anchor в методе show , это свойство уже должно быть установлено на элемент управления, иначе show выдаст исключение.)
Свойство anchor идентифицирует элемент управления, который активирует всплывающий элемент, или любую другую операцию, которая может открыть всплывающий элемент (как в случае с подтверждением некоторого действия). Свойство placement, указывает, как всплывающий элемент должен располагаться по отношению к положению, заданному свойством anchor: 'top', 'bottom', 'left', 'right' , или 'auto' (по умолчанию). Обычно placement задают только тогда, когда всплывающий элемент может перекрыть важное содержимое. В противном случае вы рискуете тем, что всплывающий элемент будет уменьшен для того, чтобы занять доступное ему место. Содержимое всплывающего элемента при этом останется того же размера, что означает, - вот незадача! – что появятся полосы прокрутки! Таким образом, если только у вас нет достойной причины и справки от врача, используйте тип размещения 'auto' , так всплывающий элемент будет размещен там, где он может быть показан в полном размере. В том же духе, помните, что в прикрепленном режиме просмотра у вас есть лишь 320 пикселей по горизонтали, что означает, что всплывающий элемент, который вы показываете в данном режиме просмотра следует делать такого или меньшего размера.
Свойство alignment, в свою очередь, когда используется со свойством placement , установленным в 'top' или 'bottom' , определяет, как всплывающий элемент выравнивается с anchor: 'left', 'right' , или 'center' (по умолчанию). Само содержимое всплывающего элемента выравнивается посредством CSS как и любые HTML-элементы.
Если вам нужно стилизовать сам всплывающий элемент управления, вы можете задать стили в классе win-flyout , наподобшие шрифтов, выравнивания по умолчанию, полей и так далее. Что касается других классов стилей WinJS, родственных этому, используйте win-flyout как базу для более конкретных селекторов, если только вы не хотите стилизовать каждый всплывающий элемент в приложении. Обычно, на самом деле, вы так же исключаете win-menu из правила, таким образом, на всплывающие элементы меню такая стилизация не действует. Например, большинство сценариев в примере, который посвящен всплывающим элементам управления HTML, которые мы рассмотрим в дальнейшем, имеют правила наподобие такого:
.win-flyout:not(.win-menu) button, .win-flyout:not(.win-menu) input[type="button"] { margin-top: 16px; margin-left: 20px; float: right;
И, наконец, если по какой-либо причине вам нужно знать, когда загружается всплывающий элемент, прослушивайте DOMNodeInserted в document.body:
document.body.addEventListener("DOMNodeInserted", insertionHandler, false);
Примеры всплывающих элементов
Всплывающий элемент управления создается так же, как любой другой элемент управления WinJS, с помощью атрибутов data-win-control и data-win-options, и обрабатывается WinJS.UI.process/processAll. Всплывающие элементы с относительно постоянным содержимым элементов обычно объявляют в разметке, где вы можете использовать привязку данных для некоторых свойств элементов во всплывающем элементе. Всплывающие элементы с динамическим содержимым, с другой стороны, могут быть созданы прямо из кода с использованием команды вида new WinJS.UI.Flyout(<element>, <options>) , и вы можете, безусловно, менять его дочерние элементы в любое время. Все это – лишь часть DOM! (Не повторяю ли я собственные слова?)
Как я говорил раньше (видимо, я повторяюсь) элемент управления WinJS.UI.Flyout может содержать произвольный HTML, стилизованный, как всегда, с помощью CSS. Всплывающий элемент для Сценария 1 в примере выглядит следующим образом в html/confirm-action.html (слегка сокращенный вид):
<div id="confirmFlyout" data-win-control="WinJS.UI.Flyout" aria-label="{Confirm purchase flyout}"> <div>Your account will be charged $252. </div> <button id="confirmButton">Complete Order</button> </div>
Всплывающий элемент для входа в систему из Сценария 2 похож, и он даже использует HTML-форму для прикрепления к кнопке Login события нажатия на кнопку Enter на клавиатуре:
<div id="loginFlyout" data-win-control="WinJS.UI.Flyout" aria-label="{Login flyout}" > <form onsubmit="return false;" > <p > <label for="username" gt;Username <br / ></label > <span id="usernameError" class="error" > </span > <input type="text" id="username" / > </p > <p > <label for="password">Password<br / ></label > <span id="passwordError" class="error" ></span > <input type="password" id="password" / > </p > <button id="submitLoginButton" >Login</button > </form > </div >
Всплывающий элемент отображается путем вызова его метода show . В Сценарии 1, например, событие кнопки click прикреплено к функции showConfirmFlyout (js/confirm-action.js), где кнопка Buy задается как элемент прикрепления. Обработка нажатия на кнопку Complete Order так же производится посредством обработчика события click, прикрепленного к этому элементу, и здесь мы вызовем метод hide для программного закрытия всплывающего элемента. Наконец, событие afterhide используется для выявления факта закрытия элемента:
var bought; var page = WinJS.UI.Pages.define("/html/confirm-action.html", { ready: function (element, options) { document.getElementById("buyButton").addEventListener("click", showConfirmFlyout, false); document.getElementById("confirmButton").addEventListener("click", confirmOrder, false); document.getElementById("confirmFlyout").addEventListener("afterhide", onDismiss, false); } function showConfirmFlyout() { bought = false; var buyButton = document.getElementById("buyButton"); document.getElementById("confirmFlyout").winControl.show(buyButton); // Когда кнопка Buy нажата, скрыть всплывающий элемент, так как пользователь завершил работу с ним. function confirmOrder() { bought = true; document.getElementById("confirmFlyout").winControl.hide(); } // При закрытии элемента, определяет, был ли он закрыт потому, что пользователь нажал // Кнопку Byu. Если нет, элемент был закрыт автоматически. function onDismiss() { if (!bought) { // (В примере сообщение о закрытии отображается на полотне) }
Работа с элементами управления для входа в систему в Сценарии 2, в основном – это то же самое, с некоторыми дополнениями в виде кода, который позволяет проверить, были ли заполнены поля для ввода имени пользователя и пароля. Если это не так, обработчик нажатия кнопки Login показывает встроенное в элемент сообщение об ошибке и устанавливает фокус ввода на соответствующее поле:
Так как всплывающий элемент в Сценарии 2 немного больше, значение по умолчанию ‘auto’ для свойства placement (как в имитаторе) приводит к появлению элемента ниже кнопки, которая его вызывает. Выше этой кнопки не так много места. Поэтому попытаемся установить свойство placement в значение ‘top’ в вызове show:
function showLoginFlyout() { // ... document.getElementById("loginFlyout").winControl.show(loginButton, "top"); }
После этого вы можете увидеть, как во всплывающем элементе появляются полосы прокрутки, так как его размер слишком мал:
Каким словом я раньше это называл? "Незадача"?
Двигаемся дальше, к Сценарию 3, в котором всплывающий элемент определен в разметке, где он содержит элементы управления label, select, input. В JavaSctipt, однако, он прослушивает события изменения этих элеменов и применяет полученные значения к элементам вывода данных на полотне приложения:
var page = WinJS.UI.Pages.define("/html/change-settings.html", { ready: function (element, options) { // ... document.getElementById("textColor").addEventListener("change", changeColor, false); document.getElementById("textSize").addEventListener("change", changeSize, false); } }); // Изменение цвета текста function changeColor() { document.getElementById("outputText").style.color = document.getElementById("textColor").value; // Изменение размера текста function changeSize() { document.getElementById("outputText").style.fontSize = document.getElementById("textSize").value + "pt";
Если бы у этого всплывающего элемента была бы кнопка Применить (Apply) вместо его немедленной реакции на изменения, ее обработчик click получал бы текущее выделение и значение из ползунка и использовал бы их для того, чтобы выполнить действия, аналогичные тем, что производятся в функциях changeColor и changeSize.
И, наконец, в Сценарии 4 мы видим всплывающий элемент с заголовком, который является просто элементом в разметке, выводящим крупный текст. Сам по себе всплывающий элемент не имеет выделенного описания для заголовков:
<div id="moreInfoFlyout" data-win-control="WinJS.UI.Flyout" aria-label="{More info flyout}"> <div class="win-type-x-large">Lorem Ipsum</div> <div> Lorem Ipsum is text used as a placeholder by designers... </div> </div>
Смысл этого последнего примера заключается в том, чтобы показать, что в отличие от традиционных диалоговых окон настольных приложения, всплывающие элементы не часто нуждаются в заголовках, так как у них уже есть контекст внутри приложения. Диалоговые окна в настольных приложениях нуждаются в заголовках, так как они могут относиться к разным приложениям.
Меню и команды меню
Элемент управления WinJS.UI.Menu отличает от более общего элемента WinJS.UI.Flyout то, что меню ожидает, что все его дочерние элементы будут объектами типа WinJS.UI.MenuCommand , так же, как стандартный макет панели приложения ожидает объекты AppBarCommand (и его экземпляр не будет создан, если вы объявите у него какие-нибудь другие дочерние элементы). На самом деле, у меню есть общие характеристики и с панелью приложения, и со всплывающим элементом:
- Методы show и hide .
- Методы getCommandById, showCommands, hideCommands , и showOnlyCommands , вместе со свойством commands , что означает, что вы можете использовать те же подходы для управления командами меню, которые обсуждались в подразделе "Отображение, скрытие, включение и обновление команд" в разделе, посвященном панели приложения, в том числе – задание команд меню используя JSON-массив вместо описания отдельных элементов.
- События beforeshow, aftershow, beforehide , и afterhide .
- Свойства anchor, alignment , и placement .
Меню поддерживает два стиля, влияющих на его отображение – win-menu и win-command – который можно использовать для создания более конкретных селекторов, как мы видели, для всего меню или для отдельных текстовых команд.
Объекты MenuCommand так же очень похожи на объекты AppBarCommand. У них много одинаковых свойств: id, label, type ('button', 'toggle', 'flyout' , и 'separator' ), disabled, extraClass, flyout, hidden, onclick , и selected . У команд меню нет значков, разделов и всплывающих подсказок, но из type вы можете видеть, что элементы меню могут быть кнопками (включая полностью текстовые элементы), элементами с возможностью установки флагов, разделителями и, кроме того, другими всплывающими элементами. В последнем случае, вторичное меню заменит первое вместо того, чтобы отображаться рядом с ним, а чтобы быть полностью честным, я должен все же видеть вторичное меню, используемое в реальном приложении. Тем не менее, такая возможность поддерживается.
Мы уже видели, как использовать всплывающие меню с помощью команд панели приложения, что показано в Сценарии 6 примера, посвященного всплывающему элементу управления HTML (посмотрите раздел "Командные меню" выше). Другая типичная сфера использования – реализация того, что выглядит как выпадающее меню заголовочного элемента, что показано в Сценарии 5. Здесь (html/header-menu.html), показан стандартный дизайн помещения символа перевернутой угловой скобки () в конце заголовка:
<header aria-label="Header content" role="banner"> <button class="win-backbutton" aria-label="Back"></button> <div class="titlearea win-type-ellipsis"> <button class="titlecontainer"> <h1> <span class="pagetitle">Music</span> <span class="chevron win-type-x-large" > & #xe099 </span> </h1> </button> </div> </header>
Обратите внимание на то, что весь заголовок помещен в элемент управления button (кнопка), ее обработчик click может отображать меню с помощью метода show:
document.querySelector(".titlearea").addEventListener("click", showHeaderMenu, false); function showHeaderMenu() { var title = document.querySelector("header .titlearea"); var menu = document.getElementById("headerMenu").winControl; menu.anchor = title; menu.placement = "bottom"; menu.alignment = "left"; menu.show(); }
Всплывающий элемент (определенный как headerMenu в html/header-menu.html) появляется, когда вы щелкаете в любом месте заголовка (а не только на угловой скобке, которая является обычным символом в тексте заголовка):
Отдельные команды меню – это простые элементы button, поэтому вы можете присоединить к ним обработчики click если вам это нужно. Как и в случае с панелью приложения, лучше всего использовать метод элемента управления меню getCommandById для обнаружения этих элементов, так как это гораздо эффективнее, чем document.getElementById (что, к сожалению, используется в примере из SDK).
Для того чтобы увидеть в действии вторичное меню, попытайтесь добавить следующий элемент secondaryMenu в html/header-menu.thml перед элементом headerMenu и добавить элемент button в headerMenu, свойство flyout которого ссылается на secondaryMenu:
<div id="secondaryMenu" data-win-control="WinJS.UI.Menu"> <button data-win-control="WinJS.UI.MenuCommand" data-win-options="{id:'command1', label:'Command 1'}"></button> <button data-win-control="WinJS.UI.MenuCommand" data-win-options="{id:'command2', label:'Command 2'}"></button> <button data-win-control="WinJS.UI.MenuCommand" data-win-options="{id:'command3', label:'Command 3'}"></button> </div> <div id="headerMenu" data-win-control="WinJS.UI.Menu"> <!-- ... --> <button data-win-control="WinJS.UI.MenuCommand" data-win-options="{id:'showFlyout', label:'Show secondary menu', type:'flyout', flyout:'secondaryMenu'}"> </button> </div>
Кроме того, перейдите в css/header-menu.css и установите стиль width элемента #headerMeny в значение 200px. С этими изменениями первое меню будет выглядеть так, как показано ниже, изменение цвета заголовка – результат действия эффекта зависания над ним указателя мыши:
Когда вы выберете пункт Show secondary meny (Показать вторичное меню), первое меню будет закрыто и откроется меню второго уровня:
Другой пример использования всплывающих элементов в заголовке можно найти в примере "Адаптивный макет с использованием CSS" (http://code.msdn.microsoft.com/windowsapps/Adaptive-layout-with-sample-062e7fe2), который мы видели в лекции 6 курса "Введение в разработку приложений для Windows 8 с использованием HTML, CSS и JavaScript". Он реализован так же, как показано выше, с добавлением механизмов, которые изменяют содержимое страницы в ответ на выделение.
Контекстные меню
Помимо всплывающих меню, которые мы уже видели, существуют и контекстные меню, описанные в материале "Руководство и контрольный список для контекстных меню" (http://msdn.microsoft.com/library/windows/apps/hh465308.aspx). Они используются для команд, которые напрямую связаны с выделением разного рода, таким, как команды буфера обмена для текста, они вызываются щелчком правой кнопки мыши по элементу, прикосновением или клавишей вызова контекстного меню на клавиатуре. Текстовые элементы управления и гиперссылки обеспечивают данную возможность по умолчанию. Контекстные меню так же хорошо подходят для предоставления команд для объектов, которые не могут быть выделены (таких, как части беседы в программе мгновенного обмена сообщениями), команды панели приложения не могут быть контекстно чувствительными к подобным элементам. Они так же рекомендованы для совершения действий, которые нельзя выполнить путем непосредственного взаимодействия с объектом. Однако, не используйте их для фона страницы – именно для этого существует панель приложения, она будет появляться автоматически при щелчке правой кнопкой мыши или соответствующем жесте.
Совет. Если вы обрабатываете событие нажатий правой кнопки мыши на элемент, убедитесь в том, что для этого элемента отключено стандартное поведение, которое подразумевает отображение панели приложения. Таким образом, используйте событие щелчка правой кнопки мыши разумно, так как пользователи привыкли пользоваться правой кнопкой для вызова панели приложения. Обратите так же внимание на то, что вы можете программно открыть панель приложения, используя ее метод show.
Пример "Контекстное меню" (http://code.msdn.microsoft.com/windowsapps/Context-menu-sample-40840351) предоставляет нам некоторый контекст – я знаю, что это неудачная игра слов! В любом случае, вам нужно лишь прослушивать событие HTML contextmenu для соответствующего элемента. Вам не нужно заботиться особым образом об обработке касаний или о событиях клавиатуры. Сценарий 1 примера, например, имеет невыделяемый элемент attachment, для которого прослушивается вышеупомянутое событие (html/scenario1.html):
document.getElementById("attachment").addEventListener("contextmenu", attachmentHandler, false);
В обработчике события, вы создаете объект Windows.UI.Popups.PopupMenu (http://msdn.microsoft.com/library/windows/apps/windows.ui.popups.popupmenu.aspx) (это объект из WinRT, не из WinJS!), заполняет его объектами Windows.UI.Popups.UICommand (http://msdn.microsoft.com/library/windows/apps/windows.ui.popups.uicommand.aspx) (они содержат подпись элемента и обработчик события) или объектами UICommandSeparator (http://msdn.microsoft.com/library/windows/apps/windows.ui.popups.uicommandseparator.aspx), и затем вызывает метод меню showAsync (js/scenario1.js):
function attachmentHandler(e) { var menu = new Windows.UI.Popups.PopupMenu(); menu.commands.append(new Windows.UI.Popups.UICommand("Open with", onOpenWith)); menu.commands.append(new Windows.UI.Popups.UICommand("Save attachment", onSaveAttachment)); menu.showAsync({ x: e.clientX, y: e.clientY }).done(function (invokedCommand) { if (invokedCommand === null) { // Команда - это null если ни одна команда не была активирована. } });
Обратите внимание на то, что результат метода 2Пример, на самом деле, вызывает здесь не done, а then. Если вам интересно, почему существует подобная последовательность, это потому, что метод done был представлен не в начале разработки Windows 8, а тогда, когда стало ясно, что нам нужен более совершенный механизм для обработки ошибок в promise-вызовах, объединенных в цепочку. В результате, множество SDK-примеров и кода в документации все еще используют then вместо done, когда обрабатывают последний promise-вызов в цепочке. Такой подход все еще работает, это лишь приводит к тому, что сведения об ошибках, возникающих в цепочке, теряются, что скрывает возможные ошибки showAsync – это активация объекта UICommand. Вы можете проверить его свойство id для того, чтобы предпринять дальшейшие действия. Кроме того, параметр, который передают в showAsync – это объект Windows.Foundation.Point (http://msdn.microsoft.com/library/windows/apps/windows.foundation.point.aspx), который показывает, где следует появиться меню по отношению к указателю мыши или точке касания. Меню размещается выше данной точки и выровнено по центру.
Объект PopupMenu так же поддерживает метод, который называется showForSelectionAsync, первым аргументом которого является объект Windows.Foundation.Rect (http://msdn.microsoft.com/library/windows/apps/windows.foundation.rect.aspx), который описывает область выделения. Опять же, меню размещается выше прямоугольника выделения с выравниванием по центру. Это показано в Сценарии 2 примера в js/scenario2.js:
//В обработчике contextmenu menu.showForSelectionAsync(getSelectionRect()).then(function (invokedCommand) { // ... function getSelectionRect() { var selectionRect = document.selection.createRange().getBoundingClientRect(); var rect = { x: getClientCoordinates(selectionRect.left), y: getClientCoordinates(selectionRect.top), width: getClientCoordinates(selectionRect.width), height: getClientCoordinates(selectionRect.height) }; return rect; };
Сценарий так же показывает, что вы можете использовать обработчик события contextmenu с текстом для переопределения команд по умолчанию, которые предоставляют соответствующие элементы управления.
Последнее замечание, касающееся контекстных меню: так как они создаются с помощью API WinRT, а не с помощью элементов управления WinJS, меню не существуют в DOM, они не известны DOM, что объясняет использование других конструкций WinRT – как point (Точка) и Rect (Прямоугольник). Подобное утверждение так же справедливо для окон сообщений, которые станут последней темой этой лекции.