Комментарии 78
Что есть 'чистый javaScript'?
jQuery — это не только методы для выборки
Речь тут только о селекторных функциях. AJAX и другое — это отдельная история.
Не сочтите за занудство, но это всё таки абсолютно разные вещи.
Плюс, было бы неплохо вводную в статью добавить, потому что всё прекрасно знают, что быстрее vanillajs ничего нет, но написать подобную обёртку для выборки элементов каждый может
Миграция в данном случае это метод и процесс, а не конкретная библиотека-заменитель.
Нужно переписать функции jQuery — ну да, это логично.
А что по поводу подводных камней, сложностей, каких то советов?
Вашу статью можно уместить в одно предложение 'Напишите функции, подобные существующим в jQuery и используйте их, вместо jQuery' — ок
С таким подходом, вы можете заменить jQuery в статье на что угодно (angular, knockout), раз вам не важно количество функции, тем более функция выборки везде есть, вот её и будем переписывать.
Вашу статью можно уместить в одно предложение 'Напишите функции, подобные существующим в jQuery и используйте их, вместо jQuery' — ок
Совершенно верно. Именно в этом смысл статьи.
Конечно с учетом того, что новые функции получаются на порядок производительней прежних и реализация их достаточно проста. Если вы можете добиться такого повышения эффективности и при переписывании angular или knockout и вам от них нужна только функция выборки, а не фреймворк — почему нет?
Совершенно верно. Именно в этом смысл статьи.
Был ли смысл целую статью писать?
Конечно с учетом того, что новые функции получаются на порядок производительней прежних и реализация их достаточно проста.
До тех по пока Вы не пишете сложных функций. Не для всех функции есть аналоги в чистом js.
Если вы можете добиться такого повышения эффективности и при переписывании angular или knockout и вам от них нужна только функция выборки, а не фреймворк — почему нет?
Может быть потому что я выигрываю в поддержке, мне проще найти разработчиков, знакомых с angular, а не с моей (или Вашей) поделкой. Angular протестирован, есть много людей, которые его поддерживают, огромный зоопарк компонентов готовых и т.д.
Даже если мне нужна небольшая страница, где никогда ничего развиваться не будет, я бы предпочёл использовать готовый продукт и сфокусироваться на бизнес логике, а не стотысячном переписывании существующего функционала
Конечно с учетом того, что новые функции получаются на порядок производительней прежних и реализация их достаточно проста.
Это возможно только при потере части функциональности. То есть все равно придется просмотреть весь старый код чтобы понять какими фичами можно будет пожертвовать.
addClass -> el.classList.add(className);
Я не понимаю, о чем вы говорите.
Про циклы говорит:
$('.foobar').addClass('bla')
или
Array.from(document.getElementsByClassName("foobar")).forEach(el => {
el.classList.add('bla');
});
Array.from(document.querySelectorAll('a'))
.forEach(el => {
el.classList.add('test');
el.classList.remove('test');
})
+ меня бесит порядок аргументов в jquery в функциях ex.: each(index, element)
Object.prototype.find = function(s){return this.querySelectorAll(s);}
Object.prototype.bind = function(cssSelectors,events,callback,debug=false){
events = events.split(',');
elements= this.find(cssSelectors)||this;
elements.forEach(element=>{
events.forEach(event=>{
element.addEventListener(event,callback);
if (debug) console.dir(element+' listen '+event);
});
});
}
document.bind('a,p','click,mouseup',(e)=>{});
Ну и в таком духе всё хождение по DOM'у можно задекорировать.
Object.prototype.on = function(f,c){return Array.from(this,(i)=>i.addEventListener(f,c));}
Object.prototype.find = function(s){return this.querySelectorAll(s);}
Object.prototype.first = function(s){if(!s) return this.firstElementChild;return this.querySelector(s);}
Object.prototype.next = function(){return this.nextElementSibling;};
Object.prototype.prev = function(){return this.previousElementSibling;};
Object.prototype.last = function(){return this.lastElementChild;};
Object.prototype.parents = function(cssSelectors){
if(!cssSelectors) return this.parentElement;
cssSelectors = cssSelectors.split(',');
const a=[];
for(let i=0;i<=cssSelectors.length;i++) {
var p=this.parentElement;
while(p){
if (p.matches(cssSelectors[i])) {a.push(p);}
p=p.parentElement;
}
}
return a;
};
Однако некоторые старые браузеры на данный момент все еще не поддерживают NodeList.forEach().
Я не то слово сказал. Вот правильное: exotic object.
Если у прототипа NodeList не объявлен внутренний метод [[DefineOwnProperty]] — то никаким полифилом вы метод forEach ему не добавите. Это возможно, к примеру, в старых версиях IE где объекты DOM были COM-объектами.
.each
появился раньше, чем .forEach
в Array.prototype
.Смысл приведенной в статье миграции — чтобы не переписывать весь код, по селекторам он обычно довольно объемный. А AJAX вызовов обычно немного, перевести их на fetch не должно составить труда.
// jQuery
$(selector).load(url, completeCallback)
// Native
fetch(url).then(data => data.text()).then(data => {
document.querySelector(selector).innerHTML = data
}).then(completeCallback)
В добавок почему сравнение идет с jQuery 2.0? Последняя версия 3.3.1 и между 2 и 3 версией огромная разница в скорости.
И примеры никудышные, попробуйте выбрать чистым JS вот такое:
$('#form[name*="regsitr"] .field-wrap:eq(4) :checkbox:checked')
jQuery выбирают для удобства разработки. Если вам нужна скорость, вы можете комбинировать стандартные функции и методы jQuery.
Но все эти «переходы» сразу прекращаются когда речь заходит о событиях…
$('.some-node').wrap('<div class="wrapper"></div>')
.fadeOut(function(event) {
$(this).closest('.wrapper')
.slideUp();
});
Причина — именно в его устаревших/маргинальных/нестандартных технологиях. У большинства они как заноза в заднице, но некоторым людям и компаниям они наоборот необходимы. И видели они ваш абстрактный прогресс в белых тапках, у них есть конкретные потребности.
В общем, ресурсы, рассчитанные на широкую аудиторию, вынуждены будут поддерживать IE ещё несколько лет.
Например, я продаю водяные краны. Ко мне на сайт заходит какой-то клерк из ЖЭКа со своего старенького пентиума и видит полностью поломаный сайт. Вы наверное думаете, что он сразу же поймёт, что проблема в его браузере? Да щас. Он решит, что сайт хлам и как пить дать контора раздолбайская. Больше того, он потом ещё своему начальнику скажет, что эта контора (как там она называется? забыл. да и черт с ней) гавно.
Зато на сайте чистенький ES6, ога.
Во-вторых, для таких случаев удобно делать отдельный шаблон с минимумом функциональности на дубовом HTML без шика. Наверно все CMS это позволяют (несколько шаблонов). Это опять же может быть проще, чем делать один шаблон для всех ПК.
В конструкторе класса желательно парсить sel, чтобы более эффективно применять querySelectorAll(), getElementsByClassName() и getElementById()Это прекрасно. Сколько оверхеда даст парсинг селектора?
function $ (selector) {
const chunks = selector.trim().split(/\s+/);
if (chunks.length === 1) {
const firstChar = chunks[0].charAt(0);
const word = chunks[0].slice(1);
if (firstChar === '#') {
return document.getElementById(word);
}
else if (firstChar === '.') {
return document.getElementsByClassName(word);
}
}
else {
return document.querySelectorAll(selector);
}
}
Думаю, что да, это будет медленнее.
А в реальности код будет ещё сложнее, потому что у меня не учтены по-нормальному атрибуты и ряд других нюансов.
Всю статью можно было заменить этой ссылкой: You Might Not Need jQuery
Только вот внезапно окажется, что не вся функциональность jQuery пишется в одну-две строчки:
// jQuery
$('.inner').wrap('<div class="wrapper"></div>');
// Native
document.querySelectorAll('.inner').forEach(el => {
const wrapper = document.createElement('div');
wrapper.className = 'wrapper';
el.parentNode.insertBefore(wrapper, el);
el.parentNode.removeChild(el);
wrapper.appendChild(el);
});
И если у нас реально много ручных DOM-манипуляций, то jQuery все еще остается хорошим выбором. Хотя лучше, конечно, взять какой-нибудь фреймворк из "большой тройки" :)
Наговнокодили, лишились кроссбраущерности, но выиграли пару наносекунд
Вариант миграции с JQuery на чистый Javascript