Пользовательские изменяемые размеры ручек в пользовательском интерфейсе JQuery

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

Документация JQuery по методу Resizable (в частности, на handles) указывает, что я могу установить любой из дескрипторов для использования пользовательского элемента HTML. Мне удалось получить текстовое поле с изменяемым размером, прекрасно работающим с помощью стандартных изменяемых по умолчанию ручек, но попытка установить пользовательские (т.е. Элемент HTML, который я определил в разметке) создает следующую проблему: размерный контейнер оставляет правильное пространство для ручка div внизу (для южного дескриптора), но оставляет пустое пространство и показывает элемент ниже (вне) контейнера с изменяемым размером (проверено с использованием 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>

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

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

Ответ 1

От небольшого копания, которое я сделал в коде 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 с id '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")}}
    );

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

Ответ 2

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

<!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-ошибка может быть связана.

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

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

Ответ 3

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

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

Ответ 4

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

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

Ответ 5

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

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