окей, а как вот такой вариант:
// When a generated page (in PHP, Perl or something else)
// need add to each post (DIV, TABLE, TR, TD): onmouseover="qq.Nick='user nick'"
// Exsample for PHP: echo '<tr class="bugnote" id="'.$postId.'" onmouseover="qq.Nick=\''.$userNick.'\'">';
var qq = {
// QuickQuote Settings
LinkShowTime : 3000,
LinkId : 'quickQuote',
LinkStyle : 'z-index:1000; cursor:pointer; position:absolute; visibility:hidden',
LinkText : '<b>Цитировать</b>',
TextAreaId : 'bugnote_text', // id or name
// <--------------------
Link : '', TextArea : '', Text : '', Nick : '', TimerId : '',
Install : function(){
document.write( '<div onmousedown="qq.InsertText()" onmouseout="qq.TimerStart()" onmouseover="qq.TimerStop()" \
class="button" id="'+qq.LinkId+'" style="'+qq.LinkStyle+'">'+qq.LinkText+'</div>');
qq.Link = document.getElementById(qq.LinkId);
document.onclick = qq.GetSelText;
document.onmouseup = qq.LinkShow;
},
TimerStart : function(){ qq.TimerStop(); qq.TimerId = setTimeout(qq.LinkHide, qq.LinkShowTime); },
TimerStop : function(){ clearTimeout(qq.TimerId); },
LinkHide : function(){ qq.Link.style.visibility = 'hidden'; },
LinkShow : function(event){
qq.GetSelText();
if (qq.Text == '') return;
var mc = event || window.event;
if (mc.pageX || mc.pageY){
mc.X = mc.pageX;
mc.Y = mc.pageY;
}else if (mc.clientX || mc.clientY){
mc.X = mc.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
mc.Y = mc.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
qq.Link.style.left = (mc.X-35)+'px';
qq.Link.style.top = (mc.Y+11)+'px';
qq.Link.style.visibility = 'visible';
qq.TimerStart();
},
GetSelText : function(){
qq.Text = getSelText();
qq.Text.replace(/(\r?\n\s*){2,}/gi,'\r\n').replace(/^\s+|\s+$/gi,'').replace(/(\ |\t)+/gi,' ');
if (qq.Text == '') qq.LinkHide();
},
InsertText : function(){
qq.LinkHide();
if (qq.TextArea == '' || qq.TextArea == null){
qq.TextArea = document.getElementById(qq.TextAreaId);
if (qq.TextArea == null) qq.TextArea = document.getElementsByName(qq.TextAreaId)[0];
}
if (qq.TextArea == null) return;
if (navigator.appName == 'Opera') qq.Text = '[q]'+qq.Nick+': ' + qq.Text + '[/q]\r\n';
else qq.Text = '[q]'+qq.Nick+': ' + qq.Text + '[/q]\n';
insertText(qq.TextArea, qq.Text);
}
};
// Common functions
function saveCaretPos(event){
event = event || window.event;
var obj = event.target || event.srcElement;
if (typeof(document.selection) != 'undefined' && typeof(document.selection.createRange) != 'undefined')
obj.caretPos = document.selection.createRange().duplicate();
}
function getSelText(){
if (window.getSelection && !window.opera) var selText = window.getSelection(); // ff
else if (document.getSelection) var selText = document.getSelection(); // opera
else if (document.selection) var selText = document.selection.createRange().text; // ie
if (!selText) selText = '';
return selText.toString();
}
function insertText(obj, text){
var scrollTop, scrollLeft;
if (obj.type == 'TEXTAREA' && obj.scrollTop){
scrollTop = obj.scrollTop;
scrollLeft = obj.scrollLeft;
}
if (window.getSelection || document.getSelection) var caretPos = obj.selectionStart + text.length;
if (obj && obj.caretPos)
obj.caretPos.text = text;
else if (obj && obj.selectionStart+1 && obj.selectionEnd+1)
obj.value = obj.value.substring(0, obj.selectionStart) + text + obj.value.substring(obj.selectionEnd, obj.value.length);
else if (obj)
obj.value += text;
if (window.getSelection || document.getSelection) obj.setSelectionRange(caretPos, caretPos);
if (typeof scrollTop != 'undefined'){
textObj.scrollTop = scrollTop;
textObj.scrollLeft = scrollLeft;
}
}
// <--------------------
// Install QuickQuote
qq.Install();
document.body.onload = function(){
qq.TextArea = document.getElementById(qq.TextAreaId);
if (qq.TextArea == null) qq.TextArea = document.getElementsByName(qq.TextAreaId)[0];
if (qq.TextArea == null) return;
qq.TextArea.onselect = saveCaretPos;
qq.TextArea.onclick = saveCaretPos;
qq.TextArea.onkeyup = saveCaretPos;
}
// <--------------------
Осталось только разобраться с прокруткой в textarea.
Demo страница