是否可以使用jQuery进行更改,然后立即撤消该更改?

时间:2011-09-21 03:44:55

标签: javascript jquery dom jquery-plugins jquery-selectors

我有一个非常具体的场景,我想用jQuery选择所有元素,进行CSS更改,保存元素,然后反转我所做的更改。

目标

我创建了一个名为jQuery.sendFeedback的jQuery插件。该插件允许用户突出显示屏幕区域,如this demo所示。当他们提交反馈时,插件会抓取页面上的所有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所做的更改而不刷新页面(这可能最终成为我唯一的选择)。我不想刷新页面。

尝试解决方案

我需要的是一种操作我发送到服务器但不是DOM的HTML的方法。我尝试更改上面的代码,先取出HTML,然后对包含HTML的字符串进行操作(从而不影响DOM),但我不太清楚我在这里做什么。

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

这不起作用。所以要么我需要能够操作HTML字符串,要么我需要能够操纵DOM并在之后撤消操作。我不太清楚该怎么做。

更新

我使用了我在下面发布的解决方案,现在工作得非常好。现在我想知道是否有办法静态地将每个元素的所有css写入元素,从而无需引用样式表。

2 个答案:

答案 0 :(得分:1)

我认为您通过尝试将HTML的修改作为字符串而不是在用户的当前页面上,大多数都在正确的轨道上。

如果您选中this post,您可能还需要遵循在页面上创建临时<div>的建议,将您想要的内容克隆到新的<div>,以确保它不可见“display:none”。通过在新<div>上添加自定义Id,您可以使用更仔细的选择器安全地将静态大小调整CSS应用于这些元素。将内容发送到服务器后,您可以完全吹掉新的<div>

也许?

答案 1 :(得分:0)

经过多次痛苦和痛苦之后,我想出了一种粗略但有效的方法来恢复我对DOM的修改。虽然我还没有尝试过@fdfrye的克隆建议,但我会尝试下一步,看看是否有一个优雅的解决方案。与此同时,以下是新代码,以防其他任何人从中受益:

        $('*').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时,我将原始值作为 data 记录到元素上。在我将DOM HTML分配给变量之后,我再遍历所有元素 并将style属性恢复为其原始值。如果没有样式属性,那么我将'none'记录到元素数据中,然后在循环再次时完全删除样式属性。

这比我希望的更重要,因为它遍历所有元素两次;完成需要几秒钟。并不可怕,但对于这么小的任务来说似乎有点多了。无论如何,它的工作原理。我得到一个包含固定大小的HTML元素的字符串,并且DOM恢复正常,好像该插件从未触及过它。