Добро пожаловать. В этой краткой статье я подробно расскажу о нескольких удобных реализациях, которые я использовал в своей работе за последние пару лет, которые включают воссоздание стандартных функций jQuery с помощью ванильного JavaScript.

Как вы, возможно, слышали в последние годы, в сети много говорилось о смерти jQuery и о том, что она может устаревать в ближайшем будущем. Хотя я, вероятно, не такой паникёр, как это, в моей компании мы чаще пытаемся работать без jQuery, где только можем, используя ряд новых API и методов массивов, предоставляемых нам JavaScript. Здесь я перечислю несколько примеров, которые я недавно придумал и которые оказались полезными (и некоторые бонусные конверсии ES5, если это касается вашего брифа).

Я предполагаю хорошее практическое знание как JS, так и jQuery, и не буду слишком подробно останавливаться на реализации этих методов. Такие сайты, как MDN и W3Schools, уже отлично с этим справляются.

1. Найдите в массиве, что такое :not()

Это тот, с которым я столкнулся совсем недавно, когда исходный код имел 2 массива значений и должен был возвращать только значения, НЕ представленные во втором массиве. Это было красивое и элегантное преобразование с использованием метода Array.prototype.filter() в ES5, который отлично поддерживается браузерами.

var arr1 = [1, 2, 3, 4];
var arr2 = [3, 4, 5, 6];
// jQuery approach
return $(arr1).not(arr2);
// Vanilla JS approach
return arr1.filter(elem => !arr2.includes(elem));
// ES5 conversion
return arr1.filter(function(elem) {
   return !arr2.includes(elem);
});
// result = [1, 2]

2. Поиск предка .closest()

Это невероятно полезная функция в jQuery, позволяющая пройти вверх по дереву DOM, чтобы найти ближайший элемент с выбранным селектором. И да, некоторые из вас вполне могут указать, что в JS уже есть нативный метод .closest(). Но если, как и я, вы были обременены задачей совместимости с IE11, то, боюсь, это вам не подойдет. Вместо этого мы будем использовать простой цикл while и метод .matches().

// jQuery approach
var ancestor = element.closest('.selector');
// Vanilla JS approach (No IE11 support)
var ancestor = element.closest('.selector');
// Vanilla JS + IE11 support
const closest = (elem, selector) => {
    while (elem) {
        if (elem.matches(selector)) {
            break;
        }
        elem = elem.parentElement;
    }
    return elem;
}
const ancestor = closest(elem, '.selector');
// ES5 conversion
function closest(elem, selector) {
    while (elem) {
        if (elem.matches(selector)) {
            break;
        }
        elem = elem.parentElement;
    }
    return elem;
}

3. Проверяем, есть ли что-то :visible

Селектор :visible отлично подходит только для выбора, скажем, входных данных, которые не скрыты и могут быть доступны пользователю. Чтобы воссоздать это, мы можем использовать свойства offsetHeight и offsetWidth, которые доступны на узлах DOM.

// jQuery approach
var visibleInput = $('input:visible');
// Vanilla JS approach
const visible = (elem) => {
    if (elem.offsetHeight > 0 || elem.offsetWidth > 0) {
        return elem;
    }
    return null;
}
const visibleInput = visible(document.querySelector('input'));
// ES5 conversion
function visible(elem) {
    if (elem.offsetHeight > 0 || elem.offsetWidth > 0) {
        return elem;
    }
    return null;
}
var visibleInput = visible(document.querySelector('input'));

4. Создание .clone()

Это наш способ создания быстрых клонов HTML-элементов, и он не сильно отличается между jQuery и vanilla JS. Однако я также подробно расскажу, как мы можем создавать клоны объектов. Достаточно легко создать поверхностный клон объекта с помощью Object.assign в JS, но для создания глубокого клона требуется немного больше размышлений.

// jQuery approach
var elemClone = $('.selector').clone();
// Vanilla JS approach ('true' param creates a deep clone)
var elemClone = document.querySelector('.selector').cloneNode(true);
// Cloning an object in jQuery (deep clone)
var obj = {
  id: 1,
  data: {
    env: 'production',
    dataType: 'json'
  }
};
var objClone = $.extend(true, {}, obj); // again, pass true for a deep copy
// Cloning an object in JavaScript (deep clone)
var obj = {
  id: 1,
  data: {
    env: 'production',
    dataType: 'json'
  }
};
var clone = {};
for (var key in obj) {
  if (obj.hasOwnProperty(key)) {
    clone[key] = obj[key];
  }
}

Надеемся, что эти краткие примеры дали некоторое представление о том, чего можно добиться, используя простой старый JavaScript, без необходимости загружать какие-либо дополнительные библиотеки. Хотя они могут показаться немного громоздкими по сравнению с ними, нам всегда нравится думать об этих ресурсах, сэкономленных за счет того, что jQuery не появляется на вкладке нашей сети больше, чем нам нужно. Если бы вы чувствовали себя действительно причудливо, вы могли бы даже использовать использование Object.prototype для создания этих новых методов, а затем вызывать их для элементов HTML, а-ля jQuery! Но, возможно, это лучше сохранить для другой статьи.

Удачного кодирования.