jQuery.append, тип ввода и приложение Магазина Windows (HTML/CSS/JS)

У меня есть это приложение Window Store, в котором я хотел бы динамически добавлять некоторую разметку, и моя проблема может быть сведена к следующему:

Работающий

$('.some-element').append('<input type="radio"><label>Test</label>');

Не работает

$('.some-element').append('<input type="radio" name="test"><label>Test</label>);

Visual Studio говорит мне, что:

Ошибка выполнения JavaScript: невозможно добавить динамическое содержимое. Сценарий попытался внедрить динамическое содержимое или элементы, ранее динамически измененные, что может быть небезопасно. Например, это исключение будет создано при использовании свойства innerHTML для добавления скрипта или искаженного HTML. Используйте метод toStaticHTML для фильтрации динамического содержимого или явно создавайте элементы и атрибуты с помощью такого метода, как createElement.

И указывает на строку в реализации добавления jQuery:

append: function() {
        return this.domManip(arguments, true, function( elem ) {
            if ( this.nodeType === 1 || this.nodeType === 11 ) {
                this.appendChild( elem ); // Here!
            }
        });
    }

Кто-нибудь знает, есть ли способ обойти это? (Мне нужен jQuery, потому что я хочу использовать JsRender в качестве механизма шаблонов).


person mat    schedule 30.10.2012    source источник


Ответы (2)


Вы используете функцию обеспечения безопасности хоста. Хосту Win8 HTML не нравится, когда вы создаете элементы из строк; в этом случае, в частности, ему не нравится, когда вы помещаете атрибут name="" в элементы ввода. Не могли бы вы установить идентификатор вместо имени?

См. http://msdn.microsoft.com/en-us/library/windows/apps/hh465388.aspx, чтобы узнать, что считается безопасным.

Сообщение об ошибке фактически дало вам два варианта обхода ошибки:

  1. используйте метод toStaticHTML для фильтрации динамического содержимого
  2. явно создавать элементы и атрибуты

Использование toStaticHTML будет выглядеть так:

    $('.some-element').append(toStaticHTML('<input type="radio" name="test"><label>Test</label>'));

Но это приведет к тому, что созданный HTML-код может выглядеть иначе, чем строка, которую вы передали; toStaticHTML удалит элементы и атрибуты, которые считаются небезопасными.

Второй вариант — использовать DOM API напрямую, а не jQuery для создания рассматриваемых элементов, вы уже сказали, что это недопустимо.

Существует третий вариант, хотя он может не позволить вам пройти процесс проверки магазина:

MSApp.execUnsafeLocalFunction(function() {
    $('.some-element').append('<input type="radio" name="test"><label>Test</label>');
});

Это временно отключит небезопасные проверки html. НЕ ДЕЛАЙТЕ ЭТОГО, ЕСЛИ ВЫ НЕ ПРОВЕЛИ АНАЛИЗ БЕЗОПАСНОСТИ. В частности, НЕ берите строку, полученную из XHR, и не используйте ее для создания DOM, это приглашение получить ваше приложение и компьютер вашего пользователя, pwnd.

person Chris Tavares    schedule 30.10.2012
comment
Привет, спасибо за ваш ответ. Основная проблема в моем случае заключается в том, что я хотел бы использовать JsRender для создания шаблонов, а для этого используется jQuery. Так что я сам не использую jQuery напрямую, поэтому toStaticHTML на самом деле не вариант. Я мог бы использовать встроенные шаблоны WinJS, но это просто противоречит возможности использовать ваш обычный стек веб-технологий для приложений Магазина Windows (я думаю) - но я думаю, что я застрял с этим или просто набираю разметка вручную. Еще раз спасибо за ответ, он был очень полезен - person mat; 31.10.2012
comment
Есть еще пара вариантов для вас, и вы все равно можете продолжать использовать JsRender, хотя я предполагаю, что я не знаю JsRender. Во-первых, отредактируйте свои шаблоны рендеринга, чтобы исключить из них то, что считается небезопасным. Другой способ — инкапсулировать вызов JsRender в методе execUnsafeLocalFunction, который отключает проверку безопасности на время существования этого стека вызовов. Хотя, если JsRender выполнит рендеринг шаблона позже (knockout.js имеет эту проблему при обновлении из привязки), вы не сможете использовать execUnsafeLocalFunction без редактирования источника. - person Chris Tavares; 01.11.2012
comment
Ну, я действительно не знаю, какие вещи считаются небезопасными (так с какой следующей проблемой я столкнусь?), и в моем конкретном случае атрибут имени находится на переключателе, потому что мне нужна группа переключателей. Если я не могу использовать это, я должен сам запрограммировать функциональность, предоставленную браузером (что меня не очень интересует). - person mat; 01.11.2012
comment
Вы прошли по ссылке, по которой я дал ответ? Это точный список того, что считается безопасным/небезопасным. - person Chris Tavares; 02.11.2012

Может быть, вы можете использовать

WinJS.Utilities.setInnerHTMLUnsafe(divName, '<input type="radio"><label>Test</label>');
person Víctor    schedule 10.06.2013