IT박스

jQuery 슬라이드가 불안정합니다.

itboxs 2020. 11. 27. 07:55
반응형

jQuery 슬라이드가 불안정합니다.


jQuery의 토글 기능을 사용하여 DIV를 밀어 넣거나 빼려고했지만 결과는 애니메이션 시작 및 / 또는 끝에서 항상 불안정합니다. 내가 사용하는 js 코드는 다음과 같습니다.

$(document).ready(function(){
    $('#link1').click(
        function() {
            $('#note_1').parent().slideToggle(5000);
        }
);

그리고 HTML :

<div class="notice">
    <p>Here's some text. And more text. <span id="link1">Test1</span></p>
    <div class="wrapper">
        <div id="note_1">
            <p>Some content</p>
            <p>More blalba</p>
        </div>
    </div>
</div>

여기에서 전체 예제를 볼 수도 있습니다 : jQuery Slide test

저는 보통 Mootools를 사용하며 문제없이이 슬라이드를 할 수 있습니다. 하지만 저는 Django에서 새 프로젝트를 시작하고 있으며 Django의 대부분의 앱은 jQuery를 사용합니다. 그래서 그것을 위해 그리고이 jQuery와 Mootools를 읽은 후 jQuery 사용을 시작하기에 좋은 기회가 될 것이라고 결정했습니다. 그래서 나의 첫 번째 필요는이 DIV를 슬라이드하는 것이 었습니다. 그리고 제대로 작동하지 않았습니다.

더 많은 검색을 수행했으며 여백과 패딩이 DIV에 적용된 jQuery의 오래된 버그임을 발견했습니다. 해결책은 DIV를 다른 DIV로 래핑하는 것입니다. 제 경우에는 문제가 해결되지 않았습니다.

더 검색하면이 게시물 Slidedown animation jumprevisited . 그것은 한쪽 끝에서 점프를 해결하지만 다른 (에서 Test2를jQuery를 슬라이드 테스트 ).

Stack Overflow에서이 jQuery IE 저키 슬라이드 애니메이션을 발견했습니다 . 댓글에서 DIV 내부의 P 태그에 문제가 있음을 알았습니다. P 태그를 문제를 해결하는 DIV 태그로 바꾸면 적절한 해결책이 아닙니다.

마지막으로이 이상한 jQuery 동작 슬라이드를 찾았습니다 . 그것을 읽으면 P 태그에서 DIV로 전환하여 해결 된 문제는 P의 여백 (DIV에 없음)과 요소 사이의 여백 붕괴라는 것을 이해했습니다. 따라서 여백을 패딩으로 전환하면 문제가 해결됩니다. 그러나 나는 여백의 붕괴 동작을 느슨하게하고, 내가 원하는대로 붕괴한다.

솔직히 jQuery에 대한 첫 경험이별로 좋지 않다고 말할 수 있습니다. jQuery에서 가장 간단한 효과 중 하나를 사용하려면 적절한 기능 (slideToggle)을 사용하지 않고 대신 손으로 만든 코드를 사용하고 DIV를 다른 DIV로 감싸고 여백을 패딩으로 전환하여 레이아웃을 엉망으로 만듭니다.

더 간단한 솔루션을 놓쳤습니까?

krdluzni가 제안했듯이 애니메이션 방법으로 사용자 지정 스크립트로 작성하려고했습니다. 내 코드는 다음과 같습니다.

var $div = $('#note_2').parent();
var height = $div.height();

$('#link2').click(
    function () {
        if ( $div.height() > 0 ) {
            $div.animate({ height: 0 }, { duration: 5000 }).css('overflow', 'hidden');
        } else {
            $div.animate({ height : height }, { duration: 5000 });
        }

        return false;
});

그러나 jQuery는 항상 애니메이션이 끝날 때 오버플로를 표시하도록 설정하기 때문에 작동하지 않습니다. 따라서 DIV는 애니메이션이 끝날 때 다시 나타나지만 나머지 콘텐츠에 오버레이됩니다.

UI.Slide (및 Scale 및 Size)도 시도했습니다. 작동하지만 DIV 아래의 콘텐츠는 애니메이션과 함께 이동하지 않습니다. 애니메이션의 끝 / 시작 부분에서만 점프하여 간격을 채 웁니다. 나는 그것을 원하지 않는다.

최신 정보:

솔루션의 한 부분은 어떤 것보다 먼저 컨테이너 DIV의 높이를 동적으로 설정하는 것입니다. 이것은 하나의 점프를 해결합니다. 그러나 마진이 무너지는 원인은 아닙니다. 코드는 다음과 같습니다.

var parent_div = $("#note_1").parent();
parent_div.css("height", parent_div.height()+"px");
parent_div.hide();

두 번째 업데이트 :

이 페이지 (예제 B)에서 jQuery 자체 사이트의 버그를 확인할 수 있습니다. 튜토리얼 : jQuery의 라이브 예제

세 번째 업데이트 :

jQuery 1.4로 시도했지만 더 이상 기회가 없습니다 :-(


일관되게 작동하는 것은 보이지 않는 1px 테두리를 설정하는 것입니다.

border: 1px solid transparent;

너비 나 높이 등을 수정할 필요가 없으며 애니메이션이 점프하지 않습니다. 만세!


해결책은 슬라이딩 div의 너비가 픽셀 단위로 설정되어야한다는 것입니다. 'auto'또는 '%'를 사용하지 마십시오. 그리고 당신은 큰 결과를 얻을 것입니다! 문제는 슬라이딩 div에있는 인라인 요소에 있습니다.

그러나 너비가 px이면 높이가 동일합니다. 시도 해봐.


나는 오늘이 문제에 직면했습니다. 그러나 모든 CSS를 비활성화하면 문제가 해결된다는 것을 알았습니다. 또한 이전에는 잘 작동한다는 것을 알았으므로 문제를 일으킨 최근 변경 사항 이었음에 틀림 없습니다.

CSS에서 전환을 사용하여 호버를 쉽게 들어오고 나가는 것으로 나타났습니다 .

이러한 전환이 요소에서 제거되면 모든 것을 추가하는 것이 좋습니다.

따라서 동일한 문제가있는 경우 추가하려는 요소에 다음 줄을 추가하십시오.

-webkit-transition: none;
-moz-transition: none;
-o-transition: none;
-ms-transition: none;
transition: none;

(전환을 원하는 요소에 추가하는 것뿐만 아니라 전체 웹 사이트에 사용하여 전환을 약간 남용했을 수 있습니다.)


모든 요소에서 모든 CSS 여백을 제거해보십시오. 일반적으로 불규칙한 애니메이션은 애니메이션 프레임 워크에서 고려하지 않은 여백에서 비롯됩니다.


케이스상위 div ".wrapper" 패딩이 있을 때 저킹이 발생합니다 .

패딩은 부모가 아닌 자식 div에 적용됩니다. jQuery는 패딩이 아닌 애니메이션 높이입니다.

예:

  <div class="notice">
     <p>Here's some text. And more text. <span id="link1">Test1</span></p>
     <div class="wrapper" style="padding: 0">
        <div id="note_1" style="padding: 20px">
           <p>Some content</p>
           <p>More blalba</p>
        </div>
     </div>
   </div>

도움이 되었기를 바랍니다.


animate ()는 jQuery (적어도 크로스 브라우저)에서 모든 것을 애니메이션화하는 가장 안정적인 방법입니다.

이렇게하면 div의 콘텐츠를 동적으로 래핑 한 다음 내부 콘텐츠의 높이를 사용하여 해당 div 래퍼의 높이에 애니메이션을 적용합니다.

http://jsfiddle.net/BmWjy/13/

$('a').click(function(event) {
        event.preventDefault();
        xToggleHeight($(this).next());
});

//For each collapsible element.
$('.collapsible').each(function() {
        //Wrap a div around and set to hidden.
        $(this).wrap('<div style="height:0;overflow:hidden;visibility:hidden;"/>');
});

function xToggleHeight(el){
        //Get the height of the content including any margins.
        var contentHeight = el.children('.collapsible').outerHeight(true);
        //If the element is currently expanded.
        if(el.hasClass("expanded")){
                //Collapse
                el.removeClass("expanded")
                        .stop().animate({height:0},5000,
                        function(){
                                //on collapse complete
                                //Set to hidden so content is invisible.
                                $(this).css({'overflow':'hidden', 'visibility':'hidden'});
                        }
                );
        }else{
                //Expand
                el.addClass("expanded").css({'overflow':'', 'visibility':'visible'})
                        .stop().animate({height: contentHeight},5000,
                        function(){
                                //on expanded complete
                                //Set height to auto incase browser/content is resized afterwards.
                                $(this).css('height','');
                        }
                );
        }
}

animate 메서드를 사용하여 사용자 지정 애니메이션을 작성할 수 있습니다. 이렇게하면 모든 세부 사항을 완벽하게 제어 할 수 있습니다.


나는 당신이있는 경우주의 <br />컨테이너 후 <div>애니메이션도 불안해 할 것이다. 이것을 제거하면 문제가 해결되었습니다.


CSS 패딩과 jquery slideToggle이 함께 잘 작동하지 않습니다. 패딩을 상자에 넣으십시오.


이 문제에 대한 다양한 솔루션이 분명히 있으며 레이아웃에 따라 다른 솔루션의 결과가 다릅니다.

내가 가진 것이 여기에 있었다.

<div>
   <p>Text</p>
</div>
<div class="hidden">
   <p></p>
</div>

jQuery를 사용하여을 표시 <div class="hidden">하면 <p>요소의 여백이 그 <p>위에 있는 요소 의 여백과 함께 축소됩니다 .

서로 다르기 때문에 이상하다고 생각했습니다 <divs>.

내 해결책은 <p>. 한쪽에 여백이 있으면 첫 번째 아래쪽의 여백 <p>이 두 번째 위쪽과 함께 무너지는 것을 방지합니다 <p>.

이 해결 방법은 내 문제를 해결했으며 다른 사람에게 적용 할 수 있지만 모두에게 적용되지 않을 수 있습니다.


컨테이너에서 최소 높이를 제거하면 문제가 해결되었습니다.


effects.js의 위, 아래 효과를 수정하여 존재할 수있는 여백 또는 패딩을 고려한 다음 해당 값을 수용하기 위해 요소의 전체 크기로 인식되는 것을 조정해야합니다. 윤곽....

Effect.BlindDown = function(element) {
  element = $(element);
  var elementDimensions = element.getDimensions();

//below*
  var paddingtop = parseInt(element.getStyle('padding-top'));
  var paddingbottom = parseInt(element.getStyle('padding-bottom'));
  var totalPadding = paddingtop + paddingbottom;

  if(totalPadding > 0)
  {
   elementDimensions.height = (elementDimensions.height - totalPadding);
  }
//above*

  return new Effect.Scale(element, 100, Object.extend({
    scaleContent: false,
    scaleX: false,
    scaleFrom: 0,
    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
    restoreAfterFinish: true,
    afterSetup: function(effect) {
      effect.element.makeClipping().setStyle({height: '0px'}).show();
    },
    afterFinishInternal: function(effect) {
      effect.element.undoClipping();
    }
  }, arguments[1] || { }));
};

컨테이너의 'position'속성 (이 경우 .notice div)을 'relative'로 설정해보세요.

나를 위해 일했습니다. 출처 : slideToggle 높이는 "점프"입니다.


There are a lot of suggestions here and a lot of back and forth as to what works. For me, the behavior problem was when the animation of expanding the container would over expand and then bounce back to the correct expansion height (all done as part of the one animation). In way of example, the animation would expand to a height of 500px initially and then retract to 450px. There was no problem with collapse.

The solution that worked was to add to the expanding/collapsing div, a CSS of: white-space: nowrap;

That worked perfectly - smooth expansion to the correct height.


The problem is that you are performing the action on the parent, doing this removes the CSS related to that element.

You need to run the slide on your note1, not the parent of note 1.

I had the same issue and fixed it by moving down a level.


You might try adding a doctype if you don't have one, it worked for me on IE8 after I found the suggestion here on SO: jQuery slideToggle jumps around. He suggests a strict DTD but I just used the doctype that google.com uses: <!doctype html> and it fixed my problem.


i came across the same bug took days to find a solution. the problem is when the element is hidden jquery is getting the wrong height. top fix it you must get the hight before hiding and use a custom animation to that height. its tricky go here for a better explanation


I had the same problem with 'jerkyness' with divs inside my nav tag - my aim is to show an unordered list on hover of the div (if one exists). My lists are dynamically created so they do not have a fixed value.

Heres the fix:

$("nav div").hover(
  function() { // i.e. onmouseover function

    /****simple lines to fix a % based height to a px based height****/
    var h = jQuery(this).find("ul").height(); //find the height
    jQuery(this).find("ul").css("height", h); 
                         //set the css height value to this fixed value
    /*****************************************************************/

    jQuery(this).find("ul").slideDown("500");
  },
  function(){ // i.e. onmouseout function
    jQuery(this).find("ul").slideUp("500");
  });
});

Ran into this issue today, saw this question, and started tinkering based on what I saw here. I solved our jumpy issue by removing the position:relative from the CSS of the containing div. No more weirdness after that. My 2 cents.


Make sure you don't have CSS transition rules set globally or on your container or any included elements. It will also cause jerkiness.


In my case I solved it adding style="white-space:nowrap;" to the element to prevent miscalculations on the jQuery function; no need to set a fixed width unless you need to wrap.


I was using slideDown() like this

$('#content').hide().delay(500).slideDown(500); 

For me, it was the main container #content element. I was having it hidden and then calling slideDown(). I removed the padding property in the CSS and everything worked fine after that. It's usually a margin, padding, or % width, so the easiest method is commenting out each property and testing them 1 by 1 to get your results.


I had the same issue, but not a single one of the proposed solutions worked for me, so I propose a solution that eliminates relying on slideToggle() altogether.

Spark Notes: Load the page as normal, collect the height of each element you want to toggle, store that height in a special data attribute, and then collapse each element. Then it's as easy as changing the max-height between the value in the element's data-height attribute(expanded) and zero(collapsed). If you want to add extra padding and margins, etc to the elements, I recommend storing those in a separate CSS class to add and remove with the max-height property.

Place the jQuery right after the elements you want to toggle and allow them to execute during page load (so you don't have to watch them all load and then collapse).

HTML

<ul id="foo">
   <li>
      <h2>Click Me 1</h2>
      <div class="bar">Content To Toggle Here 1</div>
   </li>
   <li>
      <h2>Click Me 2</h2>
      <div class="bar">Content To Toggle Here 2</div>
   </li>
</ul>

CSS

#foo>li>div.bar {transition: all 0.5s;
   overflow: hidden;}

jQuery

$('#foo h2').each(function(){
   var bar = $(this).siblings('.bar');
   bar.attr('data-height', bar.height()); //figure out the height first
   bar.css('max-height', '0px'); //then close vertically
});
$('#foo h2').click(function(){
   var bar = $(this).siblings('.bar');
   if ( bar .css('max-height') == '0px' ){ //if closed (then open)
      bar.css('max-height', bar.data('height') + 'px');
   } else { //must be open (so close)
      bar.css('max-height', '0px');
   }
});

Here is a working JSFiddle: http://jsfiddle.net/baacke/9WtvU/


I had the same issue. I fixed it by adding this:

.delay(100)

Guess giving it more time to think helps it along?


I just learned that this problem can also occur if there are floated elements in the expanding/collapsing element. In that case, a clearfix (clear: both;) at the end (still within) the animated element can get rid of it.


Adding my solution: turned out my issue was flexbox (only in chrome). I had align-items: baseline; set on the parent element. Set align-self: center; to my slideToggling full-width child element and it cleared it right up. Great use of two hours.


I solved it by setting:

box-sizing: content-box;

For me the solution was, that i had a CSS style definition like following:

* {
    transition: all .3s;
}

Removing this was the solution!

참고URL : https://stackoverflow.com/questions/1335461/jquery-slide-is-jumpy

반응형