jQueryはMetro JavaScriptアプリのオプションでした のように聞こえたので、Windows 8開発者を楽しみにし始めていました。 Visual Studio 2012 Express RCをインストールし、新しいプロジェクトを開始しました(空のテンプレートとグリッドテンプレートの両方に同じ問題があります)。
JQuery 1.7.2のローカルコピーを作成し、スクリプト参照として追加しました。
<!-- SomeTestApp references -->
<link href="/css/default.css" rel="stylesheet" />
<script src="/js/jquery-1.7.2.js"></script>
<script src="/js/default.js"></script>
残念ながら、結果のアプリを実行するとすぐに、コンソールエラーが発生します。
HTML1701:動的コンテンツ「a」を追加できませんスクリプトが、動的コンテンツ、または以前に動的に変更された要素を挿入しようとしましたが、安全ではない可能性があります。たとえば、innerHTMLプロパティを使用してスクリプトまたは不正なHTMLを追加すると、この例外が生成されます。 toStaticHTMLメソッドを使用して、動的コンテンツをフィルタリングするか、createElementなどのメソッドで要素と属性を明示的に作成します。詳細については、 http://go.Microsoft.com/fwlink/?LinkID=247104 を参照してください。
JQueryの縮小されていないバージョンのブレークポイントをスラップし、 問題のある行 を見つけました。
div.innerHTML = " <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
どうやら、Metroアプリのセキュリティモデル この方法で要素を作成することを禁止 。このエラーは、ユーザーに直接的な問題を引き起こすことはありませんが、その場所を考えると、jQueryの機能発見テストが失敗するのではないかと心配しています。
私は間違いなくjQueryが欲しい$.Deferred
ほぼすべてを簡単にするため。セレクターエンジンとイベント処理システムを使用できるようにしたいと思いますが、必要に応じてそれらを使用せずに生活します。
最新のjQueryをどのようにしてMetro開発とうまく連携させることができますか?
jQuery.support
関数をMSApp.execUnsafeLocalFunction
に渡すようにjQueryソースを編集する必要があります。これにより、次のように安全でないコンテンツのチェックが無効になります。
jQuery.support = MSApp.execUnsafeLocalFunction(function() {
var support,
all,
a,
select,
opt,
input,
fragment,
tds,
events,
eventName,
i,
isSupported,
div = document.createElement( "div" ),
documentElement = document.documentElement;
// lots of statements removed for brevity
return support;
});
括弧の最後のペアを削除することを忘れないでください-execUnsafeLocalFunction
は渡された関数を自動的に実行するので、自己実行関数は必要ありません。
WinJS機能を使用することをお勧めします。これには、遅延操作(それ自体がPromiseパターンの実装)の代替としてWinJS.Promise
オブジェクトが含まれます。そして、WinJS.Utilities
名前空間を使用して、いくつかの基本的なDOM操作を行うことができます。
遅延操作にjQueryを使用することをよく考えてください。 WinJS.Promise
オブジェクトは、非同期アクティビティを表すためにMetro API全体で使用され、最終的には2つの類似した異なるアプローチを使用します。
価値のあるものとして、jQueryコアの大部分をネイティブのWinJSライブラリをラップするように移植しました。軽量で、バッジ、通知などのプラグインを追加することでjQueryが実行するほぼすべての機能を提供します。
それは進行中の作業ですが、私は何人かの人々に楽しみに参加してもらうことを試みています。
https://github.com/rmcvey/winjq
簡単な説明(ドキュメントを追加中): http://practicaljs.com/jquery-in-windows-8-apps/
最近の// Build/2012会議と this talk の後、Windows 8ストアアプリでjQueryを使用する方法について説明します。具体的には、スクリプトインジェクション内部innerHTMLの正確な例外について話し、これで行われた更新について話します。
会社AppendToも、その講演中に jQuery for Windows 8 を公式に発表しました。リンクのトークで与えられたデモンストレーションからきれいに見えます。
また、ローカルコンテキストでWindows 8アプリのCDNからjQueryを取得することはお勧めできません。
GitHubの JavaScript Dynamic Content shim は、このエラーに対処するためにMicrosoft Open Technologiesによって作成およびリリースされました。 jQueryでテストされていませんが、ほとんどの場合、問題を解決できます。他のスクリプトが実行される前に、アプリの先頭でwinstore-jscompat.jsファイルを参照します。このエラーは表示されなくなります。
私はもう少し調査をして、いくつかのことを明確にしたかったです。
表示されるエラーはJavaScriptコンソールにあり、実際の例外ではありません。 jQueryコードは引き続き実行されますjust fine。実際には、エラーや例外ではなく、基になるシステムが記録しているものです。
JQueryにパッチを適用するなどの理由はありません。実際のエラーではなく、ノイズの多いシステムコンポーネントです。
JQueryをWindows 8で動作させる方法について、かなり詳細な説明をここに書きました http://davidvoyles.wordpress.com/2013/09/23/hacking-jquery-to-work-in-windows-8 /
これは、コンテンツセキュリティポリシー(CSP)によって課される制限と同じだと思います。この特定のケースはjQuery 1.8.0で対処されました。それでも問題は発生しますか?
https://github.com/jquery/jquery/commit/dc83072878ed9636c8158a014bd9fa4acc1ccce
次の形式のすべてのコードを置き換えた限り、jQuery自体は最新バージョンではこのような例外をスローしませんでした:
_$('<input type="button" value="Press Me" />')
_
と
_$(toStaticHTML('<input type="button" value="Press Me" />'))
_
すべてのHTML文字列が安全でないと見なされるわけではないことに注意してください:
_$('<span></span>')
_
例外をスローしません。ただし、何らかの処理を行うと、jQueryは引き続き追加時に例外をスローします。
_var div = '<div class="' + classesToApply + '"';
div += attrToAdd;
div += '</div>';
$(div).appendTo(container);
_
上記はjQueryを使用する良い方法の例ではありませんが、jQueryを使用する人もいるので、エラーが発生する可能性があります。上記のコードは、最初のスニペットと同じエラーを生成せず、jQuery.append内でエラーをスローします。このエラーは、$(toStaticHTML(div)).appendTo(container);
を実行することで修正されます
それでも必要な場合は、jQueryにあるDeferredオブジェクトの再実装を書いています。
終了したら、jQueryのDeferredオブジェクトと100%互換性があるはずです。現時点では完全に完了していますが、テストが必要です。
this を参照してください。
これが役立つことを願っています!
とはいえ、Windows 8アプリで作業するときは、jQueryの代わりにMicrosoftのPromiseの実装を使用する方法を学ぶことをお勧めします。
InnerQueryを設定するjQueryのすべての場所を見つけ、設定されている値をtoStaticHTML()
でラップすることで、この問題を解消できました。
したがって、たとえば:
div.innerHTML = " <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
なりました:
div.innerHTML = toStaticHTML(" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>");
安全のため、ファイルが通常のブラウザで使用される場合に備えて、jQueryが定義される直前にこれも定義しました。
window.toStaticHTML = window.toStaticHTML || function (s) { return s; };
私にとって最も安全な変更のように思えましたが、jQueryで数十箇所にパッチを適用する必要がありました。 (toStaticHTMLの前にvarステートメントを使用しないでください)