02.07.2009, 17:44
|
Кандидат Javascript-наук
|
|
Регистрация: 04.05.2009
Сообщений: 105
|
|
[Решено 2 из 3] Как сделать цитирование?
Доброго времени суток, подскажите, пожалуйста, в двух словах, в каком направление «копать» …
Задача: При выделение любого текста на сайте - необходимо, что бы появлялась ссылка, чуть ниже курсора мыши, с текстом «цитировать». Действие ссылки – скопировать выделенный текст и вставить в textarea в позицию каретки.
1. Подскажите, как «отловить», что был выделен текст.
2. Скопировать выделенный текст.
3. Как узнать позицию каретки в textarea.
cсоответственно, под IE 6-8, Opera, FF
Рабочий вариант на функциях:
Скачать / Пример
// 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
TextBefore : '[q\nick]', // \nick - will be replaced by qq. Nick
TextAfter : '[/q]',
// <--------------------
Link : '', TextArea : '', Text : '', Nick : 'e', 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);
if (navigator.appName == 'Opera') qq.TextAfter += '\r\n';
else qq.TextAfter += '\n';
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(event);
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(event){
event = event || window.event;
var targ = event.target || event.srcElement;
if ( targ && targ.tagName == 'TEXTAREA' || targ.tagName == 'A' || targ.tagName == 'IMG' ||
(targ.tagName == 'INPUT' || targ.type == 'TEXT' || targ.type == 'PASSWORD')) return qq.LinkHide();
qq.Text = getSelText();
qq.Text = qq.Text.replace(/(\r?\n\s*){2,}/gi,'\r\n').replace(/^\s+|\s+$/gi,'').replace(/(\ |\t)+/gi,' ');
if (qq.Text == '') return 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;
insertText( qq.TextArea, qq.TextBefore.replace(/\nick/gi, (qq.Nick ? '='+qq.Nick : ''))
+ qq.Text + qq.TextAfter.replace( /\nick/gi, (qq.Nick ? '='+qq.Nick : '')));
qq.Nick = '';
}
};
// 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 = obj.scrollTop;
var 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);
obj.scrollTop = scrollTop;
obj.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;
}
// <--------------------
Последний раз редактировалось `p r o x y, 12.07.2009 в 01:02.
|
|
02.07.2009, 17:51
|
|
|
Регистрация: 10.07.2008
Сообщений: 3,873
|
|
Большинство ответов на ваши вопросы здесь: Range, TextRange и Selection.
По событию mouseup документа, получаете объект-выделение (selection), проверяет схлопнуто (collapsed) ли оно, если нет, то создаете ссылку для помещения выделенного текст в textarea.
Для получения координат события mouseup прочитайте Свойства объекта событие: Координаты мыши
Последний раз редактировалось Octane, 02.07.2009 в 17:55.
|
|
02.07.2009, 18:03
|
Кандидат Javascript-наук
|
|
Регистрация: 04.05.2009
Сообщений: 105
|
|
Octane, благодарю, полезная и понятная информация.
|
|
02.07.2009, 18:13
|
|
|
Регистрация: 10.07.2008
Сообщений: 3,873
|
|
Только такие штуки раздражают, когда хочется просто скопировать выделенный участок текста, а тут тебе какие-то меню всплывать начинают.
|
|
02.07.2009, 18:24
|
Кандидат Javascript-наук
|
|
Регистрация: 04.05.2009
Сообщений: 105
|
|
Octane,
ни капли - наоборот - ооооочень помогают, форумы где используют: forum.oszone.net / forum.ru-board.com - после выделения, одна единственная ссылка "цитировать", на 2 сек, далее исчезает.
Имхо, очень удобно.
Вот теперь к Мантису хочу прикрутить такое еже ..
|
|
03.07.2009, 23:03
|
Кандидат Javascript-наук
|
|
Регистрация: 04.05.2009
Сообщений: 105
|
|
Часть решения:
var divQuote = document.write('<div onmousedown="oQuote.past()" class="button" id="quote_div" style="z-index:1000;cursor:pointer;position:absolute;visibility:hidden;"><b>Цитировать</b></div>');
var divQuote = document.getElementById('quote_div');
window.onload = function(){
//document.onselect = quickQuote;
//document.onclick = quickQuote;
document.onkeyup = quickQuote;
document.onmouseup = quickQuote;
var oQuote = new quickQuote();
}
function quickQuote(e){
var selText = '';
if (window.getSelection && !window.opera) selText = window.getSelection();
else if (document.getSelection) selText = document.getSelection();
else if (document.selection) selText = document.selection.createRange().text;
this.selText2 = selText;
selText.toString().replace(/(\r?\n\s*){2,}/gi,'\r\n').replace(/^\s+|\s+$/gi,'').replace(/(\ |\t)+/gi,' ');
if(!selText) return
var e = e || window.event;
if (e.pageX == null && e.clientX != null){
var html = document.documentElement;
var body = document.body;
e.pageX = e.clientX + (html && html.scrollLeft || body && body.scrollLeft || 0) - (html.clientLeft || 0);
e.pageY = e.clientY + (html && html.scrollTop || body && body.scrollTop || 0) - (html.clientTop || 0);
}
divQuote.style.left = (e.pageX-80)+'px';
divQuote.style.top = (e.pageY+11)+'px';
divQuote.style.visibility = 'visible';
//divQuote.innerText = selText;
this.past = function(){
alert(selText);
}
}
Есть вопрос: Как работать с объектами Javascript?
вот это прочитал, не осилил.
В данном случае у меня происходит:
1. Появляется ссылка, после выделения любого текста на старнице.
2. При нажатие на ссылку - необходимо вызвать функцию, которая продеманстрирует выделенный текст, который содержится в переменной selText.
Как это сделать с помощью объектов, а не банальной передачей выделенного текста в функцию?
А такой вриант:
if(!selText) return
не вызовет ошибку? Т.е. всегда будет выполняться верно?
Этим хотел проверить, есть ли текст в этой переменной, и нет ли ошибок получения выделенного текст (undefined).
Последний раз редактировалось `p r o x y, 03.07.2009 в 23:24.
|
|
04.07.2009, 01:21
|
Кандидат Javascript-наук
|
|
Регистрация: 04.05.2009
Сообщений: 105
|
|
нарыл более подробный материал с примерами, изучаю...
|
|
04.07.2009, 02:21
|
|
|
|
Регистрация: 27.12.2008
Сообщений: 4,201
|
|
объекты хочешь использовать потому что модно?
Сообщение от `p r o x y
|
А такой вриант:
if(!selText) return
не вызовет ошибку? Т.е. всегда будет выполняться верно?
|
а какие значения может принимать эта переменная?
|
|
04.07.2009, 02:30
|
Кандидат Javascript-наук
|
|
Регистрация: 04.05.2009
Сообщений: 105
|
|
x-yuri,
1. потому, что не умею ))
2. потому что, скрипт цитирования, который выковырял с форума на объектах работает, и работает он хорошо - вот и стараюсь равняться на лучшее. Но, мало что понимаю в том скрипте, вот и пишу сам, почти все с нуля.
Не пойму, почему тут ошибка:
function quickQuote(){
document.write('<div onmousedown="quickQuote.showSelText()" class="button" id="divQuickQuote" style="z-index:1000;cursor:pointer;position:absolute;visibility:hidden"><b>Цитировать</b></div>');
var selText = '';
this.getSelText = function(){
selText = '';
if (window.getSelection && !window.opera) selText = window.getSelection();
else if (document.getSelection) selText = document.getSelection();
else if (document.selection) selText = document.selection.createRange().text;
selText.toString().replace(/(\r?\n\s*){2,}/gi,'\r\n').replace(/^\s+|\s+$/gi,'').replace(/(\ |\t)+/gi,' ');
if(!selText) return;
this.showSelText();
};
/*this.getMouseCord = function(e){
var e = e || window.event;
if (e.pageX == null && e.clientX != null){
var html = document.documentElement;
var body = document.body;
e.X = e.clientX + (html && html.scrollLeft || body && body.scrollLeft || 0) - (html.clientLeft || 0);
e.Y = e.clientY + (html && html.scrollTop || body && body.scrollTop || 0) - (html.clientTop || 0);
}
return e;
};
this.showLink = function(e){
var divQuote = document.getElementById('divQuickQuote');
divQuote.style.left = (e.X-35)+'px';
divQuote.style.top = (e.Y+11)+'px';
divQuote.style.visibility = 'visible';
//divQuote.innerText = selText;
};*/
this.showSelText = function(){
alert('= '+selText);
};
}
var oQuote = new quickQuote();
window.onload = function(){
//document.onselect = quickQuote;
//document.onclick = quickQuote;
document.onkeyup = oQuote.getSelText();
document.onmouseup = oQuote.getSelText();
}
это решил, правильно использовать вот так:
document.onkeyup = oQuote.getSelText;
document.onmouseup = oQuote.getSelText;
Последний раз редактировалось `p r o x y, 04.07.2009 в 03:43.
|
|
04.07.2009, 02:35
|
Кандидат Javascript-наук
|
|
Регистрация: 04.05.2009
Сообщений: 105
|
|
Цитата:
|
а какие значения может принимать эта переменная?
|
ну по коду должно быть видно, эта переменная принимает:
- либо выделенный текст
- либо ошибки, при попытки определить выделенный текст
Сначала написал так:
if (selText == '' || selText == 'undefined') return;
но потом сократил на то, что выше.
|
|
|
|