LINUX.ORG.RU

Как ныне принято писать на js?

 , ,


4

2

Смотрю jquery вышел.. вот и захотелось спросить.

Как вы меняете содержимое страницы с помощью js (какими библиотеками пользуетесь, какие конструкции из этих библиотек применяете)?

В первую очередь мне интересно что называется шаблонизацией. Пользуетесь ли вы чем-то таким, как считаете, вообще, нужно/не нужно? Как формируете представление?

★★★★

Последнее исправление: post-factum (всего исправлений: 3)

Первое - jQuery, второе - jQuery-tmpl. Шаблоны определенно нужны, иначе получаются тонны html и конкатенаций в js, что во-первых уродливо и во-вторых неудобно ни для программиста, ни для верстальщика.

anonymous
()
Ответ на: комментарий от anonymous

jQuery вообще отличная вещь, если не подменять им знание js как такового.

anonymous
()

Как вы меняете содержимое страницы с помощью js (какими библиотеками пользуетесь, какие конструкции из этих библиотек применяете)?

Ищу в своих наработках. Если нужного не нахожу, пишу. Вот, кстати, недавно начал складывать в кучу всякие свои наработки. Все проще искать будет, если понадобится что.

А, да, насчет библиотек я соврал: одну таки применял — webGLU. Правда, ее допиливать пришлось.

Eddy_Em ☆☆☆☆☆
()

Шаблонизация редко нужна, только если осовная часть логики на клиенте. Обычно хвататет document.createElement и сахара над ним.

Kalashnikov ★★★
()

бекбоны разные, все что под ноду работает то и на клиент годится, jade и так далее, шаблон компилируется в жаваскрипт модуль, как обычно короче говоря. может чуть конкретизируешь вопрос, что всетаки интересно, риа или просто дата-биндинг объект-html? есть ангулярны разные и нокауты, и нокбеи и бекуляры, много его короче развелось ^_^

trashymichael ★★★
()

короче говоря в моих реалиях это часто полноценное приложение и рест-апи на сервере

trashymichael ★★★
()
Ответ на: комментарий от trashymichael

может чуть конкретизируешь вопрос

Просто хочу расширить кругозор. Я использую свой подход с блэкджеком, шлюхами и упором на скорость. Это близко к тому что сказал Kalashnikov

document.createElement и сахара над ним

Поэтому интересно именно то, что используется и часто.

special-k ★★★★
() автор топика
Ответ на: комментарий от special-k

ну createElement это для одного элемента подходит, а когда он сложный, дергать дом несколько раз (когда копируют или создают а потом через text() или html() заполняют) нерационально, тут уже в любом случае шаблонизатор. держать шаблоны в шаблоне (простите за каламбур) когда script id = 'template-foo' мне просто не нравится, особенно когда проект большой, кучку мелких файлов просто удобней майнтайнить, есть и другие причины, пока в голову не пришло, просто иметь шаблон-жаваскрипт функцию мне лично кажется более правильным

trashymichael ★★★
()
Ответ на: комментарий от special-k

и вот, я беру любой шаблонзатор например, в самом примитивном случае это underscore template, хотя, в самом примитивном случае я могу и зашить его в основной шаблон. либо через requirejs подтягивать нужные шаблоны, либо компилировать их при сборке проекта и держать в виде модулей

trashymichael ★★★
()
Ответ на: комментарий от trashymichael

ну createElement это для одного элемента подходит, а когда он сложный

ну.. не все так просто..

#вот это по сути шаблон
class Product extends RTW
  constructor: (@product = {})->
    self = @
    @dom = RT.div class: 'product', ->
      @h1 ->
        #прямо во время генерации сохраняем нужные объекты в свойства
        self.title = @tn self.product.title
      @p ->
        self.description = @tn self.product.description
      self.image = @img src: self.product.thumbUrl
      self.bigImageLink = @a href: self.product.imageUrl, ->
        @tn "View larger image"
      @form ->
        @label for: 'quantity', ->
          @tn 'Quantity'
        @input type: "text", name: "quantity", id: "quantity", value: 1
        @input type: "submit", value: "Add to Cart"

  #обновляем значения
  update: (@product)->
    @title.nodeValue = @product.title
    @description.nodeValue = @product.description
    @image.satr 'src', @product.thumbUrl
    @bigImageLink.satr 'href', @product.imageUrl
применяем это дело следующим образом
product = new Product someParams
product.update anotherParams

#Т.е. имеем следующее:
#создать один элемент
el = RT.div()

#создать div со span внутри
RT.div ->
  @span()

#весь прикол в совместимости элементов и тем, что я называю "виджеты", т.е.
#создать div с product внутри
RT.div().add product

#создать div со span и product внутри
RT.div ->
  @ins product
  @span()
  
Все это основанно исключительно на createElement без единного innerHTML или чего-то такого.

special-k ★★★★
() автор топика
Ответ на: комментарий от trashymichael

компилировать их при сборке проекта и держать в виде модулей

Можешь привести простенький пример того как выглядит скомпилированный вариант и как он используется?

special-k ★★★★
() автор топика
Ответ на: комментарий от special-k

дело в том что в каждом вызове апдейт (каждом изменении свойства дом узла и т.п.) происходит траверсинг по дереву, это не очень целесообразно, тем более когда менять нужно ВСЕ

пример вот https://github.com/visionmedia/jade#a15

trashymichael ★★★
()
Ответ на: комментарий от special-k

это обычно у меня вьюв у которого есть фу-я render и дата-биндинги для изменения данных

trashymichael ★★★
()

Как ныне принято писать на js?
В первую очередь мне интересно что называется шаблонизацией.

Геморроя добавишь, профита не получишь. Инфа 100%.

Deleted
()
Ответ на: комментарий от trashymichael

траверсинг

это поиск элементов который, да где ж.. идет прямое обращение к свойствам. Суть как раз в том, чтобы не было, ни поиска элементов, ни повторной инициализации сложного элемента.

special-k ★★★★
() автор топика
Последнее исправление: special-k (всего исправлений: 2)
Ответ на: комментарий от special-k

Ты что-то конкретное пишешь? Всё зависит от того что именно тебе надо. Если просто привесить кнопочку, createElement. Если динамически переставлять содержимое, засунь всё в хтмл и рули стилями (display/visibility) заполняя нужные элементы текстом. Если приложение работает на клиенет, а сервер - это рест апи отдающее заглушки на запросы, тогда шаблоны.

Kalashnikov ★★★
()
Ответ на: комментарий от Kalashnikov

Ты что-то конкретное пишешь?

Да, но и размышляю над методикой в целом.

Третье. Какую систему шаблонов предлагаешь?

special-k ★★★★
() автор топика
Последнее исправление: special-k (всего исправлений: 1)
Ответ на: комментарий от trashymichael

траверсинг по дереву

но если ты при использовании шаблонизации захочешь интерактивности, траверсинг не заставит себя ждать.

special-k ★★★★
() автор топика
Ответ на: комментарий от special-k

Никакую, я с ними почти не работал, не могу ничего советовать. Обычно шаблоны нужны одни на сервере и клиенте, от этого и стоит плясать (если не ноде конечно). maxcom вот недавно для явы искал например и нашёл видимо судя по ридонли апи.

Kalashnikov ★★★
()
Ответ на: комментарий от special-k

дело в том что когда ты обновляешь какое-то свойство дом элемента, цсс, или меняешь его содержимое, происходит обход дерева и рендеринг, т.к. стили каскадные и т.п. установи спидтест и убедись, это старая фича и отсюда растут корни у documentFragment

trashymichael ★★★
()
Ответ на: комментарий от trashymichael

потому сложные элементы выгодней отрендерить из шаблона, на интерактивность это никак не влияет, интерактивность это уже другое

trashymichael ★★★
()
Ответ на: комментарий от trashymichael

интерактивность это уже другое

Допустим, но тем не менее, когда, на уже отрендеренный элемент ты хочешь навесить событие, то как это обычно выглядит? Чем обычно выполняется поиск по элементам?

special-k ★★★★
() автор топика
Ответ на: комментарий от special-k

говорят делегирование быстрее работает чем непосредственно навешивание на закверинные элементы, как я уже писал, я активно использую бекбон, у класса вью там есть пропортя ивентов, которая делегируется отрендеренному элементу, что не выходит делегировать, навешивается в инициализаторе объекта

class MyView extends Backbone.View
  events:
    'click [data-submit]': 'submit'
    'click [data-reset]': 'reset'

причем эти обработчики автоматически биндятся к инстансу, тоесть можно делать $('.foo').click myViewInstance.submit, т.к. в конструкторе произошел _.bindAll(this, 'submit', 'reset') (считай @submit = _.bind @, submit, или this.submit = this.submit.bind(this) если уж совсем на чистом)

trashymichael ★★★
()
Ответ на: комментарий от trashymichael

но обычно я стараюсь все дробить на мелкие методы и выношу этот процесс (из инициализатора) в со-вующие методы, если класс маленький, то какие-то общие типа setupUi, bindUIEvents, если большой то по предметной области

trashymichael ★★★
()
Последнее исправление: trashymichael (всего исправлений: 1)
Ответ на: комментарий от trashymichael

классная штука, и недооцененная мной поночалу, нокаут, который делает биндинги модель-представление, есть порты nockback, но если проект маленький то можно взять что-то и для бекбона, т.к. нокаут махина

trashymichael ★★★
()
Ответ на: комментарий от trashymichael

Из делегирования мне непонятна одна вещь: как именно идет проверка селекторов на соответствие заданному, что за механизм там применяется.. просто, на сколько я знаю, нет в js такой функции, а сталобыть это какой-то костыль..

special-k ★★★★
() автор топика
Последнее исправление: special-k (всего исправлений: 1)
Ответ на: комментарий от special-k

Ты о каком делегирование? В jQuery проверяет sizzle вестимо.

У объекта события (который передаётся обработчикам) есть свойство target которое указывает на объект на котором произошло событие, его при делегировании и проверяют.

Kalashnikov ★★★
()
Последнее исправление: Kalashnikov (всего исправлений: 1)
Ответ на: комментарий от Kalashnikov

его при делегировании и проверяют

да, но как? Первое что приходит в голову - сделать запрос селектором, и поискать среди результатов таргет, это так делается?

special-k ★★★★
() автор топика
Последнее исправление: special-k (всего исправлений: 1)
Ответ на: комментарий от special-k

ну тут используется всплытие событий, все просто, ты делегируешь событие контейнеру-родителю, а в нем проверяешь цель, для которой событие реально сработало

я советую тебе с этим разобраться и начинать активно юзать, кроме того что это экономит, становится негласным стандартом, не даром в новом апи жквери стерты границы между биндингом и делегированием

trashymichael ★★★
()
Ответ на: комментарий от trashymichael

для всех кто затрудняется с делегированием привожу небольшой пример:

<!doctype html>
<head>
  <style type='text/css'>
    div {
      margin: 10px;
      padding: 10px;
      outline: dashed red 2px
    }
    [data-type=container] {
      background: rgba(255, 0, 0, .5)
    }
    [data-type=child] {
      background: rgba(0, 255, 0, .5)
    }
  </style>
</head>
<body>
<div data-type='container'>
  <div data-type='child'></div>
  <div data-type='child'></div>
  <div data-type='child'></div>
</div>
<script type='text/javascript'>
  window.addEventListener('load', function () {
    document.querySelectorAll('[data-type=container]')[0].addEventListener('click', function (event) {
      console.log(event.target)
    })
  })
</script>
</body>

попробуйте покликать по деткам

trashymichael ★★★
()
Ответ на: комментарий от Kalashnikov

т.е. все сводится к тому, что при делегировании проверяется какой-то атрибут таргета, верно?

special-k ★★★★
() автор топика
Ответ на: комментарий от special-k

да, вместо того чтобы бегать по элементам контейнера и навешивать на них событие ты навешиваешь его на контейнер, и при срабатывании проверяешь target на соответствие селектору

учитывая что элементов таких может быть очень много, и часто создаются они динамически, это более выгодно

trashymichael ★★★
()
Ответ на: комментарий от trashymichael

под костылем я имел ввиду

проверяешь target на соответствие селектору

в примере ты никак не проверяешь, потому и нет)

И, предположим я согласен с Kalashnikovым, проверить атрибут несложно и быстро, но что там будет творить jquery.. боюсь оно шагнет гораздо дальше.

special-k ★★★★
() автор топика
Ответ на: комментарий от special-k

я залез в исходник и нашел что конкретно там происходит, чтоб это было не предположениями, хотя и достаточно обоснованными

исключая всякую мишуру, если у биндинга есть селектор и он определен как делегат, при срабатывании события происходит конкретно поиск элемента в контейнере

<!doctype html>
<head>
  <style type='text/css'>
    div {
      margin: 10px;
      padding: 10px;
      outline: dashed red 2px
    }
    [data-type=container] {
      background: rgba(255, 0, 0, .5)
    }
    [data-type=child] {
      background: rgba(0, 255, 0, .5)
    }
  </style>
  <script src='http://code.jquery.com/jquery-1.9.0.min.js'></script>
</head>
<body>
<div data-type='container'>
  <div data-type='child'></div>
  <div data-type='child'></div>
  <div data-type='child'></div>
</div>
<script type='text/javascript'>

  window.addEventListener('load', function () {
  
    var container = document.querySelectorAll('[data-type=container]')[0]
  
    container.addEventListener('click', function (event) {
    
      console.log($('[data-type=child]', container).index(event.target) >= 0 ? 'Работаем' : 'Отдыхаем')
      
    })
    
  })
</script>
</body>

цитируя дословно

jQuery( sel, this ).index( cur ) >= 0
trashymichael ★★★
()
Последнее исправление: trashymichael (всего исправлений: 1)
Ответ на: комментарий от trashymichael

поиск элемента в контейнере

Т.е. вместо того, чтобы сканировать один раз, ты предлагаешь сканировать каждый раз, думаешь это хорошо? Или можно поставить вопрос по-другому, что может быть хуже, чем сканировать каждый раз?)

special-k ★★★★
() автор топика
Последнее исправление: special-k (всего исправлений: 1)
Ответ на: комментарий от special-k

тут как посмотреть, если собрать статистику соотношения того сколько раз ты проводишь «сканирование» к тому сколько раз реально эти биндинги используются, выводы могут быть совсем другие

trashymichael ★★★
()
Ответ на: комментарий от special-k

и во вторых это предлагаю не я, я лишь передаю тебе заветы прогрессивного сообщества, а со своим фи можешь обратиться на всякие хакерньюсы

trashymichael ★★★
()
Ответ на: комментарий от special-k

в итоге все сводится к тому что ты представляешь интерфейс как некую кнопочку на которую можно нажать, а не как сложный набор кнопочек, состояние которых зависит друг от друга

trashymichael ★★★
()
Ответ на: комментарий от trashymichael

со своим фи

Причем тут фи. Можно так, можно эдак - это нормально.

Так, я написал небольшой бенч https://gist.github.com/4556709, где генерация объектов противопоставляется шаблонам (точнее использованию underscorejs + jquery).

Ситуация следующая:

      объекты                       шаблоны
      создание        обновление    создание
ff    190ms           6ms           313ms
crome 135ms           3ms           256ms
opera 265ms           24ms          432ms
Я считаю, бенч показывает, что методика обновления фрагмента необходима, и если из-за двухкратного профита парится может и не стоит (хотя фф и рендерит объектами быстрее чем хром шаблонами), но вот ради 50-кратного, думаю можно и заморочиться. И, на сколько я понимаю, underscorejs - одна из самых быстрых библиотек, не так ли.

Причем сравнение не совсем коррекно, потому что в одном случае мы получаем полноценный объект с нужной нам логикой, то в другом просто объект jquery.

special-k ★★★★
() автор топика
Последнее исправление: special-k (всего исправлений: 1)
Ответ на: комментарий от Kalashnikov

классы для стилей, можно делать js-* классы, но мне так больше нравится

trashymichael ★★★
()
Ответ на: комментарий от special-k

функция шаблонизации в underscore самая примитивная. как я писал выше, компилирую я шаблоны на стадии сборки проекта, в итоге рендеринг это грубо говоря просто вызов функции

function person(firstName, lastName) {
  return '<h1>' + firstName + ' ' + lastName + '</h1>'
}

+ экранирование

лень вникать в твои бенчи, но ими ты только вводишь людей в заблуждение. и про какие полноценные и неполноценные объекты говоришь мне совсем не понятно, ты разделяешь данные от представления или нет?

trashymichael ★★★
()
Последнее исправление: trashymichael (всего исправлений: 1)
Ответ на: комментарий от special-k

все твои выводы основаны на том что виджет = тег, представь себе шаблон этой формы ответа, например, как ты будешь ее создавать, генерировать отдельно каждый тег, собирать и т.д.?

trashymichael ★★★
()
Ответ на: комментарий от special-k

тебе этот «полноценный объект» в общем случае до полной фени, у тебя должна отдельно модель быть и отдельно представление, то что ты приводишь это лапша натуральная

потом представь что у тебя 500 продуктов, и твои 190 мс плавно умножаются в 500 раз, а мои строки конкатенируются и потом создается дом, но это конечно розовые очки

trashymichael ★★★
()
Последнее исправление: trashymichael (всего исправлений: 2)
Ответ на: комментарий от trashymichael

ты разделяешь данные от представления или нет

Да, коль скоро представление это css. Но, думаю, ты имеешь ввиду другое, что-то вроде mvc, и сейчас нет, потом посмотрим. Но фишка в том, что это mvc - довольно забавный перенос серверных методик на клиент. Относительно браузера дом элемент - это полноценный объект, с состоянием, с методами и много чем, а не текст. Работу с dom деревом как с текстом надо критиковать я считаю. Она _медленная_ и неудобная. «Делегация» про которую ты говорил как раз следствие этой неудобности. Я не имею ничего против «делегации», я просто говорю откуда ноги растут.

Существование модели на сервере обуславливается сложностью работы с БД, на клиенте ее существование вряд ли чем-то обусловлено, хотя здесь можно спорить. Пока мне хватает обсервера внутри объекта.

но ими ты только вводишь людей в заблуждение

Генерирую одинаковые фрагменты разными способами, один быстрее, другой медленнее, что тут непонятного. Один позволяет (например) обновить объект (очень быстро, и ооочень много чего еще), другой только повторную генерацию (за то же время).

компилирую я шаблоны

время компиляции шаблона не учитывалось, только превращение оного сначала в текст, а затем в dom-елемент.

представь себе шаблон этой формы ответа

Ну представил, просто объект, в конструкторе которого генерируется dom-структура.

собирать

что это означает?

special-k ★★★★
() автор топика
Последнее исправление: special-k (всего исправлений: 2)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.