TypeScriptでjQueryプラグインとか
かなりポンコツなjQuery Mobile
特にPopupは結構致命傷で、例えばInputを配置してAndroidで表示すると日本語入力できません
キーボードに負けます
公式のデモでもそうなので、現状どうしようもないのでしょう
そこで別途オーバーラップな子ウィンドウをでっちあげます
JavaScriptを使用しなくてはいけないのですが、生のJavaScriptは書きたくありません
無理です、スペルミスで勝手に変数が生えてくるようなものは気が狂います、古VBのバリアント思い出します
そこでTypeScript
型付き、Class付き、Namespace付きのJavaScript擬きです
最終的には自動生成されたJavaScriptが実行されるのですが、VisualStudioを使用している限りは変換等を気にする必要はありません
発行まで全自動です
VisualStudioは2013なのでTypeScript1.8.2とかなり古いですが十分です
別途型定義ファイル(*.d.ts)が必要ですがNuGetでサクッと取れます
ソースファイルの先頭に
/// <reference path="../scripts/typings/jquery/jquery.d.ts" /> /// <reference path="../scripts/typings/jquerymobile/jquerymobile.d.ts" />
と書くと使えるようになります
外部モジュールとか使えるようですが面倒なのでこれでいいです
VisualStudioでプロジェクトのプロパティに「TypeScrptビルド」があるので「暗黙的な'any'型を許可」をオフしなと台無しです
ECMAScriptのバージョンは5で
設定が出ない場合はtsファイルを追加してVisualStudio再起動
脱線してTypeScriptでprototypeとjQueryプラグインを書いてみます
/Srcにcm.tsとhome.tsを作成します
homeはhtmlに合わせただけでなんでもよいです
cmは共通モジュールです
/Src/cm.ts
interface String { toInt(): number; toFloat(): number; } String.prototype.toInt = function () { let n = parseInt(this, 0); if (!n || isNaN(n)) { n = 0; } return n; }; String.prototype.toFloat = function () { let n = parseFloat(this); if (!n || isNaN(n)) { n = 0; } return n; }; interface Number { toComma(): string; toFillZero(width: number): string; } Number.prototype.toComma = function () { return String(this).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,"); }; Number.prototype.toFillZero = function (width: number) { let v = String(this); width -= v.length; if (width > 0) { return Array(width + 1).join("0") + v; } else { return v; } };
StringとNumberを拡張します
interface を用意して実行という流れになります
インテリセンスも効いてくれます
interface JQuery { checked(): boolean; checked(value: boolean): JQuery; disabled(): boolean; disabled(value: boolean): JQuery; uiDisabled(): boolean; uiDisabled(value: boolean): JQuery; resetDisplay(): JQuery; readOnly(): boolean; readOnly(value: boolean): JQuery; uiBtnActive(): boolean; uiBtnActive(value: boolean): JQuery; uiBtnUnderline(): boolean; uiBtnUnderline(value: boolean): JQuery; vclick(): JQuery; isVisible(): boolean; } namespace JQuery { "use strict"; let $: JQueryStatic = <JQueryStatic>jQuery; $.fn.disabled = function (value?: boolean): JQuery | boolean { if (typeof value === "undefined") { if ($(this).is(":disabled")) { return true; } else { return false; } } else { if (value === true) { $(this).attr("disabled", "disabled"); } else { $(this).removeAttr("disabled"); } return this; } }; $.fn.uiDisabled = function (value?: boolean): JQuery | boolean { if (typeof value === "undefined") { return $(this).hasClass("ui-disabled"); } else { if (value === true) { $(this).addClass("ui-disabled"); } else { $(this).removeClass("ui-disabled"); } return this; } }; $.fn.readOnly = function (value?: boolean): JQuery | boolean { if (typeof value === "undefined") { if ($(this).is(":readonly")) { return true; } else { return false; } } else { if (value === true) { $(this).attr("readonly", "readonly"); } else { $(this).removeAttr("readonly"); } return this; } }; $.fn.checked = function (value?: boolean): JQuery | boolean { if (typeof value === "undefined") { if ($(this).is(":checked")) { return true; } else { return false; } } else { if (value === true) { $(this).attr("checked", "checked"); } else { $(this).removeAttr("checked"); } return this; } }; $.fn.resetDisplay = function () { $(this).css("display", ""); return this; }; $.fn.uiBtnActive = function (value?: boolean): JQuery | boolean { if (typeof value === "undefined") { return $(this).hasClass("ui-btn-active"); } else { if (value === true) { $(this).addClass("ui-btn-active"); } else { $(this).removeClass("ui-btn-active"); } return this; } }; $.fn.uiBtnUnderline = function (value?: boolean): JQuery | boolean { if (typeof value === "undefined") { return $(this).hasClass("ui-btn-underline"); } else { if (value) { $(this).addClass("ui-btn-underline"); } else { $(this).removeClass("ui-btn-underline"); } return this; } }; $.fn.vclick = function (): JQuery { $(this).trigger("vclick"); return this; }; $.fn.isVisible = function (): boolean { if ($(this).is(":visible")) { return true; } else { return false; } }; }
こちらも流れは同じです