سؤال

أحاول بناء الأكورديون الأفقي مع jQuery. يبدو أنه يعمل "موافق" في Firefox. ولكن في WebKit (Safari 3 + 4 ، و Chrome) ، تومض UL من المستوى الفرعي بعد وظيفة إخفاء. أي مساعدة سيكون موضع تقدير كبير. لرؤية عرض عمل: http://ousobject.com/horaccordion1.html

هذا ما أعمل عليه:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>

    <title>untitled</title>
    <style type="text/css">
    #container {
        display: table; 
        margin: 0 auto; 
        text-align: center; /* for IE */
    }
            ul{
                    list-style: none;
                    background-color: yellow;
                    margin: 0;
                    padding: 0;
                    float: left;
                    height: 20px; /* For testing */     
            }
            ul li {
                   background-color: aqua;
                    float: left;
            }
            ul li ul {
                   background-color: blue;
                    display: none;
            }
            ul li ul li {
                   background-color: green;
            }
            a, a:link, a:hover, a:visited, a:active {
                    color: black;
                    text-decoration: none;
                    float: left;
            }
    </style>

   <script type="text/javascript">
/* Care of Hunter Daley */
    var $current = null;
        $(document).ready(function(){
         $("ul li ul").hide();  // hide submenus by default on load

           $("ul li a").click(function(){
              var $sub = $(this).next(); 
              if ($sub.css("display") == "none")
              {
                 if ($current != null)
                    $current.animate({ width: 'hide' }); // if you want to only show one sub at a time
                 $sub.animate({ width: 'show' }); 
                 $current = $sub;
              }
              else
              {
                 $sub.animate({ width: 'hide' });
                 $current = null;
              }
           });
        });
    </script>
</head>

<body>
    <div id="container">
    <ul>
            <li>
                    <a href="#">Top-level 1</a>
            </li>
            <li>
                    <a href="#">Top-level 2</a>

                    <ul>
                            <li><a href="#">Bottom Level A1</a></li>
                            <li><a href="#">Bottom Level A2</a></li>
                            <li><a href="#">Bottom Level A3</a></li>
                            <li><a href="#">Bottom Level A4</a></li>
                    </ul>
            </li>

            <li>
                    <a href="#">Top-level 3</a>
                    <ul>
                            <li><a href="#">Bottom Level B1</a></li>
                            <li><a href="#">Bottom Level B2</a></li>
                    </ul>
            </li>

            <li>
                    <a href="#">Top-level 4</a>
            </li>
    </ul>
</div>
</body>
هل كانت مفيدة؟

المحلول

هذا يبدو أنه مرتبط بمشكلة واجهتها منذ فترة قصيرة مع WebKit. هناك خطأ في WebKit الذي يتسبب في بعض الأحيان في العودة إلى والد العنصر إلى حجمه الأصلي بعد الرسوم المتحركة التي تقلل من عرض العناصر. بعد الرسوم المتحركة ، يعود والد العنصر إلى حجمه الأصلي من أجل استيعاب محتواه.

تحرير: إزالة التعليقات حول jQueryui. لست متأكدًا لماذا اعتقدت أنك تستخدمه.

تمت مناقشة الخطأ هنا, ، والتي تفاصيل الحل البديل.

لقد قدمت أ تقرير الشوائب إلى jQuery كذلك.

في الأساس ، ستحتاج إلى تقليل عرضك في وقت واحد $sub والد العنصر بنفس مبلغ $sub يتم تقليله. لذلك إذا كان عرض $sub هو 100 بكسل ، سيكون هناك منفصلة animate() لتقليل الوالد بمقدار 100 بكسل.

لم أختبر أيًا من هذا مثالك ، لكنني أعتقد أنه ربما يكون المفتاح.

تحرير 2:نسخة جديدة باستخدام divs

CSS:

.title {
       list-style: none;
       margin: 0;
       padding: 0;
       float: left;
       height: 32px; /* For testing */
       font-family: helvetica;
       font-size: 18px;
       clip: auto; overflow: hidden;
}
.menu {
       height: 32px; /* For testing */
       clip: auto; overflow: hidden;
       float: left;
}
a, a:link, a:hover, a:visited, a:active {
       color: black;
       text-decoration: none;
       padding: 12px;
       font-weight: 700;
       float: left;
       color: #222;
}

 .menu a, .menu a:link, .menu a:hover, .menu a:visited, .menu a:active {
   color: black;
   text-decoration: none;
   padding: 12px;
   font-weight: normal;
   float: left;

}

JavaScript:

    // Prevents us from having to check for null.
    var $current = $('#someFictionalElement');
    var $previous = null;
    $(document).ready(function(){
    $(".menu").css({width: 0});  // hide submenus by default on load

    $(".title").click(
        function() {
            $previous = $current;
            $current = $(this);
            var $currentMenu = $current.next();

            $previous.next().animate({ width: 0 }, {duration: 1000, queue: false} );

    // Make sure that if there's no menu text (like Top Level 1 and 4) that it does not animate.
    // This is because of the pixels added for Firefox (see comment below)
            if( $currentMenu.width() == 0 && $currentMenu.text() != ''  ) {

    // Expand the menu but keep it hidden so we can get its width
                $currentMenu.css({visibility: 'hidden', width: ''});

    // Store the width, and add a few pixels for Firefox
                var currentWidth = $currentMenu.width() + 3;

    // Make menu visible and set with to 0 in preparation for the animation
                $currentMenu.css({visibility: 'visible', width: 0})
                            .animate({ width: currentWidth }, 1000);
            }
    });

    $(".title a").hover(
        function(){$(this).animate ({ opacity: 0.7 }, 200);},
        function(){$(this).animate ({ opacity: 1 }, 600);}
    );
});

لغة البرمجة:

<body>
    <div id="container">
        <div class='title' id='level1'>
            <a href="#">Top-level 1</a>
        </div>
        <div class='menu'></div>
        <div class='title' id='level2'>
            <a href="#">Top-level 2</a>
        </div>
        <div class='menu'>                         
            <a href="#">Bottom Level A1</a>
            <a href="#">Bottom Level A2</a>
            <a href="#">Bottom Level A3</a>
            <a href="#">Bottom Level A4</a>
        </div>
        <div class='title' id='level3'>
            <a href="#">Top-level 3</a>
        </div>
        <div class='menu'>
            <a href="#">Bottom Level B1</a>
            <a href="#">Bottom Level B2</a>
        </div>
        <div class='title' id='level4'>
            <a href="#">Top-level 4</a>
        </div>      
        <div class='menu'></div>
    </div>
</body>

نصائح أخرى

أقوم بنشر هذا كإجابة منفصلة فقط في حال كنت لا تزال تجد الإجازة السابقة مفيدة.

يرجى ملاحظة ما يلي:

  • لم أختبر هذا في IE.
  • يعود هذا إلى إصدار "متداخل" ، لذلك غيرت الفصل وأسماء المتغيرات قليلاً.
  • لم تعد هناك حاجة إلى قائمة فارغة عندما لا توجد قائمة لعرضها.
  • يتم الآن تقليل عرض "حاوية" كل قائمة من نفس القائمة. هذا هو ما يلغي فلاش WebKit المؤقت (الذي كان الاستراتيجية الأصلية).
  • ستلاحظ توقيت الرسوم المتحركة للقائمة يختلف قليلاً عن توقيت حاوية القائمة. في الأساس ، تريد أن تكون الحاوية متقدمًا قليلاً عند التوسع ، وتكون القائمة مقدمة قليلاً عند التقليل. إذا تم تعيين التوقيت ليكون متساوًا ، فيمكنك الحصول على بعض وميض القائمة.
  • كما هو موضح في التعليقات ، في البداية ، تحفظ كل قائمة "عرضها" عند توسيعها بالكامل عن طريق تعيين سمة غير موجودة مسبقًا تسمى "FullWidth". ثم يسترجع قيمة هذه السمة عند الحاجة. يمكنك بسهولة استخدام المتغيرات العالمية ، أو وظيفة بيانات jQuery () لتخزين المعلومات. النقطة المهمة هي أن الأمور مبسطة إذا كانت كل قائمة على دراية بمدى عرضها عند توسيعها.

حتى هنا هو عليه. أتمنى أن يساعد!

CSS

#container {
    margin: 0 auto 0 auto; 
    text-align: center;
    display: table;
}

.menuContainer {
       margin: 0;
       padding: 0;
       float: left;
       height: 32px; /* For testing */
       font-family: helvetica;
       font-size: 18px;
       clip: auto; overflow: hidden;
}
.menu {
       height: 32px; /* For testing */
       clip: auto; overflow: hidden;
       float: left;
}
a, a:link, a:hover, a:visited, a:active {
       color: black;
       text-decoration: none;
       padding: 12px;
       font-weight: 700;
       float: left;
       color: #222;
}

.menu a, .menu a:link, .menu a:hover, .menu a:visited, .menu a:active {
   color: black;
   text-decoration: none;
   padding: 12px;
   font-weight: normal;
   float: left;
}

جافا سكريبت

var $currentMenuContainer = $('#someFictionalElement');
var $previousMenuContainer = null;

$(document).ready(function() {

// Iterate through each .menu element, setting the full width of each menu to a 'custom'
//        attribute called 'fullWidth'. Since the full width should never change, this
//        makes it easy to recall it quickly. You could use global variables instead.
// After setting 'fullWidth', it then collapses each menu and title.
$(".menu").each(function() {
    var $theMenu = $(this);
    var $theMenuContainer = $theMenu.parent();
    $theMenu.attr({fullWidth: ($theMenu.width() + 3)});   // Add a few pixels for firefox
    var menuContainerWidth = $theMenuContainer.width() - $theMenu.attr('fullWidth') + 6;  // Add DOUBLE the pixels here
    $theMenu.css({width: 0});
    $theMenuContainer.css({width: menuContainerWidth});
});

    $(".menuContainer a").click(
        function() {
// Set the current and previous elements properly
            $previousMenuContainer = $currentMenuContainer;
            $currentMenuContainer = $(this).parent();
            var $previousMenu = $previousMenuContainer.find('.menu');
            var $currentMenu = $currentMenuContainer.find('.menu');

// Collapse the previous menu
            $previousMenu.animate({ width: 0 }, {duration: 480, queue: false} );

// Subtract the width of the previous menuContainer's menu from the menuContainer (only if its menu is displayed)
            if($previousMenu.width() > 0) $previousMenuContainer.animate({width: ('-=' + $previousMenu.attr('fullWidth'))}, 500);

// Expand the current menu and its menuContainer if it's not showing
            if($currentMenu.width() == 0) {
                // Increase the menuContainer width by the full width of its menu
                $currentMenuContainer.animate({width: ('+=' + $currentMenu.attr('fullWidth'))}, 480);
                // Increase the menuContainer to its full width
                $currentMenu.animate({ width: $currentMenu.attr('fullWidth') }, 500);
            }
    });

    $(".menuContainer a").hover(
        function(){$(this).animate ({ opacity: 0.7 }, 200);},
        function(){$(this).animate ({ opacity: 1 }, 600);}
    );
});

لغة البرمجة

<div id="container">
    <div class='menuContainer'>
        <a href="#">Top-level 1</a>
    </div>
    <div class='menuContainer'>
        <a href="#">Top-level 2</a>
        <div class='menu'>                         
            <a href="#">Bottom Level A1</a>
            <a href="#">Bottom Level A2</a>
            <a href="#">Bottom Level A3</a>
            <a href="#">Bottom Level A4</a>
        </div>
    </div>
    <div class='menuContainer'>
        <a href="#">Top-level 3</a>
        <div class='menu'>
            <a href="#">Bottom Level B1</a>
            <a href="#">Bottom Level B2</a>
        </div>
    </div>
    <div class='menuContainer'>
        <a href="#">Top-level 4</a>
    </div>
</div>

يحرر: أضف DTD التالي إلى أعلى صفحتك-

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top