Автор оригинала: FreeCodeCamp Community Member.
Курт
JavaScript Frameworks – это ярость. Скорее всего, любой JavaScript, связанный с новостными новостями, которых вы открыты, будут заселены ссылками на инструменты, такие как inventjs, angularjs, meteor, ristjs, backbonejs, jquery и за его пределами.
Любой, кто учится коду (и даже опытные разработчики), почувствует огромное давление, чтобы узнать эти новые инструменты. Сышась создает спрос. Если вы не в курсе того, что пользуется спросом, он может чувствовать, что ваши услуги не востребованы.
Я заметил тенденцию, где люди дайвинг головой в изучении этих инструментов, не зная Что они делают, не говоря уже о … Как они это делают. Это в конечном итоге делает отладки и концептуализацию указанного инструмента исключительно сложно. Есть тысячи случаев неправильного использования, где целые проекты создаются просто для двухстороннего привязки данных или для эффекта анимации или даже просто для отображения слайдера изображений.
Разработчики пренебрегают изучением самого дома
Дом или Модель объекта документа Сердце и душа вашего веб-браузера. Вы смотрите на это прямо сейчас. Чтобы уточнить, DOM не является особенностью JavaScript – его даже не написано в JavaScript – это интерфейс программирования, API между языком и браузером. Вычисление языковых элементов управления и т. Д., Дисплей и события элементов управления браузерами.
Я собираюсь продемонстрировать ниже, как создать простую библиотеку манипулирования DOM JQUERY. Это сможет нацелить элементы, используя знаменитый $ селектор, создают новые элементы, добавьте HTML, а также связывание событий управления.
Начиная
Нам нужно создать наш базовый объект. Давайте назовем это Доменение Отказ Этот объект будет действовать как обертка для целевых элементов.
var domElement = function(selector) { this.selector = selector || null; //The selector being targeted this.element = null; //The actual DOM element };
Теперь мы можем начать добавлять функциональность.
Методы jQuery Мы будем реплицироваться селектор/создатель $ () .on (), .off (), .val (), .append, .prepend () и .html ()
Давайте сначала погрузиться в связывание события. Это безусловно, самый сложный метод, который мы создадим, а также наиболее полезным. Это клей в двухсторонней модели передачи данных. (Модель обновляет своих подписчиков, когда срабатывает событие, такое как обновление, а подписчики также делают.)
Мы будем использовать Опубликовать/Подписаться Дизайн Отказ
Когда .on (событие, обратный вызов) называется мы Подписаться на мероприятие и аналогично, когда .off (событие) называется мы Отписаться от мероприятия.
Обработчик событий будет его собственным объектом.
Давайте начнем с создания базового объекта и расширение прототипа Доменение с этим.
domElement.prototype.eventHandler = { events: [] //Array of events & callbacks the element is subscribed to. }
Отлично, теперь давайте создадим наш метод подписчика. Мы назовем это BindEvent Поскольку он связывает слушатель события на нашему элементу DOM.
domElement.prototype.eventHandler = { events: [], //Array of events the element is subscribed to. bindEvent: function(event, callback, targetElement) { //remove any duplicate event this.unbindEvent(event,targetElement); //bind event listener to DOM element targetElement.addEventListener(event, callback, false); this.events.push({ type: event, event: callback, target: targetElement }); //push the new event into our events array. } }
Вот и все! Давайте быстро сломаем функцию
- Мы удаляем все существующие события на элементе, которые имеют тип, который связан. Это чисто вопрос личных предпочтений. Я предпочитаю сохранить сингулярные обработчики событий, так как их легче управлять и отладки. Удаление линии позволит нескольким обработчикам того же типа. Мы создадим невывинно функционировать чуть позже.
- Мы связываем событие к элементу DOM, заставляя его жить.
- Мы нажимаем событие и всю свою информацию в массив событий, чтобы элемент мог отслеживать наших слушателей.
Теперь, прежде чем мы сможем удалить событие, нам понадобится способ найти и вернуть его из массива событий, если он существует. Давайте создадим быстрый способ найти и вернуть событие по его типу, используя встроенный Массивный фильтр метод.
domElement.prototype.eventHandler = { events: [], //Array of events the element is subscribed to. bindEvent: function(event, callback, targetElement) { //remove any duplicate event this.unbindEvent(event,targetElement); //bind event listener to DOM element targetElement.addEventListener(event, callback, false); this.events.push({ type: event, event: callback, target: targetElement }); //push the new event into our events array. }, findEvent: function(event) { return this.events.filter(function(evt) { return (evt.type === event); //if event type is a match return }, event)[0]; } }
Теперь мы можем добавить наш невывинный метод.
domElement.prototype.eventHandler = { events: [], //Array of events the element is subscribed to. bindEvent: function(event, callback, targetElement) { //remove any duplicate event this.unbindEvent(event,targetElement); //bind event listener to DOM element targetElement.addEventListener(event, callback, false); this.events.push({ type: event, event: callback, target: targetElement }); //push the new event into our events array. }, findEvent: function(event) { return this.events.filter(function(evt) { return (evt.type === event); //if event type is a match return }, event)[0]; }, unbindEvent: function(event, targetElement) { //search events var foundEvent = this.findEvent(event); //remove event listener if found if (foundEvent !== undefined) { targetElement.removeEventListener(event, foundEvent.event, false); } //update the events array this.events = this.events.filter(function(evt) { return (evt.type !== event); }, event); } };
И это наш обработчик событий! Попробуйте это ниже …
Теперь это довольно полезная маленькая утилита, но вы, вероятно, задаетесь вопросом, что это связано с jQuery, и почему методы для обработчика события не называются «на» и «OFF».
Это то, что мы будем делать дальше. Поскольку нам требуется, чтобы обработчик событий быть объектом, и мы не хотим звонить $ («элемент»). EventHandler.on (..) Наши методы будут просто указывать на правильные функции.
Вот код для на и Выкл. Методы:
domElement.prototype.on = function(event, callback) { this.eventHandler.bindEvent(event, callback, this.element); } domElement.prototype.off = function(event) { this.eventHandler.unbindEvent(event, this.element); }
Посмотрите, как это работает? Теперь давайте добавим в нашу другие полезные функции …
domElement.prototype.val = function(newVal) { return (newVal !== undefined ? this.element.value = newVal : this.element.value); }; domElement.prototype.append = function(html) { this.element.innerHTML = this.element.innerHTML + html; }; domElement.prototype.prepend = function(html) { this.element.innerHTML = html + this.element.innerHTML; }; domElement.prototype.html = function(html) { if(html === undefined){ return this.element.innerHTML; } this.element.innerHTML = html; };
Это все довольно быстро. Единственный, кто обратил внимание на .html (). Этот метод может быть вызван двумя способами, если он называется без аргумента, он вернет innerhtml Для элемента, но если он называется с аргументом, он устанавливает HTML для элемента. Это обычно решается как Getter/Setter функция.
Инициализация
По инициализации нам нужно сделать одну из двух вещей …
- Если селектор начинается с открытого кронштейна ‘<‘ Мы wi LL CREA новый элемент.
- В противном случае мы будем использовать Document.Queryselector выбрать Существующие элемент.
С целью простоты я только делаю минимальный минимум только для проверки HTML в случае создания элемента и при выборе элемента, который я использую Document.Queryselector Это означает, что он вернет только один элемент (первый матч) независимо от объема матчей.
Это может быть изменено без особых усилий, чтобы выбрать все соответствующие элементы, используя Document.QuerySelectorall и рефакторирование методов для работы с элементом массива.
domElement.prototype.init = function() { switch(this.selector[0]){ case '<' : //create element var matches = this.selector.match(/<([\w-]*)>/); if(matches === null || matches === undefined){ throw 'Invalid Selector / Node'; return false; } var nodeName = matches[0].replace('<','').replace('>',''); this.element = document.createElement(nodeName); break; default : this.element = document.querySelector(this.selector); } };
Давайте пройдем по вышеуказанному коду.
- Мы используем Переключатель Заявление и передайте первый персонаж нашего селектора в качестве аргумента.
- Если он начинается с кронштейна, мы делаем быстрый Regex Сопоставить, чтобы найти текст между открытым и закрытым кронштейнами. Если это не удается, мы бросаем ошибку, что селектор недействителен.
- Если матч сделан, мы распределяем кронштейны и передаем текст на Document.Createlement создать новый элемент.
- В качестве альтернативы, мы ищем совпадение, используя Document.Queryselector Это возвращает NULL, если не найдено совпадение.
- Наконец, мы устанавливаем свойство Element на нашем Доменение к соответствующему/созданному элементу.
Использование $ для справки Доменя
Наконец, мы будем назначать символ $ для инициализации нового доменения.
$ = function(selector){ var el = new domElement(selector); // new domElement el.init(); // initialize the domElement return el; //return the domELement }
$ Символ – это просто переменная! Это наша завершенная jQuery – подобная библиотеке, как и все в 71 строках читаемого, хорошо разнесенного кода.
Вот ручка, управляющая полной библиотекой … Используйте вашу консоль.
Что делать дальше?
- Почему бы не пытаться воспроизвести ваши любимые функции утилиты?
- Нырять в Домочка
- Используйте слушатели событий, чтобы связать двусторонние данные.
Важные заметки
Особые благодаря Quincy Larson для гуманизации этого поста, исправляя мою мясолюбие английского языка, визуальные твики и отличное изображение заголовка.
Этот код был написан как простой пример, чтобы проиллюстрировать, как библиотеки JavaScript взаимодействуют с – и изменять – DOM. Это следует относиться как таковое.
Я использовал простые, четкие заявления, чтобы помочь читателям понять и следовать примерам, и слегка скинут вокруг – или полностью игнорируются – точки провала и валидации.
Возвращенный элемент будет иметь только созданные методы, связанные с оберткой. Вы можете получить доступ к фактическому элементу DOM и его методам, позвонив $ (‘селектор’). Элемент. Это следует избегать продления DOM, который является чувствительной темой, требующей собственного поста.
Если вы правильно соблюдали шаги, вы должны иметь заполненный файл, как приведен ниже:
var domElement = function(selector) { this.selector = selector || null; this.element = null; }; domElement.prototype.init = function() { switch (this.selector[0]) { case '<': var matches = this.selector.match(/<([\w-]*)>/); if (matches === null || matches === undefined) { throw 'Invalid Selector / Node'; return false; } var nodeName = matches[0].replace('<', '').replace('>', ''); this.element = document.createElement(nodeName); break; default: this.element = document.querySelector(this.selector); } }; domElement.prototype.on = function(event, callback) { var evt = this.eventHandler.bindEvent(event, callback, this.element); } domElement.prototype.off = function(event) { var evt = this.eventHandler.unbindEvent(event, this.element); } domElement.prototype.val = function(newVal) { return (newVal !== undefined ? this.element.value = newVal : this.element.value); }; domElement.prototype.append = function(html) { this.element.innerHTML = this.element.innerHTML + html; }; domElement.prototype.prepend = function(html) { this.element.innerHTML = html + this.element.innerHTML; }; domElement.prototype.html = function(html) { if (html === undefined) { return this.element.innerHTML; } this.element.innerHTML = html; }; domElement.prototype.eventHandler = { events: [], bindEvent: function(event, callback, targetElement) { this.unbindEvent(event, targetElement); targetElement.addEventListener(event, callback, false); this.events.push({ type: event, event: callback, target: targetElement }); }, findEvent: function(event) { return this.events.filter(function(evt) { return (evt.type === event); }, event)[0]; }, unbindEvent: function(event, targetElement) { var foundEvent = this.findEvent(event); if (foundEvent !== undefined) { targetElement.removeEventListener(event, foundEvent.event, false); } this.events = this.events.filter(function(evt) { return (evt.type !== event); }, event); } }; $ = function(selector) { var el = new domElement(selector); el.init(); return el; }
Если вам понравилось, этот пост посмотрите на некоторые другие вещи, которые я написал.
Профилактическое программирование – как исправить ошибки, прежде чем они произойдут … и почему Шерлок Холмс был бы блестящим программистом
5 вещей, которые нужно помнить, когда вы учитесь программировать Обучение программе является сложной. Помимо выбора языка или создания среды развития, которую вы …
Как я стал программистом. И когда я начал звонить в один Я хотел начать вести блог о программировании в течение нескольких месяцев и вроде так много других, прежде чем я, я надоел …
Делать его кодом дождя – матричный стиль Введение в HTML 5 Canvas Animations
Переключение кода наличными – как заработать деньги в качестве веб-разработчика и жить, чтобы рассказать историю. Так что вы только что научились кодировать. Вы хотите, и все, кто не умеет код думать, что ты гений, слово выходит и все … Medium.com.