多个选择器或多个函数 - 有效率提升吗?

发布于 2024-09-11 17:22:26 字数 1674 浏览 2 评论 0 原文

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

 $('#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

每个国家/地区名称保持不变,并在末尾添加“Trigger”或“Img”。这里有很多重复,这表明我并没有采用最好的方法。

我的想法是:

  • 创建一个案例场景,或者
  • 以某种方式获取用于选择的选择器,使其成为一个字符串,分割它的名称以捕获正在使用的国家/地区,并将其应用到带有“Img”的嵌套淡入/淡出函数结束。

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

编辑1:非常感谢您的所有回复,很抱歉没有发布 html,我已将其放在下面。 简而言之,我在(地球的)背景图像上使用图像映射作为悬停触发器来淡入/淡出我的绝对定位的悬停图像。

<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>

雷格尔的回答似乎是正确的选择,我会尝试一下并报告,欢迎进一步评论! :)

I'm wondering if its possible to make the following code more concise:

 $('#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

The country name stays the same for each, with 'Trigger' or 'Img' added to the end. There's a lot of repetition here which indicates to me I'm not going about the this best way.

I had thoughts around:

  • Crearting a case scenario, or
  • Somehow getting the selector being used for a selection, making it a string, splitting it's name to capture the country in use and applying that to the nested fadeIn/Out function with 'Img' on the end.

Is this possible or am I being too fancy?

Edit 1: Thanks verymuch for all the responses, apologies for not posting the html, i've put this bellow.
In short I'm using image maps over a bg image (of earth) as the hover triggers for fading in/out my absolutely positioned on-hover images.

<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's answer seems like the way to go here, ill try it out report back, further comments welcome! :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

困倦 2024-09-18 17:22:26

我,在不了解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();
    }
);

您也可以按照.replace() >Anurag 在下面的评论中...


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

演示

Me, without knowledge of the html, suggest this...

$('#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();
    }
);

You can also use .replace() as suggested by Anurag in the comment below...


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

demo

蓝眸 2024-09-18 17:22:26

由于看起来您只访问唯一的 id,因此您最好的选择是使用查找表 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();
    });
});

干燥!全部完成!

另一种更有效的方法是使用事件委托

如果所有 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,以便仅针对那些特定元素。

限制 delegate()根元素非常有意义。这里我使用 document.body ,它会使用 .live() 来实现。 .delegate() 的一大优点是,如果您的悬停元素共享一个父节点,您可以在该节点上应用 delegate() 。通过这种方式,您可以减少绑定的事件处理程序的数量

(2 个而不是 6 个)。

Since it looks like you are accessing only unique ids, your best choice is to use a 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();
    });
});

DRY! all done!

Another way to do it in a more efficient manner would be to use event delegation.

If all of your hover elements have the same TAG, this approach could be useful:

$(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();
});

Assuming that all your "hoverable" elements were DIVs. You still should give those elements a classname so that only those specific elements are targeted.

It makes a lot of sense to confine the root element for delegate(). Here I use document.body which would .live() do. The great thing about .delegate() is, that if your hover elements share one parent node, you can apply delegate() on that node. In that manner you reduce the number of event handlers bound

(2 instead of 6).

蹲在坟头点根烟 2024-09-18 17:22:26

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

感谢 @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')
);

lol, looks like this may be about the same size or longer than your code, but definitely dryer.

Thanks to @Andy for pointing out the performance penalty with the previous version using $(..).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;
}

If you can change the HTML, I would encode all knowledge into the page itself, and just use jQuery to setup hover events.

<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')
);
鹤仙姿 2024-09-18 17:22:26

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

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

这是有效的,因为所有图像,无论其 id 如何,都在同样,您真正需要做的就是确定页面上的哪些图像需要附加悬停处理程序,这是通过标记类完成的。如果 id 不用于其他用途,您甚至可以完全放弃它们。

更新:
不,我已经醒了(感谢 jAndy 和 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 原则。

Or, to make things much simpler, add a marker class, called 'fadingImage' for example, to each of the images and then use this code...

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

This works because all of the images, regardless of their id, are handled in the same way, al that you really need to do is identify which images on your page need to have the hover handlers attached, and this is done with the marker class. You might even be able to dispense with the ids altogether, if they aren't used for anything else.

Update:
No that I've woken up (Thanks jAndy & Reigel!), I'll amend my post to deal with the fact that the element being hovered is not the one that is being faded.

Without having any sample markup, I'm going to have to make some assumptions, but the original poster may want to provide the real markup, in order to put things in context.

<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() 
    } 
); 

Depending on the markup structure, the method of finding the fadingImage that is associated with the fadingTrigger may have to vary, but by having some well defined structure, it should be reliable.

The reason why I'd prefer this method over using an array of ids to lookup the elements is that any additions to the markup would require changes to the javascript - this would be especially problematic if the markup is dynamically generated. The javascript could be dynamically generated too, to include the appropriate array of values, but the would violate the DRY principal.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文