是否可以使用 jQuery 进行更改,然后立即撤消该更改?
我有一个非常具体的场景,我想使用 jQuery 选择所有元素,进行 CSS 更改,保存元素,然后反转我所做的更改。
目标
我创建了一个名为 jQuery.sendFeedback 的 jQuery 插件。该插件允许用户突出显示屏幕区域,如此演示所示。当他们提交反馈时,插件会抓取页面上的所有 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静态写入到该元素中,从而无需引用样式表。
I have a pretty specific scenario where I would like to select all elements with jQuery, make a CSS change, save the elements, then reverse the change I made.
The Goal
I created a jQuery plugin called jQuery.sendFeedback. This plugin allows the user to highlight areas of the screen, as shown in this demo. When they submit their feedback the plugin grabs all the HTML on the page and dumps it into a callback function. Like so:
$('*').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);
The callback function accepts this feedback information and makes an AJAX call to store the page HTML on the server (this HTML includes the red box highlights the user drew on the screen). When someone from tech support needs to view the user's "screen shot" they navigate to a page that serves up the stored HTML so the developer can see where the user drew their highlights on the screen.
My original problem was that different screen resolutions made the elements different sizes and the red highlights would highlight the wrong areas as the screen changed. This was fixed pretty easily by selecting all elements on the page and manually setting their height and width to their current height and width when the user takes the snap shot. This makes all the element sizes static, which is perfect.
$('*').each(function ()
{
$(this).width($(this).width());
$(this).height($(this).height());
});
The Problem
The issue with this is that when the plugin is done transmitting this HTML the page currently being viewed now has static heights and widths on every element. This prevents dropdown menus and some other things from operating as they should. I cannot think of an easy way to reverse the change I made to the DOM without refreshing the page (which may very well end up being my only option). I'd prefer not to refresh the page.
Attempted Solution
What I need is a way to manipulate the HTML that I'm sending to the server, but not the DOM. I tried to change the above code to pull out the HTML first, then do the operation on the string containing the HTML (thus not affecting the DOM), but I'm not quite sure what I'm doing here.
var html = '<html>' + $('html').html() + '</html>';
$('*', html).each(function ()
{
$(this).width($(this).width());
$(this).height($(this).height());
});
This did not work. So either I need to be able to manipulate the string of HTML or I need to be able to manipulate the DOM and undo the manipulation afterward. I'm not quite sure what to do here.
Update
I employed the solution that I posted below it is working beautifully now. Now I am wondering if there is a way to statically write all the css for each element to the element, eliminating the need for style sheets to be referenced.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为通过尝试将 HTML 作为字符串进行修改而不是在用户的当前页面上进行修改,您基本上走在正确的轨道上。
如果您查看这篇文章,您可能还想关注建议在页面上创建临时
,将您想要的内容克隆到新的
,确保其不可见“
显示:无
。”通过在新的上放置自定义 Id,您可以使用更仔细的选择器安全地将静态大小调整 CSS 应用于这些元素。将内容发送到服务器后,您可以完全清除新的
。
或许?
I think you are mostly on the right track by trying to make the modifications to the HTML as a string rather than on the current page for the user.
If you check this post, you might also want to follow the recommendation of creating a temporary
<div>
on the page, cloning your intended content to the new<div>
ensuring it is invisible using "display:none
." By also putting a custom Id on the new<div>
you can safely apply your static sizing CSS to those elements using more careful selectors. Once you have sent the content to the server, you can blow away the new<div>
completely.Maybe?
在经历了很多痛苦之后,我找到了一种粗略但有效的方法来恢复对 DOM 的修改。虽然我还没有抽出时间尝试 @fdfrye 的克隆建议,但接下来我会尝试看看是否有一个更优雅的解决方案。同时,这里是新代码,以防其他人可以从中受益:
当我循环遍历每个元素并修改 css 时,我将原始值作为数据记录到元素上。将 DOM HTML 分配给变量后,我再次循环遍历所有元素,并将 style 属性恢复为其原始值。如果没有样式属性,那么我将“无”记录到元素数据中,然后在再次循环时完全删除样式属性。
这比我希望的性能更重,因为它循环遍历所有元素两次;需要几秒钟才能完成。并不可怕,但对于这么小的任务来说似乎有点太多了。无论如何,它有效。我得到一个带有固定大小 HTML 元素的字符串,并且 DOM 恢复正常,就好像插件从未触及它一样。
After much pain and suffering I figured a crude but effective method for reverting my modifications to the DOM. Though I hadn't gotten around to trying @fdfrye's suggestion of cloning, I will be trying that next to see if there is a mroe elegant solution. In the meantime, here is the new code in case anyone else can benefit from it:
When I'm looping through every element and modifying the css, I log the original value onto the element as data. After I assign the DOM HTML to a variable I then loop through all elements again and restore the style attribute to its original value. If there was no style attribute then I log 'none' to the element data and then remove the style attribute entirely when looping through again.
This is more performance heavy than I wish it was since it loops through all elements twice; it takes a few seconds to finish. Not horrible but it seems like a little much for such a small task. Anyway, it works. I get a string with fixed-sized HTML elements and the DOM goes back to normal as if the plugin never touched it.