多个选择器或多个功能 - 任何效率提升?

时间:2010-07-30 06:18:40

标签: jquery jquery-selectors

我想知道是否可以使下面的代码更简洁:

 $('#americasTrigger').hover(
  function () {
          $('#americasImg').fadeIn()
      },
  function(){
          $('#americasImg').fadeOut()
  }
  );

$('#europeTrigger').hover(
  function () {
      $('#europeImg').fadeIn();
  },
  function(){
      $('#europeImg').fadeOut();
  }
  );    

$('#middleEastTrigger').hover(
  function () {
      $('#middleEastImg').fadeIn();
  },
  function(){
      $('#middleEastImg').fadeOut();
  }
  );    

//More etc

每个国家/地区名称保持不变,最后添加“触发器”或“Img”。这里有很多重复,这表明我不会采用这种最佳方式。

我有想法:

  • 创建案例场景,或
  • 以某种方式将选择器用于选择,使其成为一个字符串,拆分它的名称以捕获正在使用的国家,并将其应用于嵌套的fadeIn / Out函数,最后使用'Img'。

这可能还是我太过花哨了?

编辑1:非常感谢所有的回复,对于不发布HTML的道歉,我已经把这个吼了一下。 总之,我在bg图像(地球)上使用图像映射作为悬停触发器,用于淡入/淡出我绝对定位的悬停图像。

<div class="mapTub"> 

  <img src="images/transparentPixel.png" class="mapCover" usemap="#worldMap" width="524px" height="273px"/>

  <map name="worldMap" id="worldMap">
    <area id="americasTrigger" shape="poly" coords="1,2,3" href="#americas" />
    <area id="europeTrigger" shape="poly" coords="4,5,6" href="#europe" />
    <area id="middleEastTrigger" shape="poly" coords="7,8,9" href="#middleEast" />
  </map>

<img src="images/International_americas_dark.png" class="americas" id="americasImg" />
<img src="images/International_europe_dark.png" class="europe" id="europeImg" />
<img src="images/International_middleEast_dark.png" class="middleEast" id="middleEastImg"  />

</div>

Reigel的答案似乎就是去这里的方式,生病尝试报告回来,欢迎进一步的评论! :)

4 个答案:

答案 0 :(得分:2)

我,在不知道html的情况下,建议这......

$('#americasTrigger, #europeTrigger, #middleEastTrigger').hover(
    function () {
        var id = this.id;
        $('#'+id.replace('Trigger', 'Img')).fadeIn();
        //$('#'+id.slice('0',id.indexOf('Trigger'))+'Img').fadeIn();
    },
    function(){
        var id = this.id;
        $('#'+id.replace('Trigger', 'Img')).fadeOut();
        //$('#'+id.slice('0',id.indexOf('Trigger'))+'Img').fadeOut();
    }
);

您也可以按照以下评论中的Anurag建议使用.replace()


id ='europeTrigger';
alert(id.slice('0',id.indexOf('Trigger'))); // alerts 'europe'
// '#'+id.slice('0',id.indexOf('Trigger'))+'Img' is '#europeImg'

demo

答案 1 :(得分:2)

由于您似乎只访问unique ids,因此您最好选择使用lookup table IMO。

var lookmeup = [  [$('#americasTrigger'), $('#americasImg')],
                  [$('#europeTrigger'), $('#europeImg')],
                  [$('#middleEastTrigger'), $('#middleEastImg')]
               ];

$.each(lookmeup, function(index, element){
    element[0].hover(function(){
      element[1].fadeIn();
    }, function(){ 
      element[1].fadeOut();
    });
});

干的!一切都完成了!

以更有效的方式执行此操作的另一种方法是使用event delegation

如果您的所有hover元素都具有相同的TAG,则此方法可能很有用:

$(document.body).delegate('div', 'mouseenter', function(e){
     $('#' + e.target.id.replace(/Trigger/, 'Img')).fadeIn();
});

$(document.body).delegate('div', 'mouseleave', function(e){
     $('#' + e.target.id.replace(/Trigger/, 'Img')).fadeOut();
});

假设您的所有“hoverable”元素都是DIV个。您仍然应该为这些元素添加classname,以便只定位那些特定元素。

root element限制为delegate()非常有意义。在这里,我使用document.body .live()。关于.delegate()的好处是,如果您的悬停元素共享一个父节点,则可以在该节点上应用delegate()。以这种方式减少绑定的事件处理程序的数量

(2而不是6)。

答案 2 :(得分:0)

lol,看起来这可能与您的代码大小相同或更长,但绝对干燥。

感谢@Andy使用$(..).each指出了以前版本的性能损失。

var regions = ['americas', 'europe', 'middleEast'];

$.each(regions, function(region) {
    var trigger = id(region, 'Trigger');
    var image = id(region, 'Image');

    $(trigger).hover(
        effect(image, 'fadeIn'),
        effect(image, 'fadeOut'),
    );
});

function effect(selector, method) {
    return function() {
        $(selector)[method]();
    };
}

function id(prefix, suffix) {
    return '#' + prefix + suffix;
}

如果您可以更改HTML,我会将所有知识编码到页面本身,并使用jQuery来设置悬停事件。

<div class='trigger' data-image='#americasImg'>
   ..
</div>
<div class='trigger' data-image='#europeImg'>
  ..
</div>

的Javascript

function imageId(elem) {
    return $(elem).attr('data-image');
}

// Using the fade function from before
$('.trigger').hover(
    effect(imageId(this), 'fadeIn'),
    effect(imageId(this), 'fadeOut')
);

答案 3 :(得分:0)

或者,为了使事情变得更简单,例如,为每个图像添加一个名为“fadingImage”的标记类,然后使用此代码......

$('.fadingImage').hover( 
    function () { 
        $(this).fadeIn() 
    }, 
    function(){ 
        $(this).fadeOut() 
    } 
); 

这是有效的,因为所有图像,无论其ID如何,都以相同的方式处理,您真正需要做的是确定页面上的哪些图像需要连接悬停处理程序,这是通过以下方式完成的:标记类。如果它们不被用于其他任何东西,你甚至可以完全免除ID。

<强>更新 不,我已经醒了(谢谢jAndy&amp; Reigel!),我将修改我的帖子,以处理悬停的元素不是正在褪色的元素。

如果没有任何样本标记,我将不得不做出一些假设,但原始海报可能想要提供真正的标记,以便将事情放在上下文中。

<div>
    <span class="fadingTrigger">first text to hover over<span>
    <img class="fadingImage" src="..." alt="first image to be faded"/>
<div>
<div>
    <span class="fadingTrigger">second text to hover over<span>
    <img class="fadingImage" src="..." alt="second image to be faded"/>
<div>

$('.fadingTrigger').hover( 
    function () { 
        $(this).parent().find(".fadingImage").fadeIn() 
    }, 
    function(){ 
        $(this).parent().find(".fadingImage").fadeOut() 
    } 
); 

根据标记结构,找到与fadingTrigger关联的fadingImage的方法可能必须改变,但是通过一些定义良好的结构,它应该是可靠的。

我更喜欢使用这个方法而不是使用id数组来查找元素的原因是,对标记的任何添加都需要更改javascript - 如果动态生成标记,这将特别成问题。 javascript也可以动态生成,包含适当的值数组,但会违反DRY主体。