2009-06-05 15 views
17

Próbowałem utworzyć zmienny rozmiar pola tekstowego (ASP.NET multiline TextBox/HTML textarea) i używać interfejsu JQuery do zmiany rozmiaru, ale wydaje się, że działa na kilka problemów związanych z niestandardowym przeciągnięciem uchwyty.Niestandardowe uchwyty skalowalne w JQuery UI

Dokumentacja JQuery w metodzie Resizable (konkretnie w przypadku opcji handles) sugeruje, że mogę ustawić dowolny uchwyt, aby używał niestandardowego elementu HTML. Udało mi się uzyskać skalowalny textbox działający doskonale przy użyciu domyślnych uchwytów z możliwością zmiany rozmiaru, ale próba ustawienia niestandardowych (tj. Elementu HTML, który zdefiniowałem w znacznikach) tworzy następujący problem: zmienny rozmiar kontenera pozostawia odpowiednią ilość miejsca na Uchwyt div u dołu (dla uchwytu południowego), pozostawia jednak puste miejsce i pokazuje element poniżej (poza) rozmiaru pojemnika (zweryfikowanego za pomocą Firebug).

Tu jest mój znaczników (ASP.NET/XHTML) i kod JavaScript:

<asp:TextBox runat="server" ID="codeTextBox" TextMode="MultiLine" Wrap="false" Rows="15"> 
</asp:TextBox> 
<div class="resizable-s" style="width: 100%; height: 22px; background: red;"> 
</div> 

<script type="text/javascript"> 

    $(function() { 
     var codeTextBox = $("#<%= codeTextBox.ClientID %>"); 

     codeTextBox.resizable({ 
      handles: { s : $(".resizable-s") }, 
      minHeight: 80, 
      maxHeight: 400 
     }); 
    }); 

</script> 

Oczywiście, nie mogę dokonać zmienny rozmiar uchwytu div (klasa resizable-s) dzieckiem TextBox/textarea, ale nie powinno to stanowić problemu zgodnie z dokumentacją JQuery.

Sądząc z przeszukania, które zrobiłem, nie jestem jedyną osobą, która miała ten problem. (Niestety, dokumentacja JQuery nie daje przykładu użycia niestandardowych uchwytów skalowalnych, więc nie mamy pewności co do właściwego kodu.) Jeśli ktokolwiek mógłby zaproponować poprawkę do tego, lub w rzeczywistości potwierdzenie, że jest to błąd JQuery, to byłoby bardzo docenione.

Odpowiedz

24

Z kawałka kopania zrobiłem w kodzie jquery-ui, myślę, że mogę potwierdzić, że niestandardowy uchwyt poza elementem resizable nie działa.

Problem polega na tym, że zdarzenia myszy są inicjowane dla elementu resizable (lub elementu opakowania w przypadku textarea). Jeśli uchwyt nie jest dzieckiem miejsca, w którym obsługiwane są zdarzenia myszy, nie wywoła ono zdarzenia mousedown na uchwycie, nie czyniąc go przeciągalnym.

Jako dowód koncepcji, trochę poprawiłem w jquery-ui, dopóki nie uzyskałem pewnych rzeczy do wykonania. Brak gwarancji co do kodu, ale powinien on wskazywać, jakie zmiany musiałyby się zdarzyć, aby działał.

Wokół linii 140 w ui.resizable.js zmieniłem:

this._handles = $('.ui-resizable-handle', this.element) 
    .disableSelection(); 

do

this._handles = $('.ui-resizable-handle') 
    .disableSelection(); 

Potem dodaje następujący kod (część mouseInit z ui.core.js, prawdopodobnie powinien wykorzystanie całej funkcji) w ui.resizable.js (wokół linii 180) po mouseInit wywołano dla elementu resizable:

... 
    //Initialize the mouse interaction 
    this._mouseInit(); 

    // Add mouse events for the handles as well - ylebre 
    for (i in this.handles) { 
     $(this.handles[i]).bind('mousedown.resizable', function(event) { 
     return self._mouseDown(event); 
     }); 
    } 

Umożliwia to wykonanie uchwytu zmiany rozmiaru, który nie jest elementem podrzędnym elementu skalowalnego. Mój uchwyt to div z id "south" i jest dołączony do elementu resizable. Oto snippit HTML:

<textarea id="resizable" class="ui-widget-content"> 
    <h3 class="ui-widget-header">Resizable</h3> 
</textarea> 
<div id="south" class="ui-resizable-handle">south</div> 

I kod javascript:

$("#resizable").resizable(
     {handles: {s: document.getElementById("south")}} 
    ); 

Nadzieja to pomaga!

+0

Dzięki za zbadanie tego. Nie spodziewałem się, że hack naprawi pliki JS, ale byłoby wspaniale mieć je! Niestety, próbowałem wprowadzić zmiany, ale bez powodzenia. "Południe" div pojawia się jako bardzo mały tekst i wcale nie zachowuje się jak uchwyt (ustawienie "font-size: 100%;" sprawia, że ​​tekst jest wyraźnie widoczny, ale nie więcej). Być może są jakieś inne zmiany, które wprowadziłeś? – Noldorin

+0

Zupełnie dobrze, przegapiłem jedną linię, którą wtrąciłem. W moich testach umieściłem wysokość/szerokość/kolor tła w CSS dla południowego div, co ułatwia znalezienie uchwytu. Tylko przy wielkości czcionki 100% działa, więc nie dodałem reguł CSS do analizy. – ylebre

+0

Dziwne ... Ciągle nie otrzymuję wyników, a dwukrotnie sprawdziłem, czy mój kod pasuje do tego, co wysłałeś w identyczny sposób. Jakieś pomysły? Czy w ogóle możliwe byłoby przesłanie strony testowej i zmodyfikowanego pliku ui.resizable.js? – Noldorin

3

Tak, wygląda mi na błąd. Oto pełna próbka, dla tych, którzy próbują lokalnie:

<!DOCTYPE html> 
<html> 
<head> 
    <link rel="stylesheet" href="http://jqueryui.com/latest/themes/base/ui.all.css" type="text/css"/> 
    <script src="http://jquery-ui.googlecode.com/svn/tags/latest/jquery-1.3.2.js" type="text/javascript"></script> 
    <script src="http://jquery-ui.googlecode.com/svn/tags/latest/ui/ui.core.js" type="text/javascript"></script> 
    <script src="http://jquery-ui.googlecode.com/svn/tags/latest/ui/ui.resizable.js" type="text/javascript"></script> 
    <style type="text/css"> 
    #resizable { width: 100px; height: 100px; background: silver; } 
    #southgrip { width: 100px; height: 10px; background-color: blue; } 
    </style> 
    <script type="text/javascript"> 
    $(function() { 
     $('#resizable').resizable({ 
     handles: { 's': $('#southgrip') }, 
     minHeight: 80, 
     maxHeight: 400 
     }); 
    }); 
    </script> 
</head> 
<body> 

<div id="resizable"></div> 
<div id="southgrip"></div> 

</body> 
</html> 

This jQuery UI bugmoże być spokrewnieni.

Inne rzeczy próbowałem:

  • Wymienić „ostatni” z „1.6” i „jQuery 1.3.2” „z jQuery 1.2.6” spróbować ze starszą wersją jQuery UI, aby zobaczyć jeśli to regresja. Nie wygląda na to.
  • Dodaj ui-resizable-s i/lub ui-resizable-handle Klasy CSS do #southgrip. Nie ma kości. Jednak, jeśli #southgrip jest wewnątrz #resizable, to działa. Ale to nie rozwiązuje twojego problemu.
  • Używanie { 's': $('#southgrip').get(0) } dla opcji handles. Nie ma kości.
+1

BTW, gdy jesteś na zastanawianie się, dlaczego jQuery UI nie działa, może chcesz aby po prostu użyć wersji Resizable 'textarea' biblioteki interfejsów: http://interface.eyecon.ro/demos/resize_textarea.html –

+0

Dzięki za odpowiedź ... Rzeczywiście wygląda na to, że jest to błąd. Jeśli nie uda mi się uzyskać rozwiązania ylebre w hackowaniu (rozwiązanie jQueryUI jest nadal nieco preferowane), zdecydowanie skorzystam z biblioteki Interface, ponieważ wydaje mi się, że właśnie tego chcę. – Noldorin

+0

Nie sugerowałbym używania opublikowanej przeze mnie wersji hacked - jest to raczej dowód, że faktycznie istnieje problem z kodem jquery-ui, i w jakim kierunku można wytworzyć rozwiązanie. Nie polecałabym, aby ten kod był wszędzie gotowy do produkcji :) – ylebre

0

Miałem ten sam problem 4 lata później. Nigdy tego nie naprawili. Chociaż korzystałem z interfejsu, ale nie miałem żadnych aktualizacji od 2007 roku. Postanowiłem więc samemu naprawić błąd i poprosić o wciągnięcie projektu jQuery UI do Github. https://github.com/jquery/jquery-ui/pull/1134 Mam nadzieję, że zaakceptują to i wkrótce się połączą. Dodałem test, więc jestem pewien, że zadziała w każdym przypadku, ponieważ wszystkie testy resizable z Jquery UI działa z tą modyfikacją.

Zacząłem używać kodu ylebre, ale to nie zadziałało. Wprowadziłem więc kilka drobnych zmian.

0

W końcu znalazłem niezwykle skuteczne rozwiązanie po wielu godzinach próbowania przełamania tego irytującego błędu. Po prostu dołącz element handle w klasie Ui. Poniższa funkcja została przetestowana i działa dobrze z uchwytami południowymi i zachodnimi. Mam nadzieję, że pomaga!

function resizables(element, handle, type){ 

var height = handle.height(); 
var place = type =="s"? "bottom":"top"; 
var css = {}; 
     css["height"] = height+"px"; 
     css[place] = -height+"px"; 


element.resizable({handles: type}); 
var jqclass = element.find(".ui-resizable-"+type); 

     handle.css({"cursor": type+"-resize"}); 
     jqclass.append(handle); 
     jqclass.css(css); 
} 

Kiedy wywołasz funkcję jak poniżej, twój niestandardowy uchwyt zostanie umieszczony we właściwym miejscu i prawdopodobnie zadziała. PS: funkcja działa z uchwytami "n" i "s".

resizables($("#draggable"), $("#handle"), 's'); 
-1

miałem podobny problem, ale moja potrzeba było ustawić hadlers dynamicznie do wielu elementów:

  $.each($(".imagecontainer"),function() { 
       $(this).resizable({ 
        handles: {se: $(this).closest(".spaciator").find(".ui-resizable-se")} 
       }); 
      };