05.08.2010, 02:08
|
|
Аспирант
|
|
Регистрация: 10.01.2010
Сообщений: 33
|
|
x-yuri,
Да, я в первом сообщении не упомянул (и хорошо), что вряд ли код (функция выделения фрагмента) будет где-то еще использоваться. Функция будет является частью небольшого скрипта и действовать только в его рамках.
Сообщение от x-yuri
|
В частности, использование выражений с побочными эффектами.
|
Намекаете, что у функции есть побочные эффекты? Можно поподробнее? Интересно с т. з. получения нового знания.
Сообщение от x-yuri
|
когда я вижу что происходит, а не как это реализовано
|
Глядя на ваш пример и Octane я, увы, не могу сказать что я вижу (конечно, дело во мне).
И "простоту" я упомянул зря - она не только не однозначна, но как оказалось, ситуативна .
|
|
05.08.2010, 04:17
|
|
|
|
Регистрация: 27.12.2008
Сообщений: 4,201
|
|
Сообщение от Cuprum
|
Функция будет является частью небольшого скрипта и действовать только в его рамках
|
ключевые слова "частью небольшого скрипта". Хотелось бы увидеть этот небольшой скрипт...
Сообщение от Cuprum
|
Намекаете, что у функции есть побочные эффекты? Можно поподробнее? Интересно с т. з. получения нового знания.
|
выражения с побочными эффектами - выражения, в которых не только что-то вычисляется, но и что то изменяется. В первую очередь это всякие ++, --. Согласитесь, что проще рассчитывать, что в if у меня только проверяется условие и ничего не меняется. А ведь условие может быть не таким простым. Кроме того, не понятно, зачем вашей функции глобальная переменная. Вроде как по названию складывается впечатление, что она ничего не меняет, а только возвращает. В результате ее проще (и в вашем и в моем понимании) записать так:
function getSel(){
if( window.getSelection )
return window.getSelection();
else
return document.selection.createRange().text;
}
Сообщение от Cuprum
|
Глядя на ваш пример и Octane я, увы, не могу сказать что я вижу (конечно, дело во мне).
|
ну видимо смотрите не с той стороны Я рассчитвал, что нужно сделать некий компонент "ссылка для цитирования", т.е. я встрачаю в коде
<a id="quote-link" href="#">Цитировать</a>
<script type="text/javascript">new QuoteLink('#quote-link')</script>
и вижу, что при щелчке по этой ссылке происходит копирование выделенного текста (так как не было указано куда, соответственно компонент не доделан). Т.е. я вижу, что происходит, но не вижу как это реализовано. Если мне нужно узнать, как это реализовано я смотрю исходник компонента
function QuoteLink( el ){
this._el = $(el);
$("body").mouseup( this._onMouseUp_body.bind(this) );
this._el.click( this._onClick.bind(this) );
}
QuoteLink.prototype._onMouseUp_body = function(){
this._text = $Range.stringify($Selection.getRange());
}
QuoteLink.prototype._onClick = function(){
alert(this._text);
}
и вижу, что назначаются два обработчика, что происходит в обработчиках, но не вижу реализацию назначения обработчиков, как находится выделение. Т.е. на каждом уровне у меня есть минимум необходимых деталей. В общем-то я не знаю вашей задачи, поэтому какие-то действия могут быть лишними или может быть лучший вариант организации кода, но вынесение библиотечного кода в любом случае не помешает
Кроме того, в моем случае нету никаких необоснованно глобальных переменных.
Вообще можно было еще всякие детали поубирать, вот только jQuery не предоставляет такие возможности. Хотя по задумке и не должна. Все должно быть максимально просто. Просто пишем код и пишем, и никаких дополнительных движений не делаем. Зачем разбивать код на вменяемые части? Ведь это дополнительные движения, сложно. Зачем повторное использование? Лучше мы в каждом плагине напишем то же самое. Зачем нам компоненты, если можно общаться с объектами через одну функцию ($(foo).dialog('open'))?
Сообщение от Cuprum
|
И "простоту" я упомянул зря - она не только не однозначна, но как оказалось, ситуативна
|
а в чем ситуативность?
Последний раз редактировалось x-yuri, 05.08.2010 в 04:21.
|
|
05.08.2010, 12:26
|
|
Аспирант
|
|
Регистрация: 10.01.2010
Сообщений: 33
|
|
Сообщение от x-yuri
|
ключевые слова "частью небольшого скрипта"
|
Ключевое слово - будет. Скрипт есть
, но пока работает не совсем так, и делает еще не все, что я задумал.
Сообщение от x-yuri
|
Хотелось бы увидеть этот небольшой скрипт
|
Не проблема, в конце сообщения покажу.
Сообщение от x-yuri
|
ну видимо смотрите не с той стороны
|
Согласен, в том смысле, что js я знаю плохо. Поэтому
Сообщение от x-yuri
|
Просто пишем код и пишем, и никаких дополнительных движений не делаем
|
Сообщение от x-yuri
|
а в чем ситуативность?
|
в одном случае, когда есть какие-то описательные параметры, сделать проще - сделать одним способом, если эти параметры изменились или отсутствуют, "проще" - значит по-другому.
Сам скрипт (условно назвал "просто вставить цитату" - видел на некоторых форумах, вот пытаюсь сделать что-то подобное)
// Задаем необходимые переменные
var qPanel = $('<div id="past" style="position:absolute; display:none;"><a href="" id="link">Вставить цитату в поле<a></div>');
var textarea = $('textarea');
function getSel() { // Функция возвращает текстовое выделение
if (window.getSelection) // !IE, используем метод getSelection
return window.getSelection().toString();
else // IE, используем объект selection
return document.selection.createRange().text;
}
qPanel.click(function () { // Обработчик события
textarea.val(textarea.val() + '<blockquote>' + getSel() + '</blockquote>\r\n').focus();
$(this).hide();
return false;
});
qPanel.appendTo('body');
$('body').mouseup(function(event){
var widthqPanel = qPanel.outerWidth();
if (getSel())
{
qPanel
.css({
top: event.pageY - 40,
left: event.pageX - widthqPanel/3,
display: 'block',
opacity: 0
})
.animate({
top: '-=' + 10 + 'px',
opacity: 1
}, 250);
}
});
$('body').click(function () {
if (!getSel()) qPanel.hide();
});
Последний раз редактировалось Cuprum, 05.08.2010 в 12:29.
|
|
05.08.2010, 22:17
|
|
|
|
Регистрация: 27.12.2008
Сообщений: 4,201
|
|
Сообщение от Cuprum
|
Согласен, в том смысле, что js я знаю плохо
|
не думаю я, что это не от языка зависит. Просто в некоторый языках принято все слишком упрощать, а в некоторых - слишком усложнять (ну или нельзя не усложнять)
Сообщение от Cuprum
|
в одном случае, когда есть какие-то описательные параметры, сделать проще - сделать одним способом, если эти параметры изменились или отсутствуют, "проще" - значит по-другому.
|
ну да, логично. Решение зависит от контекста. Чем проще, тем лучше. Проще зависит от контекста
я бы сделал как-то так (ошибки не исправлял, может даже новые добавил)
var QuotePanel = new Class({
initialize: function( textarea ){
this._el = textarea;
this._panel = new Element('div', {'html': '<a href="#">Вставить цитату в поле</a>'});
document.body.addEvents({
'mouseup': this._onMouseUp_body.of(this),
'click': this._onClick_body.of(this)
});
this._panel.addEvent( 'click', this._onClick_panel.of(this) );
this._panel.inject( document.body );
},
_onMouseUp_body: function( e ){
if( ! Selection.get() )
return;
var panelWidth = this._panel.getStyle('width').parseInt();
var top = e.page.y - 40;
var left = e.page.x - panelWidth/3;
this._panel
.setStyles({
'top': top,
'left': left,
'display': 'block',
'opacity': 0
})
.morph({
'opacity': 1,
'top': top-10
});
},
_onClick_body: function( e ){
if( ! Selection.get() )
this._panel.setStyle('display', '');
},
_onClick_panel: function( e ){
this._el.value += this._el.value+'<blockquote>'+Selection.get()+'</blockquote>\r\n';
this._el.focus();
this._panel.setStyle('display', '');
e.preventDefault();
}
});
|
|
06.08.2010, 00:29
|
|
Аспирант
|
|
Регистрация: 10.01.2010
Сообщений: 33
|
|
x-yuri,
Ловко вы перешли на MooTools! Там, где скрипт будет использоваться есть только jQuery, так что придется остаться на нем.
Возник вопрос - (e) это сокращенная форма записи (event)?
И еще один - долго ломал над ним голову и так и не придумал ничего путного. Хочу на панельку, всплывающую после выделения мышкой, повесить таймер - если, допустим, 3 секунды ничего не происходит (нет клика на ней и вне ее), панель исчезает. Если до истечения этих 3 секунд был клик вне панели, панель тут же исчезает (если был клик на панели, цитата вставляется в поле ответа). Может подскажите как это реализовать?
Последний раз редактировалось Cuprum, 06.08.2010 в 00:36.
|
|
06.08.2010, 00:46
|
Любитель
|
|
Регистрация: 16.12.2009
Сообщений: 422
|
|
Сообщение от Cuprum
|
(e) это сокращенная форма записи (event)?
|
event передается аргументом в функцию-обработчик.
Сообщение от Cuprum
|
повесить таймер - если, допустим, 3 секунды ничего не происходит
|
с setTimeout, setInterval знакомы ?
|
|
06.08.2010, 00:59
|
|
Аспирант
|
|
Регистрация: 10.01.2010
Сообщений: 33
|
|
Сообщение от JsLoveR
|
с setTimeout, setInterval знакомы ?
|
Шапочно знаком, но тут как-то все не однозначно - т. е. пока эти 3 секунды не истекли и панель не исчезла (функция в теле setTimeout) надо еще и следить был ли внешний клик...
|
|
06.08.2010, 01:45
|
|
|
|
Регистрация: 27.12.2008
Сообщений: 4,201
|
|
Сообщение от Cuprum
|
Ловко вы перешли на MooTools
|
на самом деле не все так грустно. Просто jQuery в лучшем случае оставляет проблемы организации кода на плечах разработчиков. В худшем провоцирует то, что мы видим в исходниках плагинов. Была тут тема недавно. Кроме того, у mootools есть builder, который позволяет взять только нужную функциональность. Кроме того есть готовые решения того, как можно добавить ООП в jQuery. Ну и помимо всего прочего для данного случая просто и свой велосипед написать
function Class( methods ){
var r = function(){
if( this.initialize )
this.initialize();
};
$.extend( r.prototype, methods );
return r;
}
String.prototype.parseInt = function(){
return parseInt(this);
};
Function.prototype.of = function( o ){
var self = this;
return function(){
return self.apply(o, arguments);
}
};
var QuotePanel = new Class({
initialize: function( textarea ){
this._el = $(textarea);
this._panel = $('<div><a href="#">Вставить цитату в поле</a></div>');
document.body.mouseup( this._onMouseUp_body.of(this) );
document.body.click( this._onClick_body.of(this) );
this._panel.click( this._onClick_panel.of(this) );
this._panel.appendTo( $('body') );
},
_onMouseUp_body: function( e ){
if( ! Selection.get() )
return;
var panelWidth = this._panel.css('width').parseInt();
this._panel
.css({
'top': e.pageY - 40,
'left': e.pageX - panelWidth/3,
'display': 'block',
'opacity': 0
})
.animate({
'opacity': 1,
'top': '-='+10+'px'
});
},
_onClick_body: function( e ){
if( ! Selection.get() )
this._panel.css('display', '');
},
_onClick_panel: function( e ){
this._el.value += this._el.value+'<blockquote>'+Selection.get()+'</blockquote>\r\n';
this._el.focus();
this._panel.css('display', '');
e.preventDefault();
}
});
да, я, кстати, подразумевал, что лишний css, который не изменяется я бы поместил в отдельный файл. Это несколько усложняет использование, но упрощает код
Сообщение от Cuprum
|
И еще один - долго ломал над ним голову и так и не придумал ничего путного
|
так совсем же просто
var QuotePanel = new Class({
_onMouseUp_body: function( e ){
...
this._panel
...
.animate(
{ ... },
{
'complete': function(){
setTimeout( function(){
this._hidePanel();
}.of(this), 3000 );
}.of(this)
});
},
_onClick_body: function( e ){
...
this._hidePanel();
},
_hidePanel: function(){
this._panel.css('display', '');
}
});
вот только зачем ее автоматически убирать? Пользователь ее и так убрать сможет, кликнув на пустом месте. Главное, чтобы она не перекрывала выделение. А вы еще говорите, что все должно быть максимально просто
Последний раз редактировалось x-yuri, 06.08.2010 в 01:47.
|
|
06.08.2010, 02:45
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
замена алерта ... как раз висит 3 секунды и удаляется по клику ...
замечания принимаются )))
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script language="JavaScript" type="text/javascript">
function position(b) {
b = typeof b == "string" ? document.getElementById(b) : b;
var a = document.documentElement,
c = document.body,
e = self.pageXOffset || a && a.scrollLeft || c && c.scrollLeft || 0;
t = self.pageYOffset || a && a.scrollTop || c && c.scrollTop || 0;
var f = b.offsetHeight,
g = b.offsetWidth,
d = document.compatMode == "CSS1Compat" && !window.opera ? a.clientWidth : c.clientWidth;
a = document.compatMode == "CSS1Compat" && !window.opera ? a.clientHeight : c.clientHeight;
if (document.compatMode == "CSS1Compat" && window.opera) {
d = window.innerWidth;
a = window.innerHeight
}
b.style.left = Math.floor(e + (d - g) / 2) + "px";
b.style.top = Math.floor(t + (a - f) / 2) + "px"
};
window.alert = function (b) {
b = b.replace(/\n/gim, "<br />");
var a = document.createElement("div");
a.style.position = "absolute";
a.style.color = "#0000FF";
a.style.backgroundColor = "#FFFACD";
a.style.border = "1px solid #000";
a.style.padding = "0px 4px";
a.innerHTML = b;
document.onmousedown = function () {
a && document.body.removeChild(a);
c && window.clearTimeout(c);
document.onmousedown = null
};
document.body.appendChild(a);
position(a);
var c = window.setTimeout(function () {a && document.body.removeChild(a);document.onmousedown = null}, 3E3)
};
</script>
</head>
<body>
<a href="#" onclick="alert('замена алерта'); return 0">кликни</a>
</body>
</html>
Последний раз редактировалось рони, 06.08.2010 в 02:51.
|
|
06.08.2010, 03:14
|
|
|
Регистрация: 10.07.2008
Сообщений: 3,873
|
|
Однобуквенные переменные
|
|
|
|