JQuery如果然后使用URL解析器插件任务优雅2

时间:2009-04-26 02:54:34

标签: jquery firefox url

这是关于这个主题的第二个问题,原始问题可以在这里找到: JQuery if then else using URL parser plugin, there must be a more elegant solution!

如果你坐得舒服我就会开始!

我已经建立了一个包含问题列表的网页。每个问题的答案都包含在Div之后。 HTML看起来像这样:

<div class="questions_main_box">
   <h2>common questions:</h2>
   <ul>
      <li>
         <h3 id="question1">question number 1</h3>
     <div id="answer1"> answer number 1</div>
      </li>
      <li>
         <h3 id="question2">question number 2</h3>
     <div id="answer2"> answer number 2</div>
      </li>
      etc etc...
   </ul>
</div>

我已经使用jQuery编写了一些代码来调整此列表的行为方式。这个想法是所有答案Div都被jQuery隐藏,然后以两种方式之一显示它们:

用户点击相关的h3标题

用户点击指向其他页面中某个问题的链接。

如果用户来自其他网页,则应显示他们点击的问题,并隐藏所有其他网页。

我已经完成了这项工作,但我的代码效率很低。我之前在解释这个问题时得到了一个答案,但我收到的答案有一个不良的副作用:他们停止菜单显示任何答案,除非URL中有一个锚链接。例如:

http://mydomain.com/questions.html不起作用

但是

http://mydomain.com/questions.html#question1会奏效!

我需要两个人工作!正如我所说,我的版本确实在两个方面都有效,但非常笨重,我相信必须有更好的表达方式。这是可能更有效的代码:

if 
($.url.attr('anchor') == 'question1'){
        $('#answer2, #answer3, #answer4, #answer5, #answer6, #answer7, #answer8').hide();
        $.scrollTo('#question1');
}
else if
($.url.attr('anchor') == 'question2'){
        $('#answer1, #answer3, #answer4, #answer5, #answer6, #answer7, #answer8').hide();
        $.scrollTo('#question2');
}
else if
($.url.attr('anchor') == 'question3'){
        $('#answer1, #answer2, #answer4, #answer5, #answer6, #answer7, #answer8').hide();
        $.scrollTo('#question3');
}
else if
($.url.attr('anchor') == 'question4'){
        $('#answer1, #answer2, #answer3, #answer5, #answer6, #answer7, #answer8').hide();
        $.scrollTo('#question4');
}
else if
($.url.attr('anchor') == 'question5'){
        $('#answer1, #answer2, #answer3, #answer4, #answer6, #answer7, #answer8').hide();
        $.scrollTo('#question5');
}
else if
($.url.attr('anchor') == 'question6'){
        $('#answer1, #answer2, #answer3, #answer4, #answer5, #answer7, #answer8').hide();
        $.scrollTo('#question6');
}
else if
($.url.attr('anchor') == 'question7'){
        $('#answer1, #answer2, #answer3, #answer4, #answer5, #answer6, #answer8').hide();
        $.scrollTo('#question7');
}
else if
($.url.attr('anchor') == 'question8'){
        $('#answer1, #answer2, #answer3, #answer4, #answer5, #answer6, #answer7').hide();
        $.scrollTo('#question8');
}
else if
($.url.attr('anchor') != 'question1, question2, question3, question4, question5, question6, question7, question8'){
        $('.questions_main_box ul li div').hide();
};

它运行正常,但非常笨重,在它目前的化身中,它还意味着如果我想添加更多的问题和答案,我必须将它们明确地添加到ID的列表中。不必这样做会好得多!

这样你就可以了解整个代码的其余部分:

$('.questions_main_box h3').addClass('js_main_box');
    $('.questions_main_box h3').hover(
        function(){
            $(this).addClass('js_main_box_highlight');
        },
        function(){
            $(this).removeClass('js_main_box_highlight');
        }
    );

    $('.questions_main_box h3').click(
            function(){
                if ($(this).next().is(':visible')){
                    $(this).next().hide('fast');
                    }
                else if ($(this).next().is(':hidden')){
                    $(this).next().show('fast');
                    }
            }
    );

所以这一切都是按原样运作的,我真的只是在寻找提高效率的方法。

我发现我正在做的事情有一个问题,而对于我的生活,我无法理解为什么会发生这种情况或者我将如何修复它:

问题仅出在Firefox(我测试过3.0.9和3.1b3)

当我点击其中一个锚链接进入相关的问题和答案时,Firefox将跳转到右侧页面,正确的答案将会显示但页面不会垂直滚动到正确的位置锚标签开始。这意味着,当用户首次到达问答页面时,屏幕上通常无法看到用户点击的问题!这只发生在Firefox中。 Safari和Opera去了正确的地方。我确定它必须与被隐藏的Div有关,因为当关闭javascript并且正常显示列表时,锚标签在Firefox中正常工作。我觉得这真的很奇怪,我不知道它是如何修复的,或者它只是一个没有解决方法的bug。我将非常感激地收到有关我任何一个问题的任何信息。

感谢您花时间看看这个!

伊恩。

PS

我正在使用此处的JQuery URL解析器插件:http://projects.allmarkedup.com/jquery_url_parser/

6 个答案:

答案 0 :(得分:3)

我建议使用css选择器来隐藏你的答案。为此,您必须在答案中添加一个class属性。

<div class="questions_main_box">
   <h2>common questions:</h2>
   <ul>
      <li>
         <h3 id="question1">question number 1</h3>
     <div id="answer1" class="answer">answer number 1</div>
      </li>
      <li>
         <h3 id="question2">question number 2</h3>
     <div id="answer2" class="answer">answer number 2</div>
      </li>
      etc etc...
   </ul>
</div>

然后使用jquery,您可以使用此

隐藏所有答案
$('.answer').hide();

所以,与你的其他问题 JQuery if then else using URL parser plugin, there must be a more elegant solution! 放在一起会是:

var match = jQuery.url.attr('anchor').match(/^question([0-9]+)$/);
if (match && match.length > 0) {
    $('.answer').hide();
    $('#answer' + match[1] ).show();
} 

或者在这样的单行上。

 $('.answer').hide().is('#answer' + match[1]).show();

答案 1 :(得分:1)

要解决您的Firefox问题,您可以尝试使用jQuery在取消隐藏后滚动到您的锚。我想,这有点像hackish,但它应该有效。

jQuery的'Interface'插件包含一个scrollTo方法。 Link

示例用法。 jQuery Smooth Scroll to Anchor Links

要解决优雅问题,这里有一个想法:

var targetDiv = $('#'+($.url.attr('anchor'))).next().attr('id');
$("div[id!='"+targetDiv+"'][id^='answer']").hide();
$("div[id='"+targetDiv+"']").show();
$.scrollTo('#'+($.url.attr('anchor')));

答案 2 :(得分:1)

我的建议是最初不要使用jQuery来隐藏答案,因为动态地这样做似乎可能会使浏览器混淆页面的长度。

相反,我会使用类和CSS来隐藏它们,例如。

<li>
  <h3 id="question1">Foo?</h3>
  <div id="answer1" class="answer">Bar!</div>
</li>

并将.answers { display: none; }添加到页面的样式中,以便浏览器知道在页面首次呈现时不会显示这些样式。然后,添加$('#answer1').show()将显示相应的内容。

当然,这只适用于您的用户启用了Javascript,这可能是一个有效的假设。如果它们可能没有,那么您需要在页面完全呈现之前将此CSS动态添加到页面顶部。这是通过在添加样式的正文顶部添加<script>来完成的:

<body>
  <script type="text/javascript">
    var style = document.createElement('style');
    style.type = 'text/css';
    style.innerHTML = '.answers { display: none; }';
    document.getElementsByTagName('head')[0].appendChild(style);
  </script>
  ...

这将确保没有Javascript的人会看到所有答案。

在我的测试中,这样做可以确保页面正确滚动到正确的问题,至少在FF3中。

答案 3 :(得分:1)

你应该添加一个类,用css隐藏它们会更加清晰。但是使用你现有的HTML ......

$("div.questions_main_box div").hide();

在锚点的绝对中,看起来你想要显示第一个问题......

var question = jQuery.url.attr('anchor') | "question1";
var match = question.match(/^question([0-9]+)$/);
if (match && match.length > 0) {
    $('#answer' + match[1] ).show().scrollTo();
}

我不确定你的代码中是什么.scrollTO,但我认为它是一个插件,而$ .scrollTo(selector)应该与$(selector)相同.scrollTo()

由于你使用锚点,你应该使用内置滚动机制的浏览器和锚点,忘记jQuery滚动。为每个问题添加相应的锚标记,如:

<li>
    <a name="question1" />

答案 4 :(得分:0)

$('.questions_main_box h3').addClass('js_main_box');

$('.questions_main_box h3').bind('mousenter mouseleave',function(){
    $(this).toggleClass('js_main_box_highlight');
});

$('.questions_main_box h3').click(function(){
    var answer = $(this).parent().find("div");
    if (answer.is(':visible')) {
      answer.hide('fast');
      return;
    }
    answer.show('fast');
});

答案 5 :(得分:0)

好的,所以我要回答我自己的问题!此解决方案使用scrollTo修复Firefox滚动错误,代码更加优雅和可扩展。它仍然不完美,但我设法将if循环压缩到这个:

if 
  ($.url.segment(1) == 'questions.html'||'terms.html') {
    $('.questions_main_box ul li div').hide();
    $('#'+($.url.attr('anchor'))).next().show();
    $.scrollTo('#'+($.url.attr('anchor')));
};

优点:

  • 代码更优雅/浓缩/ DRYer
  • 网址锚点现在可以正常工作,无论它们被称为什么
  • 不依赖于匹配的问题和答案ID
  • 将扩展到任意数量的条目

缺点:

  • 在使用URL解析显示任何匹配项之前,所有div都被隐藏。这比找到测试方法并且只隐藏必要的div的效率略低。

就是这样!我希望这可以帮助那些有类似难题的人在他们的大脑中喋喋不休!如果有人能想出一种方法来改进这个代码以删除最终的con,那么我真的很想看到你的解决方案。

最后感谢Steven Richards通过建议使用scrollTo来解决Firefox bug问题。一个无痛而简单的解决方案,谢谢! https://stackoverflow.com/users/96089/steven-richards