문제

What I'm trying to achieve is to use jQuery to mimic the behavior of the text-selection functionality you see in a typical text-editor, except instead of selecting text, I want to select multiple rows of <div>s. However, so far the only "selection" plugins I've found for jQuery operate based on a rectangular lasso model. In particular, I'm using the jQueryUI selectable plugin. To see what I'm talking about, consider the following 2 images:

Default jQueryUI "selectable" plugin behavior

Ideal plugin behavior (sans the lasso) http://img709.imageshack.us/img709/5664/selectableidealthumb.png

You can also go here to play with this exact example. Does anybody know of a plugin that achieves this? That would save me from proceeding to hack or hack around this plugin to get what I want...

P/S: In my app each row will contain up to 150 or so divs, and each div will have a few divs within it. I have tried hand-rolling my own selectable but it was slow even when dealing with just a single line. I'm currently using this plugin because its much more performant than what I wrote.

도움이 되었습니까?

해결책

3 단계에서 건너 뛴 DNS 재료를해야합니다!DNS에 앱 도메인을 조회 레코드를 제공하는 단계입니다. 따라서 컴퓨터 이름을 URL로 번역합니다.

다른 팁

Maybe this could be optimized somehow and yet I have tested it in Chrome only, but I think it will work in other browsers too. There is no need of jQuery UI for this, it's hand made ;)

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

I've got an example online. Note that items don't have a background colour when selecting; I think this will give a better performance.


UPDATE - Example 2

I updated it so the selection is visible while selecting:

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

Again, maybe this code could be optimized somehow for performance.

I would make my own version using the jQuery features.

First of all, interface the event for "stop:" (perhaps like serialize http://jqueryui.com/demos/selectable/#serialize)

Then have a look at which ID's I got back, lowest and highest would give me enough for a simple "for...next" loop through the remaining objects.

I know its a fix/hack solution, but that seems to solve the problem from my point of view, is it usefull for you or do you need the code too? Just wanted to provide with the algoritmic thought first. :o)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top