| 282 | |
| 283 | 以上が、 Java や C++ などで言うところのクラス定義に相当する、といって良いでしょう。継承を行いたい場合は、新たに定義するコンストラクタの関数名に、プロトタイプの複製をコピーしてあげれば ok です。以下のような記述になります。 |
| 284 | |
| 285 | {{{ |
| 286 | // ダイアログオブジェクトの基本クラス |
| 287 | function Dialog() {} |
| 288 | Dialog.prototype = { |
| 289 | "doModal": function(callback) { |
| 290 | this.modal_callback = callback; |
| 291 | this.createDialog(); |
| 292 | }, |
| 293 | "createDialog": function() { |
| 294 | this.window = document.createElement("div"); |
| 295 | this.window.className = "dialog"; |
| 296 | var dialog_title = document.createElement("h2"); |
| 297 | dialog_title.appendChild(document.createTextNode(this.title || "名称未定義")); |
| 298 | document.body.appendChild(this.window); |
| 299 | this.drawForm(); // 継承クラスにて実装する |
| 300 | this.show(); |
| 301 | }, |
| 302 | "show": function(is_show) { |
| 303 | is_show = typeof is_show == "boolean" ? is_show : true; |
| 304 | this.window.style.display = is_show ? "block" : "none"; |
| 305 | }, |
| 306 | "destroyDialog": function() { |
| 307 | if (!this.window) return; |
| 308 | if (this.modal_callback && this.preEndModal) { |
| 309 | var result = this.preEndModal(); |
| 310 | if (result == null) |
| 311 | return; |
| 312 | if (result) |
| 313 | this.modal_callback(); |
| 314 | } |
| 315 | if (this.preDestroyDialog) { |
| 316 | if (!this.preDestroyDialog()) |
| 317 | return; |
| 318 | } |
| 319 | document.body.removeChild(this.window); |
| 320 | this.window = undefined; |
| 321 | } |
| 322 | }; |
| 323 | |
| 324 | function AhoDialog() { |
| 325 | this.title = "あほダイアログ"; |
| 326 | } |
| 327 | |
| 328 | AhoDialog.prototype = new Dialog(); // メンバメソッドを継承 (プロトタイプの複製をコピー) |
| 329 | |
| 330 | // 継承クラスの独自メソッドを記述 |
| 331 | AhoDialog.prototype.drawForm = function() { |
| 332 | this.dom_elems = {}; |
| 333 | var p = document.createElement("p"); |
| 334 | p.appendChild(document.createTextNode("あほあほ")); |
| 335 | this.window.appendChild(p); |
| 336 | p = document.createElement("p"); |
| 337 | p.appendChild(document.createTextNode("どう思いますか? → ")); |
| 338 | var input = document.createElement("input"); |
| 339 | input.type = "text"; |
| 340 | input.style.width = "20em"; |
| 341 | p.appendChild(input); |
| 342 | this.dom_elems.answer_input = input; |
| 343 | this.window.appendChild(p); |
| 344 | p = document.createElement("p"); |
| 345 | p.style.textAlign = "center"; |
| 346 | input = document.createElement("input"); |
| 347 | input.type = "button"; |
| 348 | input.value = "OK"; |
| 349 | var that = this; |
| 350 | input.onclick = function() { |
| 351 | that.is_ok = true; |
| 352 | that.destroyDialog(); |
| 353 | }; |
| 354 | p.appendChild(input); |
| 355 | p.appendChild(document.createTextNode(" ")); |
| 356 | input = document.createElement("input"); |
| 357 | input.type = "button"; |
| 358 | input.value = "キャンセル"; |
| 359 | input.onclick = function() { |
| 360 | that.is_ok = false; |
| 361 | that.destroyDialog(); |
| 362 | }; |
| 363 | p.appendChild(input); |
| 364 | this.window.appendChild(p); |
| 365 | }; |
| 366 | |
| 367 | AhoDialog.prototype.preEndModal = function() { |
| 368 | if (!this.is_ok) // キャンセルボタン |
| 369 | return false; |
| 370 | var answer = this.dom_elems.answer_input.value; |
| 371 | if (answer == "") { |
| 372 | alert("何か入力して下さい…。"); |
| 373 | this.dom_elems.answer_input.focus(); |
| 374 | return; |
| 375 | } |
| 376 | this.data = { |
| 377 | "answer": answer |
| 378 | }; |
| 379 | return true; |
| 380 | }; |
| 381 | |
| 382 | // 実際にダイアログを使用するコード例 |
| 383 | var dlg = new AhoDialog(); |
| 384 | dlg.doModal(function() { |
| 385 | var div = document.getElementById("result_container"); |
| 386 | while (div.childNodes.length > 0) |
| 387 | div.removeChild(div.lastChild); |
| 388 | var text = ""; |
| 389 | for (int i = 0; i < 1000; i++) |
| 390 | text += this.data.answer + " "; |
| 391 | div.appendChild(document.createTextNode(text)); |
| 392 | }); |
| 393 | }}} |