2009-02-12 27 views
1

我愛Prototype但它沒有附帶任何小部件。特別是,它不提供窗口/對話框的創建。原型中DHTML窗口/對話框的最佳技術?

我試過Prototype Window附加庫,但發現它不可靠,並且它已經很長時間沒有維護。

任何人有任何推薦的解決方案?或者根據第一原則創建對話框的任何食譜/模式(即沒有Prototype以外的庫)?我需要模態行爲(褪色的背景效果),我必須支持IE6以及現代瀏覽器。

只是要清楚,我不打算退出Prototype,並且我不想包含額外的基本庫,如JQuery。

回答

1

對於一個非常簡單的對話,籤這樣的代碼:http://snippets.dzone.com/posts/show/3411

很小而簡單 - 正是我想要的。

該代碼經過了一些修改。這是最終版本,我工作:

/* 
* Adapted from http://snippets.dzone.com/posts/show/3411 
*/ 

var Dialog = {}; 
Dialog.Box = Class.create(); 
Object.extend(Dialog.Box.prototype, { 
    initialize: function(id) { 
    this.createOverlay(); 

    this.dialog_box = $(id); 
    this.dialog_box.show = this.show.bind(this); 
    this.dialog_box.persistent_show = this.persistent_show.bind(this); 
    this.dialog_box.hide = this.hide.bind(this); 

    this.parent_element = this.dialog_box.parentNode; 

    this.dialog_box.style.position = "absolute"; 

    var e_dims = Element.getDimensions(this.dialog_box); 
    var b_dims = Element.getDimensions(this.overlay); 

    this.dialog_box.style.left = ((b_dims.width/2) - (e_dims.width/2)) + 'px'; 
    this.dialog_box.style.top = this.getScrollTop() + ((this.winHeight() - (e_dims.width/2))/2) + 'px'; 
    this.dialog_box.style.zIndex = this.overlay.style.zIndex + 1; 
    }, 

    createOverlay: function() { 
    if ($('dialog_overlay')) { 
     this.overlay = $('dialog_overlay'); 
    } else { 
     this.overlay = document.createElement('div'); 
     this.overlay.id = 'dialog_overlay'; 
     Object.extend(this.overlay.style, { 
     position: 'absolute', 
     top: 0, 
     left: 0, 
     zIndex: 90, 
     width: '100%', 
     backgroundColor: '#000', 
     display: 'none' 
     }); 
     document.body.insertBefore(this.overlay, document.body.childNodes[0]); 
    } 
    }, 

    moveDialogBox: function(where) { 
    Element.remove(this.dialog_box); 
    if (where == 'back') 
     this.dialog_box = this.parent_element.appendChild(this.dialog_box); 
    else 
     this.dialog_box = this.overlay.parentNode.insertBefore(this.dialog_box, this.overlay); 
    }, 

    show: function(optHeight/* optionally override the derived height, which often seems to be short. */) { 
    this.overlay.style.height = this.winHeight()+'px'; 
    this.moveDialogBox('out'); 

    this.overlay.onclick = this.hide.bind(this); 

    this.selectBoxes('hide'); 
    new Effect.Appear(this.overlay, {duration: 0.1, from: 0.0, to: 0.3}); 
    this.dialog_box.style.display = ''; 

    this.dialog_box.style.left = '0px'; 

    var e_dims = Element.getDimensions(this.dialog_box); 

    this.dialog_box.style.left = (this.winWidth() - e_dims.width)/2 + 'px'; 

    var h = optHeight || (e_dims.height + 200); 
    this.dialog_box.style.top = this.getScrollTop() + (this.winHeight() - h/2)/2 + 'px'; 
    }, 

    getScrollTop: function() { 
    return (window.pageYOffset)?window.pageYOffset:(document.documentElement && document.documentElement.scrollTop)?document.documentElement.scrollTop:document.body.scrollTop; 
    }, 

    persistent_show: function() { 
    this.overlay.style.height = this.winHeight()+'px'; 
    this.moveDialogBox('out'); 

    this.selectBoxes('hide'); 
    new Effect.Appear(this.overlay, {duration: 0.1, from: 0.0, to: 0.3}); 

    this.dialog_box.style.display = ''; 
    this.dialog_box.style.left = '0px'; 
    var e_dims = Element.getDimensions(this.dialog_box); 
    this.dialog_box.style.left = (this.winWidth()/2 - e_dims.width/2) + 'px'; 
    }, 

    hide: function() { 
    this.selectBoxes('show'); 
    new Effect.Fade(this.overlay, {duration: 0.1}); 
    this.dialog_box.style.display = 'none'; 
    this.moveDialogBox('back'); 
    $A(this.dialog_box.getElementsByTagName('input')).each(function(e) { 
     if (e.type != 'submit' && e.type != 'button') e.value = ''; 
    }); 
    }, 

    selectBoxes: function(what) { 
    $A(document.getElementsByTagName('select')).each(function(select) { 
     Element[what](select); 
    }); 

    if (what == 'hide') 
     $A(this.dialog_box.getElementsByTagName('select')).each(function(select){Element.show(select)}) 
    }, 

    winWidth: function() { 
    if (typeof window.innerWidth != 'undefined') 
     return window.innerWidth; 
    if (typeof document.documentElement != 'undefined' && typeof document.documentElement.clientWidth != 'undefined' && document.documentElement.clientWidth != 0) 
     return document.documentElement.clientWidth; 
    return document.getElementsByTagName('body')[0].clientWidth 
    }, 
    winHeight: function() { 
    if (typeof window.innerHeight != 'undefined') 
     return window.innerHeight 
    if (typeof document.documentElement != 'undefined' && typeof document.documentElement.clientHeight != 'undefined' && document.documentElement.clientHeight != 0) 
     return document.documentElement.clientHeight; 
    return document.getElementsByTagName('body')[0].clientHeight; 
    } 

}); 
0

Scriptaculous是構建在Prototype之上的UI/Widget /效果庫。你肯定會在那裏找到你要找的。

+0

其實,沒有 - Scriptaculous主要是關於效果。 – 2009-02-12 19:29:09

2

有幾個不錯的網站看看:

Prototype UI - 其中有一個模式對話框。

Scripteka - 原型附加組件的母親。這裏有很多很棒的東西。

+0

謝謝!原型UI的窗口似乎與我已經使用的「原型窗口」庫共享一些遺產。在論壇上的用戶似乎對IE6中的錯誤和緩慢的性能感到沮喪。另一方面,Scripteka看起來不錯而且簡單,這個演示在IE6中表現很好。 乾杯, 大衛 – 2009-02-12 19:34:08