2016-07-29 78 views
4

我有一個循環來運行我的按鈕來給它一個懸停狀態,但我似乎無法知道如何修復函數內部的「我」,以便當它循環。好吧,這是解釋我想要實現的一種不好的方式,也許代碼會更清晰。循環和靜態編號

for (i = 1; i < 4; i++) { 
 
    $('#buttons #'+i).hover(function() { 
 
\t $(this).text(i); 
 
    }, function() { 
 
\t $(this).text('Button'); 
 
    }); 
 
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 

 
<div id="buttons"> 
 
    <h1 id="1">Button</h1> 
 
    <h1 id="2">Button</h1> 
 
    <h1 id="3">Button</h1> 
 
</div>

每個按鈕的懸停狀態被認爲分別表示1,2,3。

+0

對我來說,它看起來不錯。如果您的選擇器正在工作,您是否嘗試過? –

+0

是的,選擇器工作,因此所有3個圖像都有翻轉。但他們都翻轉到相同的第三張圖片。 含義迷上了1,2,3,但該功能的我的選擇,都停留在3 –

+1

你檢查,在事件處理程序的'this'值多少?你可以添加一個HTML代碼片段嗎? –

回答

3

如果您希望以與您當前的代碼類似的方式執行此操作,這非常簡單。只需在你的循環中調用函數,將其傳遞給i變量,並在該函數內設置hover()回調。你的代碼的唯一的變化是函數調用函數定義:

for (i = 1; i < 4; i++) { 
 
    setupHover(i); 
 
} 
 

 
function setupHover(i) { 
 
    $('#buttons #' + i).hover(function() { 
 
\t $(this).text(i); 
 
    }, function() { 
 
\t $(this).text('Button'); 
 
    }); 
 
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 

 
<div id="buttons"> 
 
    <h1 id="1">Button</h1> 
 
    <h1 id="2">Button</h1> 
 
    <h1 id="3">Button</h1> 
 
</div>

爲什麼這項工作在原來的不?請注意,循環運行時不會調用兩個hover()回調。當您將鼠標滑過元素時,它們被稱爲後面的

因此,原始版本for循環已經運行完畢,早在hover()回調被調用以響應鼠標移動之前。在這些回調運行之前,i變量已經具有4的最終值。

但是,通過調用循環內部的函數並將i傳遞到該函數中,被調用的函數會捕獲您傳入的變量的引用。需要注意的是setupHover()函數內iifor循環單獨的變量。它只是巧合,它具有相同的名稱,但它確實是一個獨立於每個函數調用的獨立變量。

閱讀上「的JavaScript倒閉潮」以獲取更多信息。

你也可以做同樣的事情在其他方面,如在其他答案在函數返回的另一功能的技術。在某些情況下,這是一種有用的方法,但是如果您只需要關閉,通常會過度。

任何函數調用可以創建一個封閉,所以你需要的只是一個簡單的替換循環體的一個函數調用 - 無論是外循環命名功能在我的例子,或者你所提到的你的評論,一個在循環中內聯調用的匿名函數。這是調用創建閉包的函數的行爲,無論您如何定義和調用該函數。

+1

我在這個問題中學到了很多東西!感謝大家的建議和鏈接。 @Michael Greary實際上在你的例子中,我可以不用調用setupHover函數,而是將它作爲一個未命名的函數來運行,並且在循環時運行它?有沒有技術上的原因,爲什麼不應該這樣做? –

+1

確實你是對的!你可以使用匿名函數並直接在循環中調用它。無論您是否像我的示例中調用命名函數一樣,也可以調用內聯的匿名函數。在這兩種情況下,都是調用創建閉包的函數的行爲。 (很高興你找到了我的答案和其他人的幫助 - 能夠聽到多個視圖並看到解決問題的不同方式是非常好的。) –

0

由於在循環結束時變量i的值爲4,所以懸停會爲您提供數字4,因此當懸停觸發時,您將獲得第4張圖像。你可以通過初始化循環後變量i作爲5來檢查,然後懸停時圖像將是s3-b5b.png

而不是使用循環,可以試試這個,

參考get the nth-child number of an element in jquery

$('#scene-3 .selection img').hover(function() { 
    $(this).attr('src', 'img/s3-b'+parseInt($(this).index() + 1)+'b.png'); 
}, function() { 
    $(this).attr('src', 'img/s3-b'+parseInt($(this).index() + 1)+'.png'); 
}); 
+0

實現這個結果的好方法!它也保存/刪除了循環。 但是我仍然想知道如何在運行時創建懸停函數嗯嗯..「 –

+0

」但我仍然想知道如何使我的靜態,當它運行到懸停函數創建循環。「請我不明白。您的變量i應該基於您懸停的元素進行動態調整,以便可以在循環創建的函數中使用它。 –

+0

感謝您的回覆!我將使用你的方法進行懸停。我的意思是,是否有任何方法可以讓每個i都固定在懸停功能中,這樣它就是1,2,3,而不是全部爲4. –

3

使用此解決它:

for (i = 1; i < 4; i++) { 
 
     $('#scene-3 .selection img:nth-child('+i+')').hover(
 
     (function (value){ 
 
      return function(){ 
 
      $(this).attr('src', 'img/s3-b'+value+'b.png'); 
 
      } 
 
     })(i) 
 
     ,(function (value){ 
 
      return function(){ 
 
      $(this).attr('src', 'img/s3-b'+value+'.png'); 
 
      } 
 
     })(i)); 
 
    };

欲瞭解更多詳情,請參閱thisthis issue on Stack overflow

+0

哇,真棒,漂亮的文章。這真是一個有趣的問題! –

+0

您可以進一步簡化。 '(function(value){return function(){...}})(i)''可以是'(value)=> function(){...}(i)' –

+0

看起來像在C#中的lambda# –

0

這可能不是您要查找的內容,但這是修復您的代碼的另一種方法。

在迭代中的「i」將在4月底,這就是爲什麼所有的按鈕都顯示4.如果您將其更改爲$(this).text(this.id);那麼它會工作

for (i = 1; i < 4; i++) { 
 
    $('#buttons #'+i).hover(function() { 
 
\t $(this).text(this.id); 
 
    }, function() { 
 
\t $(this).text('Button'); 
 
    }); 
 
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 

 
<div id="buttons"> 
 
    <h1 id="1">Button</h1> 
 
    <h1 id="2">Button</h1> 
 
    <h1 id="3">Button</h1> 
 
</div>

0

這裏是另一種方式,使其更加動態:

$(function() { 
 
    var buttonsSelectorString = '#buttons > h1'; 
 
    var defaultButtonText = 'Button'; 
 

 
    var iterator = function(index, element) { 
 
    var mouseEnterAction = function(event) { 
 
     $(event.target).text(index + 1); 
 
    }; 
 

 
    var mouseLeaveAction = function(event) { 
 
     $(event.target).text(defaultButtonText); 
 
    }; 
 

 
    $(element) 
 
     .on('mouseenter', mouseEnterAction) 
 
     .on('mouseleave', mouseLeaveAction); 
 
    }; 
 

 
    $(buttonsSelectorString).each(iterator); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 

 
<div id="buttons"> 
 
    <h1>Button</h1> 
 
    <h1>Button</h1> 
 
    <h1>Button</h1> 
 
</div>

您可以找到註釋的源代碼在這裏:http://codepen.io/anon/pen/WxKAKm