Как к каждому элементу массива прикрепить функцию?
так происходит из-за того, что все ваши обработчики смотрят на одну и ту же i, т.к. она находится в их общйе области видимсти. когда цикл отработает она будет для всех обработчиков равна 2. чтобы исправить это, нужно замкнуть каждый обработчик на своей i. 
сделать это можно несколькими способами:
1. инициализируйете счетчик через let:for(let i = 0; i < btn.length; i++) {...}
2. вешайте обработчик внутри iife:for(var i = 0; i < btn.length; i++){
  (function(i) {
    btn[i].onclick = function(e){e.target.style.marginLeft = i * (10) + 'px';}
  })(i)
}
3. forEach()btn.forEach((el, i) => {
  el.onclick = function(e){e.target.style.marginLeft = i * (-100) + '%';}
})
Смотрите первый комментарий к вашему вопросу.
Это будет работать потому что у вас i действует в области видимости вне тела цикла. А если ее объявить как let, то она будет доступна только в области видимости в которой объявленна (то есть в теле цикла) и каждую итерацию цикла будет создаваться новая i, значение которой сохраниться в добавляемой функции как замыкание.