Пользовательские изменяемые размеры в JQuery UI - PullRequest
17 голосов
/ 06 июня 2009

Я пытался создать текстовое поле с изменяемым размером (многострочное ASP.NET TextBox / HTML textarea) и использовать пользовательский интерфейс JQuery, чтобы сделать его изменяемым, но, похоже, возникают некоторые проблемы, связанные с пользовательскими маркерами перетаскивания.

Документация JQuery по методу Resizable (в частности, по опции handles) предполагает, что я могу установить любой из дескрипторов для использования пользовательского элемента HTML. Мне удалось заставить текстовое поле изменяемого размера работать отлично, используя стандартные ручки изменения размера, но при попытке установить пользовательские (т.е. HTML-элемент, который я определил в разметке) возникает следующая проблема: контейнер изменяемого размера оставляет правильный объем пространства для дескриптор div внизу (для дескриптора South), но оставляет пространство пустым и показывает элемент под (снаружи) контейнера изменяемого размера (проверено с помощью Firebug).

Вот моя разметка (ASP.NET/XHTML) и код 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>

Конечно, я не могу сделать изменяемый размер элемента div (класс resizable-s) дочерним по отношению к TextBox / textarea, но это не должно быть проблемой в соответствии с документацией JQuery.

Судя по поискам, которые я провел, я не единственный, у кого была эта проблема. (К сожалению, документы JQuery не могут привести пример использования настраиваемых дескрипторов с изменяемым размером, поэтому мы все не уверены точно в правильном коде.) Если кто-то может предложить исправление или подтверждение того, что это ошибка JQuery, это было бы очень признательно.

Ответы [ 5 ]

24 голосов
/ 10 июня 2009

После небольшого копания в коде jquery-ui я думаю, что могу подтвердить, что пользовательский дескриптор вне изменяемого размера элемента не работает.

Проблема в том, что события мыши инициализируются для элемента с изменяемыми размерами (или элемента-оболочки в случае textarea). Если дескриптор не является потомком, где обрабатываются события мыши, он не будет вызывать событие mousedown на дескрипторе, что не делает его перетаскиваемым.

В качестве доказательства концепции я немного повозился в jquery-ui, пока не начал что-то (вроде) работать. Нет никаких гарантий относительно кода, но он должен указывать, какие изменения должны произойти, чтобы заставить его работать.

Вокруг строки 140 в ui.resizable.js я изменил:

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

до

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

Затем я добавил следующий код (часть mouseInit из ui.core.js, вероятно, должна использовать всю функцию) в ui.resizable.js (около строки 180) после вызова mouseInit для элемента изменяемого размера:

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

Это позволяет мне создать дескриптор изменения размера, который не является дочерним элементом элемента с изменяемым размером. Моя ручка - это div с идентификатором 'south', который прикреплен к элементу изменяемого размера. Вот фрагмент кода 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>

И код JavaScript:

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

Надеюсь, это поможет!

3 голосов
/ 10 июня 2009

Да, для меня это похоже на ошибку. Вот полный пример для тех, кто пытается локально:

<!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>

Эта ошибка в jQuery UI может быть связана.

Другие вещи, которые я пробовал:

  • Замените 'latest' на '1.6' и 'jquery-1.3.2' на 'jquery-1.2.6', чтобы попытаться использовать более старую версию jQuery UI, чтобы узнать, регрессия ли это. Не похоже на это.
  • Добавьте ui-resizable-s и / или ui-resizable-handle CSS-классы к #southgrip. Нет кости. Однако , если #southgrip находится внутри #resizable, это работает. Но это не решит вашу проблему.
  • Использование { 's': $('#southgrip').get(0) } для опции handles. Без кубиков.
1 голос
/ 13 ноября 2013

У меня была такая же проблема 4 года спустя. То же самое они никогда не исправляли. Я хотя и использовал интерфейс, но он не имел никаких обновлений с 2007 года. Поэтому я решил исправить ошибку самостоятельно и сделать запрос в проекте пользовательского интерфейса jQuery в Github. https://github.com/jquery/jquery-ui/pull/1134 Я надеюсь, что они примут это и скоро объединят. Я добавил тест, так что я уверен, что он будет работать в любом случае, потому что все тесты изменяемого размера из Jquery UI работают с этой модификацией.

Я начал использовать код ylebre, но он не работал. Поэтому я сделал несколько небольших изменений.

0 голосов
/ 17 августа 2015

У меня была похожая проблема, но мне нужно было динамически установить хэдлеры на несколько элементов:

            $.each($(".imagecontainer"),function() {
                $(this).resizable({
                    handles: {se: $(this).closest(".spaciator").find(".ui-resizable-se")}
                });
            };
0 голосов
/ 29 октября 2014

Наконец-то нашли чрезвычайно эффективное решение после нескольких часов попыток преодолеть эту досадную ошибку. Просто добавьте свой элемент handle в класс пользовательского интерфейса. Приведенная ниже функция была протестирована и прекрасно работает с ручками на юг и запад. Надеюсь, это поможет!

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

Когда вы вызываете функцию, как показано ниже, ваш пользовательский дескриптор будет расположен в правильном месте и, вероятно, будет работать PS: функция работает с ручками 'n' и 's'.

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