【问题标题】:How can this be shortened?这怎么能缩短?
【发布时间】:2013-02-20 12:52:49
【问题描述】:

按 ID 有多个热点。 ID 特定的热点在鼠标悬停时显示一个区域(#ID-ed textarea),然后在鼠标移出时隐藏文本区域(注意 CSS display:hidden 比 hide 快得多)。大约有 50 个。我已经详细地写了这个 - 也就是每个人的函数。

想学习一种更好、更明智、更高效、更短的方法来做到这一点。

    //// POP 1_1
$('#pop_01_01').hover(
    function() {
    $('#text_01_01.textarea').fadeIn('fast');          
    },
    function() {
    $('#text_01_01.textarea').css({'display':'none'});
    }
);
//// POP 02_01
$('#pop_02_01').hover(
    function() {
    $('#text_02_01.textarea').fadeIn('fast');          
    },
    function() {
    $('#text_02_01.textarea').css({'display':'none'});
    }
);
//// POP 02_01
$('#pop_02_02').hover(
    function() {
    $('#text_02_02.textarea').fadeIn('fast');          
    },
    function() {
    $('#text_02_02.textarea').css({'display':'none'});
    }
);
//// POP 02_03
$('#pop_02_03').hover(
    function() {
    $('#text_02_03.textarea').fadeIn('fast');          
    },
    function() {
    $('#text_02_03.textarea').css({'display':'none'});
    }
);

【问题讨论】:

  • 没有看到您的 HTML,这很难回答。
  • 旁注:使用.hide() 而不是.css({'display':'none'})。它更短。
  • 欣赏 hide() 的想法,但是 hide() 明显变慢并导致眨眼。已经对此进行了测试并由其他人验证。仅供参考,希望这对某人有所帮助。
  • 我对上述关于隐藏的评论表示歉意。通过缩短每个 jfriend00 的代码,hide() 现在可以隐藏而不会眨眼。我原来的冗长代码要慢得多。

标签: jquery function mouseover jquery-hover mouseout


【解决方案1】:

您可以执行以下操作:

  1. 将具有此行为的所有对象组合到一个 jQuery 选择器中,以便它们都可以运行相同的代码。
  2. 从选择器中删除 textarea,因为 id 无论如何都是 unqiue,所以不需要它,没有它应该会更快。
  3. 从被悬停的对象的 id 中提取您想要的 id 并抓取结束字符,以便您可以使用它来创建您想要的其他 id。
  4. 使用.hide() 而不是.css({'display':'none'}); 作为内置快捷方式。

结果代码:

$('#pop_01_01, #pop_02_01, #pop_02_02').hover(
    function() {$('#text_' + this.id.substr(-5)).fadeIn('fast');},
    function() {$('#text_' + this.id.substr(-5)).hide();}
);

【讨论】:

  • 每个人的反应都很棒 - 谢谢大家。考虑到用于可点击对象的命名约定,这种方法似乎是最严格的。谢谢 jfriend00。
【解决方案2】:

使用这样的函数:

function makehover(myid)
{
  $('#pop'+myid).hover(
      function() {
      $('#text'+myid+'.textarea').fadeIn('fast');          
      },
      function() {
      $('#text'+myid+'.textarea').css({'display':'none'});
      }
  );

然后调用

 makehover('_01_01');
 makehover('_02_01');
 makehover('_02_02');

或通过 jQuery 调用

 $.each(['_01_01','_02_01','_02_02'],function (a,b) { makehover(b); });

或通过 (1.6+ javascript) 调用

 ['_01_01','_02_01','_02_02'].map(function (a) { makehover(a); return a; });

等等

【讨论】:

    【解决方案3】:

    如果你想用 jquery 的方式来做,考虑一下:

    $.fn.makeHover = function() {
        this.each(function() {
            var $el = $(this),
                $textarea = $el.find('textarea');
    
            $el.hover(
                function() {
                    $textarea.fadeIn('fast');
                },
                function() {
                    $textarea.hide();
                }
            );
        });
    };
    
    $('#pop_01_01, #pop_02_01, #pop_02_02, #pop_02_03').makeHover();
    

    顺便说一句,我还缓存了$el$textarea 以避免一直通过DOM(以提高性能)。

    【讨论】:

    • 缓存 $(this) 如何提高性能?它只是复制参考资料...
    • @Pawel_W 我很确定缓存$(this) 会提高性能,但在您发表评论后尝试进行一些性能测试,看来您是对的。 jsperf.com/caching-this-jquery 。谢谢!
    【解决方案4】:

    执行此操作的最佳方法是按类而不是 id 引用您的项目,并将相关部分(01_01、01_02 等)存储在 data-id 属性而不是 id 中。

    HTML -
    <div class="pop" data-id="_01_01"></div>
    <div class="pop" data-id="_02_01"></div>
    <div class="pop" data-id="_02_02"></div>
    
    <textarea data-id="_01_01"></textarea>
    <textarea data-id="_02_01"></textarea>
    <textarea data-id="_02_02"></textarea>
    
    //// All pops
    $('.pop').hover(
        function(e) {
          var dataid = $(e.target).attr("data-id");
          $('textarea[data-id="'+dataid+'"]').fadeIn('fast');
        },
        function(e) {
          var dataid = $(e.target).attr("data-id");
          $('textarea[data-id="'+dataid+'"]').hide();
        }
    );
    

    这样的东西应该能够很好地应用于你的所有元素,不使用一堆丑陋的不必要的 id,并保持你的数据干净并与你的名字分开。

    在这里提琴 - http://jsfiddle.net/fGLnB/

    【讨论】:

    • 也非常喜欢这种技术。谢谢你。
    【解决方案5】:
    $('#pop_01_01, #pop_02_01, #pop_02_02').hover(
        function(){
            id = $(this).attr('id');
            $('#text'+id.substring(3,id.length)).fadeIn('fast');          
        },
        function(){
            id = $(this).attr('id');
            $('#text'+id.substring(3,id.length)).css({'display':'none'});
        }
    );
    

    我省略了 ".textarea" 类,因为 ID 应该是唯一的,所以没有理由额外使用类

    【讨论】:

      【解决方案6】:

      你可以这样做:

      var hotspots = ['01_01','02_01','02_02'];   
      hotspots.forEach(function(i) {
          $('#pop_' + i).hover(
              function() {
              $('#text_' + i + '.textarea').fadeIn('fast');          
              },
              function() {
              $('#text_' + i + '.textarea').css({'display':'none'});
              }
          );
      });
      

      【讨论】:

      • 这实际上不起作用,因为调用悬停回调时i 将没有正确的值。这需要一个闭包来冻结i 的正确值。
      • 嘿@jfriend00 感谢您指出这一点!我修复了一个实际工作的答案:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-03-13
      • 2020-10-08
      • 2022-01-24
      • 1970-01-01
      • 1970-01-01
      • 2022-01-04
      • 1970-01-01
      相关资源
      最近更新 更多