在 jquery 中使用隐藏和显示时不需要的“闪烁”效果

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1131760/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 10:43:32  来源:igfitidea点击:

unwanted "flickering" effect when using hide and show in jquery

jqueryhtml

提问by craigmoliver

I'm getting an annoying "flickering" effect in Firefox when using jQuery "show" and "hide" on some div's. Any idea when this could be happening?

在某些 div 上使用 jQuery“显示”和“隐藏”时,我在 Firefox 中遇到了烦人的“闪烁”效果。知道这什么时候会发生吗?

回答by Stephen Fuhry

Depending on what you mean by flicker (if it only flickers when the page loads), instead of doing:

根据您所说的闪烁(如果它仅在页面加载时闪烁),而不是执行以下操作:

$(document).ready(function(){
   $("hide").hide();
});

<div id="hide">My Hidden Text</div>

Try adding display:none in the CSS:

尝试在 CSS 中添加 display:none :

<div id="hide" style="display:none">My Hidden Text</a>

CSS is applied to the DOM before even JavaScript is allowed to manipulate it, so if you do this, there should be no flicker when you load the page.

CSS 被应用到 DOM 之前,甚至在 JavaScript 被允许对其进行操作之前,所以如果你这样做,加载页面时就不应该有闪烁。

Also of note, in Firefox, there is a bug that causes the window to flicker when you change the size of the window (vertically), and the current scroll position is close or at the bottom of the window.

另外值得注意的是,在 Firefox 中,有一个错误会导致当您更改窗口大小(垂直)并且当前滚动位置靠近或位于窗口底部时,窗口会闪烁。

回答by dbellizzi

The flicker comes from this line of the jQuery code, in the show() method:

闪烁来自 jQuery 代码的这一行,在 show() 方法中:

 var elem = jQuery("<" + tagName + " />").appendTo("body"); 

It does that to detect the CSS it should use for the display attribute, since different tags get different values (div: block, span: inline, tr: table-row, etc). Manipulating the DOM in this way causes the flicker.

它这样做是为了检测它应该用于 display 属性的 CSS,因为不同的标签获得不同的值(div:block、span:inline、tr:table-row 等)。以这种方式操作 DOM 会导致闪烁。

Use:

用:

jQuery('...').css('display','block');

which will generally do the same thing.

这通常会做同样的事情。

回答by cletus

Two possible reasons:

两个可能的原因:

  1. Hiding and showing is causing the scrollbar to appear and disappear, which changes the page width; or
  2. The div appearing and disappearing changes the width and/or height calculations.
  1. 隐藏和显示导致滚动条出现和消失,从而改变页面宽度;或者
  2. div 的出现和消失会改变宽度和/或高度的计算。

Other than that, we'd need a sample.

除此之外,我们还需要一个样本。

回答by blindfish

@Stephen: Hard-coding display: none in the CSS may seem like an easy fix, but it's potentially a bad idea. If the hidden content is important to the user, and simply being hidden on load for convenience (and is then displayed when the user, for example, clicks on a button), then display: none will permanently hide the content from those with javascript disabled. If accessibility is a concern for you then don't use this approach...

@Stephen:硬编码显示:CSS 中的 none 看起来很容易修复,但这可能是个坏主意。如果隐藏的内容对用户很重要,并且只是为了方便而在加载时隐藏(然后在用户单击按钮时显示),则 display: none 将永久隐藏那些禁用 javascript 的内容. 如果您关心可访问性,请不要使用这种方法......

回答by Ajay Singh

Since you had mentioned some divs, if you are animating more than one div at the same time can cause flickering due to multiple repaints.

由于您提到了一些 div,如果您同时为多个 div 设置动画可能会由于多次重绘而导致闪烁。

1st solution, use settimeout to split each animation

第一种解决方案,使用 settimeout 拆分每个动画

2nd solution, move all the animation to css and just toggle the class and then hide it.

第二种解决方案,将所有动画移动到 css 并切换类,然后将其隐藏。

And use both together as follows for show and hide (using transition for opacity)

并按如下方式一起使用以显示和隐藏(使用不透明度过渡)

CSS

CSS

#you_div {
    transition: opacity 0.4s ease-in-out;
}

JS

JS

//To show
$('#you_div').css('opacity', '0');
$('#you_div').css('display', 'block');
setTimeout(function() {
    $('#you_div').css('opacity', '1');
}, 50);

//To hide
$('#you_div').css('opacity', '0');
setTimeout(function() {
    $('#you_div').css('display', 'none');
},400);

Monitor repaints using devtools on your browser. The more the repaint, more flickering and lags.

使用浏览器上的 devtools 监控重绘。重绘越多,闪烁和滞后就越多。

回答by Wouter de Winter

It is indeed this line that causes the flicker. I wrote this extension to remove the line from the show function. Note that it always sets the display element to 'block'.

确实是这条线导致了闪烁。我编写了这个扩展来从 show 函数中删除该行。请注意,它始终将显示元素设置为“块”。

I eventually solved it differently. I used a span element and changed it to a div.

我最终以不同的方式解决了它。我使用了 span 元素并将其更改为 div。

/** fixes flicker in jQuery show function */
var fxAttrs = [
  // height animations
  [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
  // width animations
  [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
  // opacity animations
  [ "opacity" ]
 ];

function genFx( type, num ){
 var obj = {};
 jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function(){
  obj[ this ] = type;
 });
 return obj;
}

(function($){ 
    $.fn.extend({ 
 show: function(speed,callback){
  if ( speed ) {
   return this.animate(genFx("show", 3), speed, callback);
  } else {
   for ( var i = 0, l = this.length; i < l; i++ ){
    var old = jQuery.data(this[i], "olddisplay");

    this[i].style.display = old || "";

    if ( jQuery.css(this[i], "display") === "none" ) {
     jQuery.data(this[i], "olddisplay", 'block');
    }
   }

   // Set the display of the elements in a second loop
   // to avoid the constant reflow
   for ( var i = 0, l = this.length; i < l; i++ ){
    this[i].style.display = jQuery.data(this[i], "olddisplay") || "";
   }

   return this;
  }
 }
    }); 
})(jQuery);

回答by etoisarobot

Per John Resig in reponse to a similar complaint on the Jquery Google Group here

每约翰Resig的的效应初探到jQuery开发谷歌集团类似的投诉在这里

Which browser? If you're in IE, then this flicker is because your page is in Quirks mode instead of Standards mode (you'll need to provide a correct DOCTYPE in order to trigger this).

哪个浏览器?如果您使用的是 IE,那么此闪烁是因为您的页面处于 Quirks 模式而不是标准模式(您需要提供正确的 DOCTYPE 才能触发此操作)。

Also this postseems to point to the same solution.

此外,这篇文章似乎指向了相同的解决方案。

回答by Ben Scheirman

I've noticed this as well. I don't have a definite answer for you, but you might try tinkering with border/padding/margin for the element in question.

我也注意到了这一点。我没有明确的答案,但您可以尝试修改相关元素的边框/填充/边距。