Question

Ce que je suis en train d'atteindre est d'utiliser jQuery pour imiter le comportement de la fonctionnalité de sélection de texte que vous voyez dans un éditeur de texte typique, sauf au lieu de sélectionner le texte, je veux sélectionner plusieurs lignes de <div>s. Cependant, jusqu'à présent, les seuls plug-ins « sélection » Je l'ai trouvé pour jQuery fonctionnent sur la base d'un modèle rectangulaire Lasso. En particulier, j'utilise le plugin sélectionnable jQueryUI. Pour voir ce dont je parle, considérez les 2 images suivantes:

Par défaut jQueryUI comportement plugin "sélectionnable"

Idéal comportement du plugin (sans le lasso) http://img709.imageshack.us/img709/5664/selectableidealthumb.png

Vous pouvez aussi aller ici pour jouer avec cet exemple précis. Quelqu'un sait-il d'un plug-in qui permet d'atteindre cela? Cela me sauver de procéder à pirater ou pirater autour de ce plugin pour obtenir ce que je veux ...

P / S: Dans mon application chaque ligne contiendra jusqu'à quelque 150 divs, et chaque div aura quelques divs en son sein. J'ai essayé main rouler ma propre sélectionnable, mais il était lent même face à une seule ligne. J'utilise actuellement ce plugin parce que son beaucoup plus performant que ce que j'écrit.

Était-ce utile?

La solution

Peut-être vous avez déjà votre propre script pour cela, mais j'optimized et le mien beaucoup amélioré. Il ajoute ou supprime des classes uniquement en cas de besoin, ce qui est excellent pour la performance.

En outre, il a des méthodes qui peuvent être utiles:

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()

Lui donner un essai , le code également availabe .

Autres conseils

Peut-être que cela pourrait être optimisé en quelque sorte et pourtant je l'ai testé que dans Chrome, mais je pense que cela va fonctionner dans d'autres navigateurs aussi. Il n'y a pas besoin de jQuery UI pour cela, il est fait à la main;)

$(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});
});

J'ai exemple en ligne . Notez que les éléments ne sont pas une couleur d'arrière-plan lors de la sélection; Je pense que cela donnera une meilleure performance.


NOUVELLES - Exemple 2

Je mis à jour si la sélection est visible lors de la sélection:

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});
});

Encore une fois, peut-être ce code pourrait être optimisé pour des performances en quelque sorte.

Je voudrais faire ma propre version en utilisant les fonctionnalités jQuery.

Tout d'abord, l'interface de l'événement pour "arrêt" (peut-être comme serialize http: // jqueryui.com/demos/selectable/#serialize )

Alors jetez un oeil à ce qui les ID je suis revenu, le plus bas et le plus élevé me donnerait assez pour une simple boucle « pour ... suivant » à travers les objets restants.

Je sais que une solution / solution hack, mais qui semble résoudre le problème de mon point de vue, est-il utile pour vous ou avez-vous besoin le code aussi? Je voulais juste donner la pensée algoritmic premier. : O)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top