Плагин для выбора стиля текстового редактора jQuery?
-
23-09-2019 - |
Вопрос
Чего я пытаюсь достичь, так это использовать jQuery для имитации поведения функции выделения текста, которую вы видите в обычном текстовом редакторе, за исключением того, что вместо выделения текста я хочу выделить несколько строк <div>
s.Однако пока единственные плагины "выбора", которые я нашел для jQuery, работают на основе прямоугольной модели лассо.В частности, я использую выбираемый плагин jQueryUI.Чтобы понять, о чем я говорю, рассмотрите следующие 2 изображения:
Поведение плагина jQueryUI по умолчанию "выбирается"
Идеальное поведение плагина (без лассо) http://img709.imageshack.us/img709/5664/selectableidealthumb.png
Вы также можете пойти здесь чтобы поиграть с этим точным примером.Кто-нибудь знает о плагине, который достигает этого?Это избавило бы меня от необходимости взламывать этот плагин, чтобы получить то, что я хочу...
П/С:В моем приложении каждая строка будет содержать до 150 или около того разделов, и в каждом div будет несколько разделов.Я пробовал вручную прокручивать свой собственный выбор, но это было медленно, даже когда имел дело всего с одной строкой.В настоящее время я использую этот плагин, потому что он гораздо более производителен, чем то, что я написал.
Решение
Возможно, у вас уже есть свой собственный скрипт для этого, но я сильно оптимизировал и улучшил свой.Он добавляет или удаляет классы только тогда, когда это необходимо, что отлично подходит для повышения производительности.
Также в нем есть некоторые методы, которые могут быть полезны:
var sR = $('#selectable').selectableRange({
/* Alternatively, you could overwrite default options
classname: 'active',
log: false,
logElement: $('#log'),
nodename: 'LI'*/
});
// Initialize the selectable so it works
sR.init();
// You can always change options like this:
$('#logOnOff').click(function(){
// Toggle log
sR.options.log = (sR.options.log) ? false : true;
});
// Also you can use this methods:
// sR.deselect()
// sR.destroy()
// sR.getSelectedItems()
Дайте ему попробовать, код является также доступно.
Другие советы
Возможно, это можно было бы как-то оптимизировать, и все же я тестировал это только в Chrome, но я думаю, что это будет работать и в других браузерах.Для этого не нужен пользовательский интерфейс jQuery, он сделан вручную ;)
$(function() {
var selectableLi = $('#selectable li');
selectableLi.mousedown(function(){
var startIndex, endIndex, mouseUpOnLi = false;
// When dragging starts, remove classes active and hover
selectableLi.removeClass('active hover');
// Give the element where dragging starts a class
$(this).addClass('active');
// Save the start index
startIndex = $(this).index();
// Bind mouse up event
selectableLi.bind('mouseup', function(){
// Mouse up is on a li-element
mouseUpOnLi = true;
$(this).addClass('active');
// Remove the events for mouseup, mouseover and mouseout
selectableLi.unbind('mouseup mouseover mouseout');
// Store the end index
endIndex = $(this).index();
// Swap values if endIndex < startindex
if(endIndex < startIndex){
var tmp = startIndex;
startIndex = endIndex;
endIndex = tmp;
}
// Give the selected elements a colour
for(i=startIndex; i<=endIndex; i++){
$(selectableLi[i]).addClass('active');
}
}).bind('mouseover', function(){
// Give elements a hover class when hovering
$(this).addClass('hover');
}).bind('mouseout', function(){
// Remove the hover class when mouse moves out the li
$(this).removeClass('hover');
});
$(document).bind('mouseup', function(e){
// When mouse up is outside a li-element
if(!mouseUpOnLi){
selectableLi.removeClass('active');
}
$(this).unbind('mouseup');
});
}).attr("unselectable","on").css("MozUserSelect","none").bind("selectstart",function(){return false});
});
У меня есть пример онлайн.Обратите внимание, что элементы не имеют цвета фона при выборе;Я думаю, что это даст лучшую производительность.
Обновить - Пример 2
Я обновил его, чтобы выделение было видно при выборе:
var selectableLi;
function colourSelected(a, b, Class){
selectableLi.removeClass(Class);
// Swap values if a > b
if(a > b){
var tmp = a;
a = b;
b = tmp;
}
// Give the selected elements a colour
for(i=a; i<=b; i++){
$(selectableLi[i]).addClass(Class);
}
}
$(function() {
selectableLi = $('#selectable li');
selectableLi.mousedown(function(){
var startIndex, endIndex, mouseUpOnLi = false;
// When dragging starts, remove classes active and hover
selectableLi.removeClass('active hover');
// Give the element where dragging starts a class
$(this).addClass('active');
// Save the start index
startIndex = $(this).index();
// Bind mouse up event
selectableLi.bind('mouseup', function(){
// Mouse up is on a li-element
mouseUpOnLi = true;
$(this).addClass('active');
// Remove the events for mouseup, mouseover and mouseout
selectableLi.unbind('mouseup mouseover mouseout');
colourSelected(startIndex, $(this).index(), 'active');
}).bind('mouseover mouseout', function(){
// Give elements a hover class when hovering
colourSelected(startIndex, $(this).index(), 'hover');
});
$(document).bind('mouseup', function(e){
// When mouse up is outside a li-element
if(!mouseUpOnLi){
selectableLi.removeClass('active hover');
}
$(this).unbind('mouseup');
selectableLi.unbind('mouseover mouseout');
});
}).attr("unselectable","on").css("MozUserSelect","none").bind("selectstart",function(){return false});
});
Опять же, возможно, этот код можно было бы как-то оптимизировать для повышения производительности.
Я бы создал свою собственную версию, используя функции jQuery.
Прежде всего, настройте событие для "stop:" (возможно, как сериализовать http://jqueryui.com/demos/selectable/#serialize)
Затем взгляните, какие идентификаторы я получил обратно, самый низкий и самый высокий дали бы мне достаточно для простого цикла "для ... следующего" по оставшимся объектам.
Я знаю, что это решение для исправления / взлома, но, с моей точки зрения, это, кажется, решает проблему, полезно ли это для вас или вам тоже нужен код?Просто хотел сначала изложить алгоритмическую мысль.:o)