mmofacts.com

[Snippet]Scrollbar für Chatfenster

gepostet vor 17 Jahre von KoMtuR
So da die Snippetdatenbank immernoch nicht geht (entweder ist mein Rechner scheisse oder ich es stimmt noch was mit der Config nicht) mach ichs mal hier direkt.
Hab ein kleines Javascript gebastelt, welches euch, wenn ihr Prototype 1.6.0 + Scrip.aculo.us 1.8.0 sowieso nutzt, den Scrollbalken vom Chat bieten kann.
Jeder kennt sicherlich das Problem, dass wenn man mittels Ajax in einem Chatfenster neue Nachrichten anhängt, dass der Text entweder nicht mitscrollt oder wenn es einen "Autoscroll" gibt, dieser manchmal beim Lesen stört, da der Text wieder weiterscrollt.
Hab nun bei Travianer gesehen, dass sie es mittels Checkbox gelöst haben. Bin vielleicht ein wenig verwöhnt, also musste ich mir was eigenes basteln.
Wenn der Scrollbalken auf Maximum ist (also bei vertikalen Scrollbalken ganz unten), dann wird automatisch mitgescrollt. Sonst bleibt der Chat stehen und man kann in Ruhe lesen.
Benutzt wird das Ding wie auf wiki.script.aculo.us/scriptaculous/show/Slider erklärt.
Hier mal die Verwendung an einem vertikalen Slider.
Definition des Scrollhandlers:

NewSlider = Class.create(Control.Slider, {
setRange : function(range) {
this.range = range;
},
getValue : function() {
return this.value;
}
});
ChatScrollObserver = Class.create({
initialize: function(handle, trackHandle, chatHandle) {
this.trackHandle = $(trackHandle);
this.sliderHandle = $(handle);
this.chatWindow = $(chatHandle);
var options = Object.extend({
autoscroll : true,
axis: 'horizontal',
sliderValue: 0,
disabled : true,
onSlide : this.updateChatWindow.bindAsEventListener(this)
}, arguments[3] || {});
this.axis = options.axis;
this.autoscroll = options.autoscroll;
this.slider = new NewSlider(handle,trackHandle,options);
this.updateFunction = this.handle.bindAsEventListener(this);
this.chatWindow.observe('chat:newLine', this.updateFunction);
//this.setNewHandleSize();
},

dispose: function() {
Event.stopObserving(this.chatWindow, 'chat:newLine', this.updateFunction);
},
handle : function(evt) {
var scrollMax = 0, windowDimension = 0;

if(this.axis == 'horizontal') {
scrollMax = this.chatWindow.scrollWidth;
windowDimension = this.chatWindow.getWidth();
} else {
scrollMax = this.chatWindow.scrollHeight;
windowDimension = this.chatWindow.getHeight();
}

if((scrollMax - windowDimension) > 0) {
this.slider.setEnabled();
this.slider.setRange($R(0, scrollMax - windowDimension));
if(this.autoscroll == true) {
if(this.axis == 'vertical') {
this.chatWindow.scrollTop = scrollMax - windowDimension;
this.slider.setValue(this.chatWindow.scrollTop);
}
} else
this.slider.setValue(this.slider.getValue());
}
},
updateChatWindow: function(value) {
if(this.axis == 'horizontal') {
this.chatWindow.scrollLeft = value;
} else {
this.chatWindow.scrollTop = value;
if((this.chatWindow.scrollHeight - this.chatWindow.getHeight() - value) == 0)
this.autoscroll = true;
else
this.autoscroll = false;
}
}
/*
Funktion für die Slideraktualisierung einbauen, damit der entsprechend die Größe verändert

setNewHandleSize: function() {

}*/
});
Html:









Und so erstellt ihr den Handler+Slider:

new ChatScrollObserver('chatvscrollbarhandle', 'chatvscrollbar', 'divchat', {axis: 'vertical', sliderValue: 1});
new ChatScrollObserver('chathscrollbarhandle', 'chathscrollbar', 'divchat');
"divchat" ist bei mir zb. die Id des Divs, wo der Chat drin ablaufen soll. Dieses Div sollte den Style overflow:hidden haben.
Wichtig ist auch, dass ihr das Event "chat:newLine" feuert, da sonst der Handler nicht mitbekommt, wann denn einen neue Nachricht im Chat hinzugefügt wird. (feuern von Events kam mit Prototype 1.6.0)
Ich hab das so gemacht:

$("divchat").appendChild(ul).fire("chat:newLine");
Bei Gelegenheit sollte man vielleicht noch eine Funktion schreiben, die das Handle-Div entsprechend verkleinert, umso größer die Range von der Scrollbar wird.
Ich hoffe es ist hilfreich.
Ps.: Getestet in IE7, Opera keine Ahnung (der neuste), FF2.0.0.9, WebKit-r27716
edit:
Code ein wenig verkleinert und die Klasse umgenannt

Auf diese Diskussion antworten