JavaScriptの最近のブログ記事

とっても速い擬似乱数生成器。Xorshift RNGs - lucille development blog 辺りを参考に。周期も適当に長く取れるので、再現性が必要なゲームにいいかもね。データの動的生成にも使えるかな?

(function (namespace) {
/**
* Xorshift128 の新しいインスタンスを初期化します。
*
* @param Number x 種その1。
* @param Number y 種その2。
* @param Number z 種その3。
* @param Number w 種その4。
*/
namespace.Xorshift128 = function (x, y, z, w)
{
var u = void(0);
this.x = x === u ? 123456789 : 0 + x;
this.y = y === u ? 362436069 : 0 + y;
this.z = z === u ? 521288629 : 0 + z;
this.w = w === u ? 88675123 : 0 + w;

if ((this.x | this.y | this.z | this.w) == 0)
{
throw new Error("x, y, z, w 全部 0 は、らめ!");
}
}

/**
* 0 以上 1 未満の乱数を返します。
*
* @return Number 0 以上 1 未満の値。
*/
namespace.Xorshift128.prototype.next = function ()
{
return this.nextUInt32() / 4294967296;
}

/**
* 0 以上 4294967296 未満の乱数を返します。
*
* @return Number 0 以上 4294967296 未満の値。
*/
namespace.Xorshift128.prototype.nextUInt32 = function ()
{
var t = this.x ^ this.x << 11;
this.x = this.y;
this.y = this.z;
this.z = this.w;
this.w = (this.w ^ this.w >>> 19) ^ (t ^ t >>> 8);

return this.w >>> 0;
}
})(window);

///////////////////////////////////////////////
var xs = new Xorshift128();
xs.next();
xs.nextUInt32();

IE だけグローバル オブジェクトのプロトタイプ オブジェクトが違うというお話です。

Object.prototype.isPrototypeOf(window);
// IE 6: false
// IE 7: false
// Firefox 2.0.0.12: true
// Opera 9.2.6: true
// Safari 3.0.4b: true

Object.prototype に毛を生やしても IE だけ影響を受けませんね。ECMA 262 3rd edition の仕様ではグローバル オブジェクトのプロトタイプ オブジェクトは実装依存だそうです。

また、window に特定のプロパティがあるかどうか知りたい場合に上記の理由で window.hasOwnProperty() とする事が出来ないので…

window.hasOwnProperty("undefined");
// IE: エラー「オブジェクトでサポートされていないプロパティまたはメソッドです。」
// Firefox 2.0.0.12: true
// Opera 9.2.6: false
// Safari 3.0.4b: true

Function#call() または Function#apply() を利用することになります。

Object.prototype.hasOwnProperty.call(window, "undefined");
// IE 6: true
// IE 7: true
// Firefox 2.0.0.12: true
// Opera 9.2.6: false
// Safari 3.0.4b: true

WYSIWYG Editor, Rich Text Editor, HTML Editor いろいろ呼び方あるけれど

カズキ先生との HTML の編集についての話で出てきたリッチ テキスト エディタについて調べてみました。

リッチ テキスト エディタとは、入力したデータと出力したデータの見た目が一致するテキスト エディタの事を指します。 今作りながら見ている物がそのまま出力結果となる、この事を用語で

WYSIWYG: "What You See Is What You Get"

と言います。

というわけで、今回作るのがこちらです。

作り方

  1. エディタの基礎
  2. 編集領域を準備する
  3. 内容を編集する
エディタの基礎

今見ているブラウザがそのままエディタになります。エディタにするには、JavaScript で document オブジェクトの designMode プロパティを "on" にします。

window.document.designMode = "on";
編集領域を準備する

designMode はドキュメント全体に適用されます。そこで、編集領域となるドキュメントを IFRAME 要素、もしくは OBJECT 要素で埋め込みます。ここでは XHTML 1.1 でも通用するように、OBJECT 要素で埋め込む方法を示します。

<object id="editWindow" type="text/html" data="blank.html" width="200" height="150"></object>

data 属性に指定されている blank.html は空のファイルです。(blank.html とエディタのドメインが異なっているとセキュリティの問題でアクセスできない場合があります)

OBJECT 要素で埋め込んだドキュメントの window オブジェクトは、次の方法で取得します。手段はブラウザによって若干違います。

Internet Explorer の場合。

// 編集領域の window オブジェクト
var w = window.document.getElementById("editWindow").object.parentWindow;

Firefox, Opera の場合。

// 編集領域の window オブジェクト
var w = window.document.getElementById("editWindow").contentDocument.defaultView;
内容を編集する

デザイン モードになったドキュメントへは、TEXTAREA 要素と同じように文章を編集できます。文章を装飾するには、document オブジェクトの execCommand メソッドを使用します。

書式
[document object].execCommand(command, userInterface, value)
引数
command (string)
Bold や Italic、JustifyCenter 等のコマンドを表す文字列。
userInterface (bool)
指定したコマンドがユーザへ情報を要求する場合、インターフェイスを表示させるかどうか。 例) document.execCommand("InsertImage", true, null) // IE ではファイル選択ダイアログが表示されます。
value (mixed)
指定したコマンドに対する引数。 例) document.execCommand("FontColor", false, "#ff0000");

次の例では、ボタンをクリックすると、選択範囲もしくはカーソルの位置が太字になります。

<object id="editWindow" type="text/html" data="blank.html" width="200" height="150"></object>
<button type="button" onclick="executeCommand('bold', false, null);">太字</button>

<script type="text/javascript">
window.onload = function ()
{
    getEditWindow().document.designMode = "on";
}

function getEditWindow()
{
    var container= window.document.getElementById("editWindow");
    var w;

    if (window.document.all && !window.opera)
    {
        w = container.object.parentWindow;
    }
    else
    {
        w = container.contentDocument.defaultView;
    }

    return w;
}

function executeCommand(command, userInterface, value)
{
    getEditWindow().document.execCommand(command, userInterface, value);
}
</script>

execCommand で使用できるコマンドや引数については、以下のサイトを参照ください。

できあがり

以上の点をまとめて作ったサンプルがこちらです。

TODO

こういうのが実装されたら便利。

  • execCommand の userInterface をサポートしていないブラウザ用にダイアログを自作する。
  • 出力する HTML の正規化。
  • キャレットがある場所のテキストのスタイル、コンテキスト スタイルをツールバーに反映させる。

その他

アイコンは famfamfam.comSilk Icon を利用させて頂きました。

猫バトン

| | コメント(8)

にゃーんだと?

語尾にニャとかふざけてるのか!そんなバカなこと出来な…な…

猫化ブックマークレット

ブックマークレットと呼ばれてるやり方で実装しました。利用方法は簡単。

  1. 変換したいページを呼び出します。
    how-step-1.png
  2. ブラウザのアドレス欄に javascript:(function(){var u="http://zenith.sakura.ne.jp/bookmarklet/arisyu.js" ;var d=document;var s=d.createElement('script');s.charset="UTF-8";s.src=u;d.body.appendChild(s);})() をコピーして貼り付け、 Enter キーを押します。するとあら、こんなところにニャンコが…!
    how-step-2.png

もっと簡単な方法は、ブックマークに登録するやり方です。

  1. こちらのブックマークレットのページを表示して、猫化を右クリックしてコンテクスト メニューを出し、ブックマークに登録します。セキュリティうんぬんと出ますが無視します。
    bookmark-step-1.png
  2. 変換したいページを表示させ、先ほど登録したブックマークをクリックすると変換されます。
    bookmark-step-2.png

使用しているソースコード

/**
 * 猫化ブックマークレット
 *
 * 使用方法は、変換を適用させたいページをブラウザに表示させてから
 * アドレス欄に
 * javascript:(function(){var u="http://ブックマークレット設置箇所";var d=document;var s=d.createElement('script');s.charset="UTF-8";s.src=u;d.body.appendChild(s);})()
 * と入力します。
 */

// 名前空間用のオブジェクト window.Zenith が存在しなければ定義
if (!("Zenith" in window))
{
  Zenith = {};
}

// 名前空間用のオブジェクト window.Zenith.Bookmarklet が存在しなければ定義
if (!("Bookmarklet" in window.Zenith))
{
  Zenith.Bookmarklet = {};
}

/**
 * HTML 文章を猫化するブックマークレットの新しいインスタンスを初期化します。
 */
window.Zenith.Bookmarklet.Arisyu = function ()
{
  this.filters = [];
}

/**
 * 指定した要素に変換フィルタを適用します。
 *
 * @param HTMLElement element 対象の要素。
 * @param bool recursive 子要素にも再帰的に適用するなら TRUE、しないなら FALSE。
 */
window.Zenith.Bookmarklet.Arisyu.prototype.filter = function (element, recursive)
{
  for (var i = 0, iLast = this.filters.length; i < iLast; i++)
  {
    var f = this.filters[i];
    
    f.apply(element);
    
    if (recursive)
    {
      for (var j = 0, jLast = element.childNodes.length; j < jLast; j++)
      {
        var child = element.childNodes[j];
        this.filter(child, recursive);
      }
    }
  }
}

/**
 * 指定した要素が持つ全ての子要素のうち、変換対象の要素のテキストを猫化します。
 * 子要素は再帰的に列挙されます。
 *
 * @param HTMLElement element 対象の要素。
 */
window.Zenith.Bookmarklet.Arisyu.prototype.apply = function (container)
{
  this.filter(container, true);
}


/**
 * 正規表現により文章を置換するフィルタの新しいインスタンスを初期化します。
 */
window.Zenith.Bookmarklet.Arisyu.RegExpFilter = function ()
{
  /**
   * 置換候補の正規表現と結果の辞書
   */
  this.dictionaries = [
      {
        "pattern": "な",
        "option": "gm",
        "replace": "にゃ"
      },
      {
        "pattern": "ぬ",
        "option": "gm",
        "replace": "にゅ"
      },
      {
        "pattern": "わたし|ワタシ|わたくし|ワタクシ|私|ぼく|ボク|ぼかぁ|僕|おれ|オレ|俺|じぶん|ジブン|自分|拙者|麻呂",
        "option": "gm",
        "replace": "我輩"
      },
      {
        "pattern": "([!!]+)",
        "option": "gm",
        "replace": "にゃ$1"
      },
      {
        "pattern": "([…+|・+])",
        "option": "gm",
        "replace": "にゃ$1"
      },
      {
        "pattern": "、",
        "option": "gm",
        "replace": "にゃー、"
      },
      {
        "pattern": "(ね?)。",
        "option": "gm",
        "replace": "にゃん。"
      }
    ];
  
  /**
   * 正規表現オブジェクトのキャッシュ
   */
  this.regexpCache = [];
}
  
/**
 * 指定された要素がフィルタの適用対象かどうかを取得します。
 *
 * @param HTMLElement 調べる対象の要素。
 * @return bool 適用対象なら TRUE、対象外なら FALSE。
 */
window.Zenith.Bookmarklet.Arisyu.RegExpFilter.prototype.isAcceptElement = function (element)
{
  var isAccept;
  
  switch (element.nodeName.toLowerCase())
  {
    case 'style':
    case 'script':
    case 'frame':
    case 'code':
      isAccept = false;
      break;
    
    default:
      isAccept = true;
  }
  
  return isAccept;
}

/**
 * 指定された要素へフィルタを適用します。
 *
 * @param HTMLElement 適用対象の要素。
 */
window.Zenith.Bookmarklet.Arisyu.RegExpFilter.prototype.apply = function (element)
{
  if ("parentNode" in element && element.parentNode != null)
  {
    if (!this.isAcceptElement(element.parentNode))
    {
      return;
    }
  }
  
  if (element.nodeName.toLowerCase() != "#text")
  {
    return;
  }
  
  var nodeValue = element.nodeValue;
  
  for (var i = 0, iLast = this.dictionaries.length; i < iLast; i++)
  {
    var dictionary =  this.dictionaries[i];
    
    if (!(i in this.regexpCache))
    {
      this.regexpCache[i] = new RegExp(dictionary.pattern, dictionary.option);
    }
    
    var regexp = this.regexpCache[i];
    nodeValue = nodeValue.replace(regexp, dictionary.replace);
  }
  
  element.nodeValue = nodeValue;
}


////////////////////////////////////////////////////////////////////////////
// ここから実行
////////////////////////////////////////////////////////////////////////////

var arisyu = new Zenith.Bookmarklet.Arisyu();

// フィルタ設定
arisyu.filters = [
    new Zenith.Bookmarklet.Arisyu.RegExpFilter()
  ];

// トップ レベルの文章に適用
arisyu.apply(window.document);

// フレームがあればそちらも適用
if ("frames" in window)
{
  for (var i = 0, iLast = window.frames.length; i < iLast; i++)
  {
    arisyu.apply(window.frames[i].document);
  }
}

flash.external.ExternalInterface クラスを使用する

flash.external.ExternalInterface は Flash Player とそのコンテナ(ブラウザなど)間で通信する為のクラス。ブラウザの HTML ドキュメントに Flash Player からちょっかいだしたり出されたりできる。

使い道

例えばシステムのフォントを列挙して JavaScript で利用する。サンプルはこちらscreenshot.png

使用した MXML ファイル

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" applicationComplete="this.applicationCompleteEventHandler(event);" layout="absolute" width="400" height="200" fontSize="12">
    <mx:Script>
        <![CDATA[
            import flash.external.ExternalInterface;
            import mx.events.FlexEvent;

            protected function applicationCompleteEventHandler(event:FlexEvent):void
            {
                var available:Boolean = ExternalInterface.available;
                this.availableLabel.text = "外部インターフェイス: "
                    + (available ? "利用可能" : "利用不可");

                if (available)
                {
                    ExternalInterface.addCallback("enumerateFont", this.enumerateFont);
                }
            }
            
            public function enumerateFont():Array
            {
                if (ExternalInterface.available)
                {
                    var fontNames:Array = new Array();
                    var fonts:Array = Font.enumerateFonts(true);
                    
                    for each (var font:Font in fonts)
                    {
                        fontNames.push(font.fontName);
                    }

                    return fontNames;
                }
                
                return null;
            }
        ]]>
    </mx:Script>
    
    <mx:Panel layout="vertical" title="フォント列挙" x="10" y="10" horizontalAlign="center" paddingBottom="10" paddingLeft="10" paddingRight="10" paddingTop="10">
        <mx:Label id="availableLabel"/>
    </mx:Panel>
</mx:Application>

iTunes でおなじみの検索ボックス スタイル

勉強しないとだめなのについ掃除を始めちゃう、そんな気分なので、こんなの preview.png を CSS で再現しちゃう。

こうしちゃう

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja">
  <head>
    <title>検索ボックス</title>

    
    <style type="text/css">
      #search input.word
      {
        margin: 0;
        padding: 0.4em 0.4em 0.4em 24px;
        width: 16em;
        border: 1px solid silver;
        background-color: white;
        background-image: url("search.gif");
        background-position: 4px center;
        background-repeat: no-repeat;
      }

      #search input.active
      {
        color: black;
      }

      #search input.passive
      {
        color: gray;
      }
    </style>
    
    <script type="text/javascript">
      this.onload = function ()
      {
        var word = this.document.forms.search.word;
        
        word.onfocus = function ()
        {
          if (this.value == this.defaultValue)
          {
            this.value = '';
            this.className = 'word active';
          }
        }
        
        word.onblur = function ()
        {
          if (this.value == '')
          {
            this.value = this.defaultValue;
            this.className = 'word passive';
          }
        }
        
        word.onkeydown = function (event)
        {
          var e = event || window.event;
          
          if (e.keyCode == 13)
          {
            if (this.value != '')
            {
              this.form.submit();
            }
          }
        }
        
        word.onfocus();
        word.onblur();
      }
    </script>
  </head>

  
  <body>
    <form id="search" action="#dummy">
      <p>
        <input type="text" name="word" value="検索キーワードを入力して下さい" class="word" tabindex="1" accesskey="F" />
      </p>
    </form>

  </body>
</html>

こうなった

サンプルはこちらです。

問題点

  • CSS のサポートが控え目なブラウザでは控え目なスタイルに。
  • JavaScript を切ってたら Firefox 等で送信できない。これは type="submit" な INPUT 要素を追加して CSS で見えなくするべきかしら?

更に問題点

間に合わなくなった。

現在の状態

UL, OL 要素は入れ子にする事が出来ます。この時、項目数や入れ子が多くになるにつれて、項目同士の親子・兄弟関係が見辛くなるかもしれません。
fig1.png

親兄弟関係を表す線を入れる

そこで、項目同士の関係を表すを入れます。線の表現は CSS でやりたいと思います。その為にルートとなるリスト要素に treeView というクラス名を付け、各リストの最後の LI 要素にも last というクラス名を割り振ります。
fig2.png

<ul class="treeView">
  <li>2005年
    <ul>
      <li>9月</li>
      <li>10月</li>
      <li>11月</li>
      <li class="last">12月</li>
    </ul>
  </li>
  <li class="last">2006年
    <ul>
      <li>1月</li>
      <li>2月</li>
      <li>3月</li>
      <li>4月
        <ul>
          <li>1日</li>
          <li>3日</li>
          <li>4日</li>
          <li>20日</li>
          <li class="last">28日</li>
        </ul>
      </li>
      <li>5月</li>
      <li class="last">6月</li>
    </ul>
  </li>
</ul>

適用する CSS は以下の通りです。

.treeView
{
  background-color: white;
  
  font-family: "ヒラギノ角ゴ Pro W3", Osaka, Tahoma, Verdana, "MS UI Gothic", "MS Pゴシック", sans-serif;
  font-size: small;
  color: black;
}

.treeView,
.treeView ul,
.treeView ol
{
  margin: 0 0 0 20px;
  padding: 0;

  background-image: url("line_vertical.png");
  background-repeat: repeat-y;
}

.treeView li
{
  margin: 0;
  padding: 0;
  
  background-image: url("line_diverge.png");
  background-repeat: no-repeat;

  text-indent: 20px;
  line-height: 160%;

  list-style-type: none;
  list-style-position: outside;
}

.treeView li.last
{
  background-color: white;
  background-image: url("line_terminal.png");
}

項目最後の要素にクラス名を振るのが大変

更新が多い部分で用いる場合、クラス名を手作業で振り直すのはかなりの作業量です。許されるなら JavaScript でクラス名を割り振ります。

function setTreeViewStyle(list)
{
  list.className = "treeView";
  
  setTreeViewItemStyle(list);
}

function setTreeViewItemStyle(list)
{
  var items = list.childNodes;
  var marked = false;
  
  for (var i = items.length - 1; i >= 0; i--)
  {
    var element = items[i];
    
    if (element.tagName && element.tagName.toLowerCase() == "li")
    {
      if (!marked)
      {
        element.className = "last";
        marked = true;
      }

      var subItems = element.childNodes;
      
      for (var j = subItems.length - 1; j >= 0; j--)
      {
        var element = subItems[j];
        
        if (element.tagName)
        {
          switch (element.tagName.toLowerCase())
          {
            case "ul":
            case "ol":
              setTreeViewItemStyle(element);
              
              break;
          }
        }
      }
    }
  }
}

実際に利用する場合は以下のようにします。

<body onload="setTreeViewStyle(document.getElementById('tree'));">
  <ul id="tree">
    <li>2005年
    <ul>
      <li>9月</li>
      <li>10月</li>
      ...後略

JavaScript を使っていると、必然的にブラウザ毎の実装の違いを吸収した関数を用意する。 例えば指定した ID で HTML 要素(レイヤー) を取得する場合、いつも以下のように書いていた。この関数は呼び出される毎にブラウザの特徴を嗅ぎ分けて、それにふさわしい処理を行おうとしている。

/**
 * 指定した ID を持つ HTML 要素を取得する
 *
 * @param 	string	ID
 * @return	object	HTML 要素
 */
function getLayer(id)
{
	var element = null;

	if (document.getElementById)
	{
		element = document.getElementById(id);
	}
	else if (document.all)
	{
		element = document.all(id);
	}
	else if (document.layers)
	{
		element = document.layers[id];
	}
	
	return element;
}

ここで気になるのが、関数を呼び出す度にブラウザを嗅ぎ分けて、それにふさわしい処理を行おうとしている点だ。嗅ぎ分けた結果を変数に入れてしまえば、分岐に掛かる時間はちょっとだけ減る。だがいまいちパッとしない。という事で書いたのが次のコードだ。

/**
 * 指定した ID を持つ HTML 要素を取得する
 *
 * @param 	string	ID
 * @return	object	HTML 要素
 */
getLayer =
	  (document.getElementById)
	? function (id) { return document.getElementById(id); }
	: (document.all)
	? function (id) { return document.all(id); }
	: (document.layers)
	? function (id) { return document.layers[id]; }
	: function (id) { return null;}

ごちゃごちゃとしていて見辛いが、やってる事は getLayer というよく判らない変数へ、ブラウザにふさわしい無名関数を入れてやっている。これできちんと期待通りに動いてくれる。この getLayer というグローバル変数も、最初の関数 getLayer も、window オブジェクトのプロパティであるのを利用している。次に例を書こう。

function XXX() { hogehoge; }

というコードは、

XXX = function () { hogehoge; }

と等価である。もう少し書こう。

function neko()
{
	alert("∧∧");
}

neko();         // alert("∧∧")
window.neko();  // alert("∧∧")


neko = function ()
{
	alert("にゃー");
}

neko();         // alert("にゃー")
window.neko();  // alert("にゃー")


var neko = "猫";

neko();			// エラー。neko is not function
window.neko();	// エラー。neko is not function

関数を定義するという事は、オブジェクトのプロパティに無名関数を登録している、と考えるといいかも知れない。

こうやって実行時に関数を定義してしまえば、余計なブラウザの嗅ぎ沸けを省く事が出来る。それによってCPUはちょっぴり(本当に、本当に少し)消費電力を少なくする。実に経済的だ。郊外のショッピングセンターで近所のスーパーより1円安いレタスを見付けたら、リッター130円のガソリンを使って車を走らせる事をためらってはならない。

Ajax なチャット

| | コメント(2)

Ajax の習作、RO風のチャット。
ajaxchat.png

サンプルは こちら。ソースコードは こちら
自由に使いねい。エラーが出たら教えてくれい。
動作確認 (Win32) Internet Explorer 5.5/6.0 Netscape 7.1 Firefox 1.0.4 Opera 8.01

従来のチャットと何が違うのか?
画面偏移がない
湖に浮かぶ白鳥が泳ぐように、見えない場所でがんばるのが Ajax の役目。

Ajax はクライアントとサーバーの関係を変える物ではない?
クライアントの要求を細かく処理していく。待たせない。

なんとなくかっこいい?
空賊連合よりはかっこいい。豚も言っている。

将来性は?
タダで作れるところがポイント。お金があるなら Flash 等のリッチクライアントを使用すべし。

XMLHttpRequest

| | コメント(2)

Ajax に必要不可欠な XMLHttpRequest の得方を調べた。
前者はラッパー関数を用いてインスタンスを取得する方法。
後者は window.XMLHttpRequest コンストラクタを自分で定義してしまう方法。面白いやり方だなぁ…

/**
 * XMLHttpRequest オブジェクトを作成する
 *
 * @return	XMLHttpRequest
 **/
function createXMLHttpRequest()
{
	var request = null;
	
	if (window.XMLHttpRequest)
	{
		try
		{
			request = new XMLHttpRequest();
		}
		catch (e)
		{
		}
	}
	else if (window.ActiveXObject)
	{
	    var names = new Array(
				'Msxml2.XMLHTTP.5.0',
				'Msxml2.XMLHTTP.4.0',
				'Msxml2.XMLHTTP.3.0',
				'Msxml2.XMLHTTP',
				'Microsoft.XMLHTTP'
			);
		
		for (var i = 0, iMax = names.length; i < iMax; i++)
		{
			try
			{
				request = new ActiveXObject(names[i]);
				break;
			}
			catch (e)
			{
			}
		}
	}

return request;
}

var request = createXMLHttpRequest();

/**
 * window.XMLHttpRequest コンストラクタ オブジェクトを定義する
 *
 * @return	XMLHttpRequest
 **/
if (!window.XMLHttpRequest && window.ActiveXObject)
{
	function window.XMLHttpRequest = function ()
	{
		var names = new Array(
				'Msxml2.XMLHTTP.5.0',
				'Msxml2.XMLHTTP.4.0',
				'Msxml2.XMLHTTP.3.0',
				'Msxml2.XMLHTTP',
				'Microsoft.XMLHTTP'
			);
		
		for (var i = 0, iMax = names.length; i < iMax; i++)
		{
			try
			{
				request = new ActiveXObject(names[i]);
				break;
			}
			catch (e)
			{
			}
		}
		
		return request;
	}
}

request = new XMLHttpRequest();

このアーカイブについて

このページには、過去に書かれたブログ記事のうちJavaScriptカテゴリに属しているものが含まれています。

前のカテゴリはHTMLです。

次のカテゴリはMXMLです。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

Powered by Movable Type 4.12