4

我有这个代码:

            $('.counter_d').mouseover(function() {
                   $('#description').html('Counter');
             });
            $('.selector_d').mouseover(function() {
                   $('#description').html('Selector');
             });
             $('.date_d').mouseover(function() {
                   $('#description').html('Date');
             });

还有更多,但我认为文件可以更小,甚至可以使用循环重复使用,但我无法将描述(HTML 方法)与选择器绑定。

我想使用这样的东西:

              var selectors=['.counter_d','.selector_d','.date_d'];
              var description=['Counter', 'Selector', 'Date'];


              for(var i=0; i<selectors.length; i++)
                 $(selectors[i]).mouseover(function() {
                   $('#description').html(description[i]);
                 });

有什么帮助吗?谢谢

4

6 回答 6

8
var selectors = {
    '.counter_d': 'Counter',
    '.selector_d': 'Selector',
    '.date_d': 'Date'
};


$.each(selectors, function (key, value) {
    $(key).mouseover(function () {
        $("#description").html(value);
    });
});

示例:http: //jsfiddle.net/andrewwhitaker/bS28q/

于 2012-09-09T01:21:55.877 回答
1

问题是在执行 mouseover 回调时变量i被分配给 3。
因为description[3]没有undefined分配新的 HTML。
Fiddle 使您的浏览器控制台能够读取 console.log!

我认为一个更优雅的解决方案是给 HTML 元素一个额外的属性description,并在 mouseover 回调中简单地做:

$('#description').html($(this).attr("description"));

(你在上面的小提琴中看到它)

在我看来,您甚至可以以更优雅的方式选择所有元素并摆脱循环,因为 jQuery 会为您处理这个问题:

$(".counter_d, .selector_d, .date_d").mouseover(function() {
    $('#description').html($(this).attr("description"));
});

更新的小提琴

于 2012-09-09T01:37:13.690 回答
1

由于已经给出了正确的解决方案(Andrew Whitaker 接受的答案是我最喜欢的),我实际上会告诉你你的代码有什么问题yoshi 的答案有一些线索,但没有详细解释)。

问题

问题是,即使i循环内的更改值在执行时i保持不变(与循环结束时相同for),但在执行事件处理程序时。

你的代码中真正发生了什么

证明看起来像这样(参见jsfiddle):

var selectors=['.counter_d','.selector_d','.date_d'];
var description=['Counter', 'Selector', 'Date'];

for(var i=0; i<selectors.length; i++)
    $(selectors[i]).mouseover(function() {
        $('#description').html(i); // i is always equal to 3
    });​

问题是事件处理程序i从外部范围使用,在处理程序执行时等于3. 因此,即使在i附加处理程序时变量具有您想要的值,该值也会在它们执行之前发生变化。

解决方案

为了解决这个问题,您可以稍微修改您的代码以使用匿名函数,这些函数通过传递正确的值来立即调用i

var selectors=['.counter_d','.selector_d','.date_d'];
var description=['Counter', 'Selector', 'Date'];
for(var i=0; i<selectors.length; i++)
    (function(i){
        $(selectors[i]).mouseover(function() {
            // i is the same as when the outer function was called
            $('#description').html(description[i]);
        });
    })(i); // executing function by passing current i
​

为了证明它工作正常:http: //jsfiddle.net/ZQ6PB/

看更多

循环内的 JavaScript 闭包 - 简单实用的示例

于 2012-09-09T07:13:28.803 回答
0

我会去做这样的事情:

var obj = {
    'a': 'content a',
    'b': 'content b',
    'c': 'content c'
};

$('.a,.b,.c').mouseover(function() {
    $('#d').html(obj[this.className]);
});​

演示

不太喜欢循环的想法,因为它使它的可读性大大降低。

UPD:您始终可以为更多类扩展解决方案

var obj = {
    '.a': 'content a',
    '.b': 'content b',
    '.c': 'content c'
};

var selector = Object.keys(obj).join(',');
$(selector).mouseover(function() {
    $('#d').html(obj['.' + this.className]);
});​

演示

于 2012-09-09T01:31:46.167 回答
0

看起来你的选择器都以 _d 结尾。我们可以执行以下操作似乎是合理的。

$('[class$=_d]').mouseover(function(){
    var str = $(this).prop('class').split('_')[0];
    var desc = str.charAt(0).toUpperCase() + str.slice(1);
    $('#description').html(desc);
});
于 2012-09-09T01:35:01.030 回答
0

如下构造 HTML(假设元素是跨度)...

<span class="d counter_d" data-desc="Counter">...</span>
<span class="d selector_d" data-desc="Selector">...</span>
<span class="d date_d" data-desc="Date">...</span>

... 允许 javascript 像这样简单:

var $description = $("#description");

$(".d").mouseover(function() {
    $description.text($(this).data('desc'));
});

类名 '.counter_d'、'.selector_d'、'.date_d' 是多余的,可以删除,除非出于其他原因需要它们 - 例如。造型。

当然,如果你有数百个这样的元素,那么手动编写 HTML 会很痛苦。使用另一种方法会更好。

于 2012-09-09T02:11:49.253 回答