Можно ли внести изменения с помощью jQuery, а затем сразу же отменить это изменение? - PullRequest
1 голос
/ 21 сентября 2011

У меня довольно специфический сценарий, в котором я хотел бы выбрать все элементы с помощью jQuery, внести изменения в CSS, сохранить элементы, а затем отменить изменение, которое я сделал.

Цель

Я создал плагин jQuery с именем jQuery.sendFeedback . Этот плагин позволяет пользователю выделять области экрана, как показано в этой демонстрации . Когда они отправляют свои отзывы, плагин захватывает весь HTML-код на странице и помещает его в функцию обратного вызова. Вот так:

        $('*').each(function ()
        {
            $(this).width($(this).width());
            $(this).height($(this).height());
        });
        var feedbackInformation = {
            subject: $feedbackSubject.val(),
            details: $feedbackDetails.val(),
            html: '<html>' + $('html').html() + '</html>'
        };
        if (settings.feedbackSent)
            settings.feedbackSent(feedbackInformation);

Функция обратного вызова принимает эту информацию обратной связи и выполняет AJAX-вызов для сохранения HTML-кода страницы на сервере (этот HTML-код включает в себя красную рамку, выделенную пользователем, нарисованным на экране). Когда кому-то из техподдержки необходимо просмотреть «снимок экрана» пользователя, он переходит на страницу, которая обслуживает сохраненный HTML-код, чтобы разработчик мог видеть, где пользователь нарисовал свои блики на экране.

Моя первоначальная проблема заключалась в том, что при разных разрешениях экрана элементы имели разные размеры, а красные блики выделяли неправильные области при изменении экрана. Это было довольно легко исправить, выбрав все элементы на странице и вручную установив их высоту и ширину в соответствии с их текущей высотой и шириной, когда пользователь делает снимок. Это делает статичными все размеры элементов, что идеально.

        $('*').each(function ()
        {
            $(this).width($(this).width());
            $(this).height($(this).height());
        });

Проблема

Проблема в том, что когда плагин завершает передачу этого HTML, просматриваемая в настоящее время страница имеет статические высоты и ширины для каждого элемента. Это препятствует тому, чтобы выпадающие меню и некоторые другие вещи работали должным образом. Я не могу придумать простой способ отменить изменения, внесенные в DOM, без обновления страницы (что может оказаться моим единственным вариантом). Я бы предпочел не обновлять страницу.

Попытка решения

Мне нужен способ манипулирования HTML, который я отправляю на сервер, но не DOM. Я попытался изменить приведенный выше код, чтобы сначала извлечь HTML, а затем выполнить операцию со строкой, содержащей HTML (таким образом, не затрагивая DOM), но я не совсем уверен, что я делаю здесь.

        var html = '<html>' + $('html').html() + '</html>';
        $('*', html).each(function ()
        {
            $(this).width($(this).width());
            $(this).height($(this).height());
        });

Это не сработало. Так что либо мне нужно уметь манипулировать строкой HTML, либо мне нужно уметь манипулировать DOM и впоследствии отменить манипуляцию. Я не совсем уверен, что здесь делать.

Обновление

Я использовал решение, которое я разместил ниже, теперь оно прекрасно работает. Теперь мне интересно, есть ли способ статически записать все CSS для каждого элемента в элемент, исключая необходимость ссылки на таблицы стилей.

Ответы [ 2 ]

1 голос
/ 21 сентября 2011

Я думаю, что вы в основном на правильном пути, пытаясь внести изменения в HTML в виде строки, а не на текущей странице для пользователя.

Если вы отметите этот пост , вы также можете последовать рекомендации по созданию временного <div> на странице, клонируя желаемый контент в новый <div>, гарантируя, что он невидим, используя «display:none».Также добавив пользовательский идентификатор в новый <div>, вы можете безопасно применять статический CSS для определения размера к этим элементам, используя более осторожные селекторы.После того, как вы отправили контент на сервер, вы можете полностью удалить новый <div>.

Может быть?

0 голосов
/ 21 сентября 2011

После долгих болей и страданий я придумал грубый, но эффективный метод возврата моих модификаций к DOM.Хотя я и не удосужился попробовать предложение @ fdfrye о клонировании, я попробую это позже, чтобы увидеть, есть ли элегантное решение mroe.А пока вот новый код на тот случай, если кто-то еще может извлечь из него пользу:

        $('*').each(function () {
            if ($(this).attr('style'))
                $(this).data('oldStyle', $(this).attr('style'));
            else
                $(this).data('oldStyle', 'none');
            $(this).width($(this).width());
            $(this).height($(this).height());
        });
        var html = '<html>' + $('html').html() + '</html>';
        $('*').each(function () {
            if ($(this).data('oldStyle') != 'none')
                $(this).attr('style', $(this).data('oldStyle'));
            else
                $(this).removeAttr('style');
        });

Когда я перебираю каждый элемент и изменяю css, я записываю исходное значение на элемент как данные .После того, как я назначил DOM HTML переменной, я затем циклически перебираю все элементы снова и возвращаю атрибуту стиля его первоначальное значение.Если атрибута стиля не было, я записываю «none» в данные элемента, а затем полностью удаляю атрибут style при повторном цикле.

Это более тяжелая производительность, чем хотелось бы, так как она проходит по всем элементамдважды;это займет несколько секунд, чтобы закончить.Не ужасно, но, кажется, немного для такой маленькой задачи.Во всяком случае, это работает.Я получаю строку с HTML-элементами фиксированного размера, и DOM возвращается в нормальное состояние, как будто плагин никогда не трогал его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...