Как стать автором
Обновить

Комментарии 28

Если взять слишком много строк (например, 100000) — то после каждого изменения перестают работать скрол и нажиматься кнопки на клавиатуре.

Интересно, можно ли это считать багом?

Конечно, это из-за того, что налету генерировался огромный CSV файл. Сделал, чтобы ссылка генерировалась лишь по клику на кнопку скачивания, а не сразу при изменении формул.

А вот это уже баг.


Если написать вот такие формулы:


A1 = B1+1
B1 = A1+1


то в соответствующих ячейках будет сообщение об ошибке.


Теперь меняем B1 на что-нибудь нормальное… и сообщение об ошибке из A1 не пропадает!


Более того, кнопка скачивания тоже превращается в сообщение об ошибке (но нажимается).

Оказывается $mol_atom неправильно восстанавливался после циклической зависимости. Уже поправлено.

Если в таблице высота строк одинаковая, то можно такой скролл запилить: jsfiddle.net/lega911/mchdL1ca

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

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

Потому что используется аппаратная прокрутка (не отключаемая на мобилках), а перемещение плавающих блоков происходит асинхронно по событию скролла. Если их не прятать, то они будут неприятно "прыгать" при прокрутке.

эээ, не понял, причем тут срол? Это же явно «особенность/косяк» реализации $mol_float, обычно sticky-блоки не исчезают при прокрутке, а корректно перемещаются под её воздействием.

Как бы вы реализовали $mol_float?

По возможности использовал бы position: sticky, иначе scroll & resize + getBoundingClientRect и всё это приправленно throttle, как обычно короче.

По возможности использовал бы position: sticky

Если бы он ещё везде работал для ячеек таблиц.


иначе scroll & resize + getBoundingClientRect и всё это приправленно throttle

$mol_float так и работает. Но если его не прятать при скроллинге — он будет прыгать, ибо событие скролла срабатывает асинхронно прокрутке.

Странно, у всех не прыгает, а у вас прыгаете, тут либо задержка большая, либо код тормозит. Обычный throttling на 16-30ms и никакого дергания.

У нас тоже не прыгает, если скроллинг отрабатывает не аппаратно. Например, если тягать за скроллбар в десктопном хроме.

Я бы не прятал заголовки строк если прокрутка вертикальная.

Хорошая идея. Сделал, чтобы плавающий блок прятался только, если направление "плавания" совпадает с направлением прокрутки.

В вашей реализации фокус уплывает
Да я в курсе, просто выложил показать идею скрола, 30 строк кода, а не готовый excel.

Первая годная статья по $mol, к концу наконце-то смог въехать в tree (чуть-чуть), но code style как был «кровь, кишки, расчленёнка», так и остался.


Но остался вопрос, позволяет-ли $mol писать компоненты, которые будут встриваться в уже готовый проект. Например хочу «форму Входа» и кнопку «Наверх» (с произвольным обработчиком onClick)?

Синтаксис и кодинг стайл — самая главная проблема mol, из-за которой его даже пробовать не хочется(((( Помнится jquery всегда любили не столько за кросс-браузерность, сколько за апи. Если в мире останутся только mol и jquery, я буду писать долго и дорого, но на последнем.

Конечно позволяет. Например, хотите вы выводить markdown, но не хотите заморачиваться с его парсингом. Для этого можно воспользоваться компонентом $mol_text. Как это сделать...


Собираем независимый бандл с этим компонентом:


npm start mol/text

В директории mol/text/- появятся следующие файлы:


  • web.js — скрипты
  • web.d.ts — определения типов для typescript
  • web.css — стили

Подключаем их к странице и рендерим нужный текст:


<link rel="stylesheet" href="text/web.css" />
<script src="text/web.js"></script>
<body>
<script>

    // Создаём реактивную переменную
    var text = new $mol_atom( 'text' , ()=> 'Текущее время *ещё не установлено*...' )

    // Периодически меняем текст
    setInterval( ()=> text.push( `Текущее время: **${ new Date().toLocaleString() }**` ) , 1000 )

    // Создаём компонент
    var view = new $mol_text

    // Провязываем с нашей реактивной переменной
    view.text = ()=> text.get()

    // Указываем рендериться в body
    view.dom_node = ()=> document.body

    // Инициируем автоматический рендеринг
    view.dom_tree()

</script>

https://plnkr.co/edit/W15eZoL4aoZptX7oHyyO?p=preview

Так, а если таких компонентов N-штук (каждый в своём бандле), как мне их собрать, чтобы они включали в себя только свой код, а всё остальное было в $mol.bundle.js, а потом всё это добро можно было грузить асинхронно, например через SystemJS?


P.S. Можете сделать пример именно с кнопкой "Наверх" с определенным onClick/alter?

Так, а если таких компонентов N-штук (каждый в своём бандле), как мне их собрать, чтобы они включали в себя только свой код, а всё остальное было в $mol.bundle.js, а потом всё это добро можно было грузить асинхронно, например через SystemJS?

Зачем? Собирайте один бандл со всеми нужными вам компонентами. Вы совершенно ничего не выиграете от асинхронной загрузки $mol компонент, ибо они крайне маленькие.


Можете сделать пример именно с кнопкой "Наверх" с определенным onClick/alter?

Тут всё то же самое:


// Создаём компонент
var view = new $mol_button_major

// Клики обрабатываем по своему
view.event_click = event => document.body.scrollTop = 0

// Задаём название
view.title = ()=> 'Наверх'

// Рендерим в body
document.body.appendChild( view.dom_tree() )

https://plnkr.co/edit/2lRttrdS2tXMFq2uZqfq?p=preview

Зачем? Собирайте один бандл со всеми нужными вам компонентами. Вы совершенно ничего не выиграете от асинхронной загрузки $mol компонент, ибо они крайне маленькие.

Я говорю про задачу, когда нужно сделать готовые виджеты, который просто подключаются к странице я не хочу, чтобы каждый такой виджет включал в себя 30KB core-кода. На том же React/jQuery мне не нужно включать их сборку, я просто оставляю эти зависимости открытыми.


ps спасибо за пример, теперь понятно.

я не хочу, чтобы каждый такой виджет включал в себя 30KB core-кода

Общего кода там куда меньше. Ну, например, минифицированный зипованный бандл mol/button весит меньше 8кб. В любом случае, у $mol нет как такового ядра. Лучшим решением в данном случае на мой взгляд был бы онлайн сборщик бандла, как тут: http://jqueryui.com/download/

";" в качестве разделителя

Это же зависит от локали офиса. csv из расшифровки подразумевает деление запятой, ';' только в отечественном офисе.

Вы чертовски правы. Эксель понимает и так и так. Жаль, он не понимает TSV. Поправил на запятые.

Баг: если быстро вводить текст и нажимать Alt+↓ (или щёлкать на следующую ячейку), то содержимое предыдущей ячейки дописывается в начало текущей. А иногда нажатия клавиш просто игнорируются.

Тут дело в том, что $mol_string не сразу записывает значение, а делает debounce пользовательского ввода. Сделано это по 2 причинам:


  1. Чтобы ввод не затыкался, если будет тяжёлый рендеринг на каждое нажатие клавиши. Переполнение клавиатурного буфера — неприятная штука.
  2. Чтобы запросы на сервер не слались, пока пользователь не закончит ввод. Дебаунсить сами серверные запросы не правильно, ибо на клики, например, нужно реагировать сразу.

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


В коде это выглядит так:


Edit_current() {
    return this.Edit( this.current() )
}
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории