【问题标题】:Is it possible to make a change with jQuery and then immediately reverse that change?是否可以使用 jQuery 进行更改,然后立即撤消该更改?
【发布时间】:2011-11-21 14:26:43
【问题描述】:

我有一个非常具体的场景,我想使用 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 所做的更改而不刷新页面(这很可能最终成为我唯一的选择)。我不想刷新页面。

尝试的解决方案

我需要的是一种方法来操作我发送到服务器的 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 静态写入元素,从而无需引用样式表。

【问题讨论】:

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


    【解决方案1】:

    我认为通过尝试将 HTML 修改为字符串而不是在用户的当前页面上进行修改,您基本上走在了正确的轨道上。

    如果您选中this post,您可能还需要遵循在页面上创建临时&lt;div&gt; 的建议,将您的预期内容克隆到新的&lt;div&gt;,确保使用“display:none”不可见。通过在新的&lt;div&gt; 上添加自定义 ID,您可以使用更谨慎的选择器安全地将静态大小 CSS 应用于这些元素。将内容发送到服务器后,您就可以彻底清除新的&lt;div&gt;

    也许?

    【讨论】:

    • 我将不得不多研究一下这个克隆业务。它可能比我目前的粗略方法更优雅地解决我的问题。
    【解决方案2】:

    在经历了许多痛苦和磨难之后,我想出了一个粗略但有效的方法来恢复我对 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 属性恢复为其原始值。如果没有样式属性,那么我将“无”记录到元素数据中,然后在再次循环时完全删除样式属性。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-26
      • 2018-08-12
      • 1970-01-01
      • 2011-04-01
      • 2017-03-20
      • 2011-06-25
      • 2014-10-27
      • 1970-01-01
      相关资源
      最近更新 更多