Основы
Существует две разные функции jQuery map()
: .map()
и $.map()
. Они выполняют похожие вещи, но над разными коллекциями. Вы используете первую форму, которая выполняет следующее:
- Перебрать объект jQuery (коллекцию, что угодно), для которого была вызвана функция. В данном случае это
$(this)
, то есть независимо от того, на что была вызвана функция .equalizeHeights()
... $('div')
: все элементы <div>
на странице (фух).
Создать массив с тем же количеством элементов, что и у объекта, к которому был вызван .map()
(помните, все div-ы на странице), чей элемент n th создается путем вызова обратный вызов - я доберусь через секунду - на элементе n th в целевом объекте jQuery. В данном конкретном случае этот обратный вызов является этой функцией:
function(i, e) {
return $(e).height();
}
Да, .map()
выглядит как .each()
, но есть ключевое отличие:
.each()
выполняет действие над каждым из элементов в коллекции; возвращаемое значение обратного вызова, переданного в .each()
, используется для определения продолжения итерации.
.map()
также выполняет действие с каждым из элементов в коллекции, но возвращаемое значение обратного вызова используется для генерации элемента в массивоподобном объекте, возвращаемого .map()
.
Ты все еще со мной?
jQuery-объекты похожи на массивы, но не являются массивами! Причина, по которой вы вызываете .get()
в конце вызова .map()
, заключается в том, чтобы превратить этот объект jQuery в истинный массив. Элементами этого массива являются значения, возвращаемые обратным вызовом.
Собираем все вместе
Эта функция устанавливает высоту каждого <div>
на странице на высоту самого высокого <div>
. Вот как:
$('input').click(function() { // bind a click listener to every <input> element
$('div').equalizeHeights(); // ...that will call the equalizeHeights() fn
// on all <div> elements when fired
});
Итак, заглянув внутрь определения equalizeHeights()
:
$.fn.equalizeHeights = function() {
// construct an array that contains the height of every <div> element
var two = $(this).map(function(i, e) {
return $(e).height();
});
return this.height( // set the height of element <div> element to...
Math.max.apply( // the largest value in...
this,two.get() // the array of height values
)
); // ...and finally, return the original jQuery object to enable chaining
}
Но как насчет constructor
бизнеса?
Как вы обнаружили, да, один - это объект (объект jQuery), а другой - массив. Вот почему вам нужен вызов .get()
, чтобы превратить массивоподобный объект в нечто, что Math.max()
может понять.
Вместо того, чтобы смотреть на свойство constructor
, вы можете использовать немного больше jQuery, чтобы выяснить, что именно вы смотрите:
console.log(two.jquery); // the version of jquery, something like "1.4.4"
console.log($.isArray(two)); // is it a plain old JS array? false
console.log(two.get().jquery); // undefined! it's just an array.
console.log($.isArray(two.get())); // true
Еще лучше смотреть на реальные объекты внутри отладчика, а не просто console.log()
-из них. Таким образом, вы можете увидеть весь граф объекта, все его свойства и т. Д.
Есть вопросы? Комментарий прочь.