Создание jQuery UI, сортируемого в iframe - PullRequest
11 голосов
/ 21 февраля 2012

На странице у меня есть iframe.В этом iframe - коллекция предметов, которые мне нужно сортировать.Весь Javascript запускается на родительской странице.Я могу получить доступ к списку в документе iframe и создать сортируемую информацию с помощью контекста:

var ifrDoc = $( '#iframe' ).contents();

$( '.sortable', ifrDoc ).sortable( { cursor: 'move' } );

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

Пример: http://robertadamray.com/sortable-test.html

* 1008Итак, есть ли способ достичь того, что я хочу сделать - желательно без необходимости взламывать код jQuery UI?

Ответы [ 4 ]

9 голосов
/ 28 июня 2012

Динамическое добавление jQuery и jQuery UI в iframe ( demo ):

$('iframe')
    .load(function() {
        var win = this.contentWindow,
            doc = win.document,
            body = doc.body,
            jQueryLoaded = false,
            jQuery;

        function loadJQueryUI() {
            body.removeChild(jQuery);
            jQuery = null;

            win.jQuery.ajax({
                url: 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js',
                dataType: 'script',
                cache: true,
                success: function () {
                    win.jQuery('.sortable').sortable({ cursor: 'move' });
                }
            });
        }

        jQuery = doc.createElement('script');

        // based on https://gist.github.com/getify/603980
        jQuery.onload = jQuery.onreadystatechange = function () {
            if ((jQuery.readyState && jQuery.readyState !== 'complete' && jQuery.readyState !== 'loaded') || jQueryLoaded) {
                return false;
            }
            jQuery.onload = jQuery.onreadystatechange = null;
            jQueryLoaded = true;
            loadJQueryUI();
        };

        jQuery.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js';
        body.appendChild(jQuery);
    })
    .prop('src', 'iframe-test.html');

Обновление: Эндрю Ингрэм правильно , что jQuery UI содержит и использует ссылки на window и document для страницы, на которую был загружен jQuery UI. Загружая пользовательский интерфейс jQuery / jQuery в iframe, он имеет правильные ссылки (для iframe, а не для внешнего документа) и работает как ожидалось.


Обновление 2: В исходном фрагменте кода возникла небольшая проблема: порядок выполнения динамических тегов сценария не гарантирован. Я обновил его, чтобы пользовательский интерфейс jQuery загружался после того, как jQuery будет готов.

Я также включил код getify для динамической загрузки LABjs , так что опрос не требуется.

5 голосов
/ 27 июня 2012

Немного поиграв с их javascript, Campaign Monitor решает эту проблему, в основном имея собственную версию пользовательского интерфейса jQuery.Они изменили ui.mouse и ui.sortable, чтобы заменить ссылки на документ и окно кодом, который получает документ и окно для рассматриваемого элемента.document становится this.element[0].ownerDocument

, и у них есть пользовательская функция jQuery, называемая window (), которая позволяет им заменять window на this.element.window() или подобное.

3 голосов
/ 21 февраля 2012

Я не знаю, почему ваш код не работает. Похоже, так и должно быть.

Тем не менее, есть два альтернативных способа реализации этой функции:

  1. Если вы можете изменить iframe

    Переместите ваш JavaScript из родительского документа в iframe-test.html. Это может быть самым чистым способом, потому что он связывает JavaScript с элементами, на которых он фактически выполняется.

    http://dl.dropbox.com/u/3287783/snippets/rarayiframe/sortable-test.html

  2. Если вы контролируете только родительский документ

    Используйте метод jQuery .load () для извлечения содержимого вместо HTML-фрейма.

    http://dl.dropbox.com/u/3287783/snippets/rarayiframe2/sortable-test.html

1 голос
/ 28 апреля 2014

Вместо загрузки jQuery и jQueryUI в iFrame и оценки взаимодействий jQueryUI как в родительском, так и в дочернем процессах - вы можете просто передать события мыши в документ родителя:

var ifrDoc = $( '#iframe' ).contents();

$('.sortable', ifrDoc).on('mousemove mouseup', function (event) {
    $(parent.document).trigger(event);
});

Таким образом, вы можете оценить весь свой Javascript в контексте документа родителя.

...