Comments 100
А можно еще вопрос?
Как правильнее обрабатывать большие объемы данных в Javascript избегая зависания интерфейса и сообщений от браузера о «долгом скрипте» (длинный список данных для отчета, отдающийся в JSON)? Есть ли какие-либо библиотеки для этого?
Как правильнее обрабатывать большие объемы данных в Javascript избегая зависания интерфейса и сообщений от браузера о «долгом скрипте» (длинный список данных для отчета, отдающийся в JSON)? Есть ли какие-либо библиотеки для этого?
0
UFO just landed and posted this here
Для этой цели и были созданы Воркеры(Workers). Когда-то давно я предлагал решение данной проблемы: WXHR: старый добрый XHR со вкусом Web Workers
0
Уже было в этом цикле статей, 8 пункт habrahabr.ru/blogs/javascript/120192/
+3
Разбить на короткие блоки, вызывая их по setTimeout() или упомянутые выше WW.
0
Задача вполне реальная, и, как мне казалось, кем нибудь уже сотни раз решалась.
WW работают не везде, и проблема с производительностью чаще касается браузеров, в которых WW не работают.
SetTimeout хоть и является очевидным решением, но очень странно видоизменяет код и скорее выглядит как костыль (либо приходится использовать его везде, либо дописывать когда количество пользовательских данных достигает объемов которые тормозят работу браузера).
WW работают не везде, и проблема с производительностью чаще касается браузеров, в которых WW не работают.
SetTimeout хоть и является очевидным решением, но очень странно видоизменяет код и скорее выглядит как костыль (либо приходится использовать его везде, либо дописывать когда количество пользовательских данных достигает объемов которые тормозят работу браузера).
0
UFO just landed and posted this here
глупость. eval — не нужен. ниже — обсудили, почему.
0
есть ещё третий вариант — через замыкания.
0
И четвертый, присвоить колбеку свойство с нужным значением как объекту. Где то ниже TheShock писал про .bind — 5й получается :) Хотя eval/new Function можно вообще за варианты не считать.
Ну писать, что в функцию передаются ссылки значений — некорректно.
Ну писать, что в функцию передаются ссылки значений — некорректно.
0
UFO just landed and posted this here
UFO just landed and posted this here
По поводу документирования кода, также интересно было бы услышать мнение о подходе, рекомендованном MS — включении xml-документации в тело функций.
weblogs.asp.net/bleroy/archive/2007/04/23/the-format-for-javascript-doc-comments.aspx
weblogs.asp.net/bleroy/archive/2007/04/23/the-format-for-javascript-doc-comments.aspx
0
Спасибо за помощь)
0
Добавлю от себя пару моментов.
Eval — зло ещё и потому, что не даёт браузерам оптимизировать код:
конструктор функции — тоже не стоит использовать. лично мне НИКОГДА не приходилось использовать eval в своём коде.
Если я правильно понимаю задачу, то сделать достаточно легко благодаря функциям высшего порядка. Допустим, возмём декоратор "@delay", который заставляет выполнятся функцию через время. В Питоне, он выглядел бы как-то так:
На JS:
Код мог бы быть каким-то таким:
Eval — зло ещё и потому, что не даёт браузерам оптимизировать код:
конструктор функции — тоже не стоит использовать. лично мне НИКОГДА не приходилось использовать eval в своём коде.
Есть ли в JavaScript аналоги декларациям/аннотациям (термины из Python/Java соответственно)?
Если я правильно понимаю задачу, то сделать достаточно легко благодаря функциям высшего порядка. Допустим, возмём декоратор "@delay", который заставляет выполнятся функцию через время. В Питоне, он выглядел бы как-то так:
@delay(1000)
def foo(object):
// code here
На JS:
var foo = function () {
// code here
}.delay(1000);
// или так:
var foo = delay(1000, function () {
// code here
});
Код мог бы быть каким-то таким:
Function.prototype.delay = function ( time ) {
var origFn = this;
return function () {
setTimeout( origFn, time );
}
}
+5
Декораторами применение аннотаций не исчерпывается.
Как вообще придать коду мета-информацию? Один из вариантов — это Google Closure Compiler, есть ли что-нибудь еще? Как бы вы делали AOP?
Как вообще придать коду мета-информацию? Один из вариантов — это Google Closure Compiler, есть ли что-нибудь еще? Как бы вы делали AOP?
0
Да, первый вариант очень близок к декораторам, спасибо.
0
Ой, я забыл добавить для сравнения вариант БЕЗ eval:
В варианте с eval в «Scope Variables» видно, что переменные не удалены из контекста
В варианте с eval в «Scope Variables» видно, что переменные не удалены из контекста
0
Chrome: Global Score в полтора раза быстрее :)
+1
Вот насчет eval
У меня есть некий пример, приходилось с подобным сталкиваться просто, не знаю, возможно вы знаете как это решить без евала, хотелось бы знать как.
Допустим есть некая функция asyncFunc, она принимает один аргумент, в нашем случае это будет число. Так же у нас есть некая переменная count, которая является целом числом больше единицы.
Нужно вызвать функцию asyncFunc, передавая ей в качестве аргумента число от 0 до count (вызвать count раз), при этом промежуток между вызовами должен составлять 10 секунд.
Вот допустим такой код:
Такой код по понятным причинам работает не так, как хотелось.
Но проблему можно решить так:
Тут без евала конечно, но в setTimeout приходится использовать строку вместо функции, так что, думаю, одно и то же
У меня есть некий пример, приходилось с подобным сталкиваться просто, не знаю, возможно вы знаете как это решить без евала, хотелось бы знать как.
Допустим есть некая функция asyncFunc, она принимает один аргумент, в нашем случае это будет число. Так же у нас есть некая переменная count, которая является целом числом больше единицы.
Нужно вызвать функцию asyncFunc, передавая ей в качестве аргумента число от 0 до count (вызвать count раз), при этом промежуток между вызовами должен составлять 10 секунд.
Вот допустим такой код:
var asyncFunc = function (n)
{
console.log(n);
};
var count = 5;
for (var i = 0; i < count; i++)
{
window.setTimeout(function()
{
asyncFunc(i);
}, 10000 * i);
}
Такой код по понятным причинам работает не так, как хотелось.
Но проблему можно решить так:
for (var i = 0; i < count; i++)
{
window.setTimeout('asyncFunc(' + i + ')', 10000 * i);
}
Тут без евала конечно, но в setTimeout приходится использовать строку вместо функции, так что, думаю, одно и то же
0
Ваша проблема решается без эвала, это классическая проблема, решаемая с помощью замыканий. Например так:
for (var i = 0; i < count; i++)
{
(function(i) {
return window.setTimeout(function()
{
asyncFunc(i);
}, 10000 * i);
})(i);
}
+7
Спасибо огромное, не знал
Насколько я понимаю он работает благодаря отделению области видимости где вызывается setTimeout от области видимости где инкрементируется i?
Насколько я понимаю он работает благодаря отделению области видимости где вызывается setTimeout от области видимости где инкрементируется i?
0
Да, это работает потому, что для каждой итерации цикла создается самовызываемая функция, которая имеет свою область видимости, в которой i — имеет нужное нам значение (мы получаем его внутри setTimeout). В вашем же коде, для всех i область видимости одинаковая и на момент вызова функции в setTimeout, i в этой области видимости будет уже равно 5 (цикл уже отработал). Подробнее почитать например тут: javascript.ru/basic/closure
+1
Сам помню, когда разбирался в тонкостях JS, думал, как красиво это сделать)
С помощью замыканий, и правда, получается просто и красиво.
С помощью замыканий, и правда, получается просто и красиво.
+1
Есть также хак с with:
Но он уже deprecated, в будущем вместо него будем использовать let.
for (var i = 0; i < count; i++) with ({ i: i }) {
window.setTimeout(function() {
asyncFunc(i);
}, 10000 * i);
}
Но он уже deprecated, в будущем вместо него будем использовать let.
0
Кстати, ещё более красивое решение этой проблемы — карринг:
for (var i = 0; i < count; i++) {
window.setTimeout(asyncFunc.bind(null, i), 10000 * i);
}
+1
UFO just landed and posted this here
А что такое декларации/аннотации в Python/Java?
+4
azproduction:
Пользуясь случаем, задам ВОПРОС о корректном освобождении памяти в JS.
Я хочу удалять отработавшие своё функции.
Об этом я, естественно, задумываюсь в конце выполения функции, которую хочу удалить.
Если я напишу наивно:
Решение может быть таким:
Пользуясь случаем, задам ВОПРОС о корректном освобождении памяти в JS.
Я хочу удалять отработавшие своё функции.
Об этом я, естественно, задумываюсь в конце выполения функции, которую хочу удалить.
Если я напишу наивно:
a = function(){
//...
delete a;
}
то могу попасть на утечку памяти: когда функцию удаляю, она исполняется, поэтому физически удалена быть не может. Когда будет выполнена — она останется в памяти, но все указатели уже удалены. Происходит ли такое на практике, читали ли Вы об этом?Решение может быть таким:
a = function(){
//...
var f = arguments.callee;
setTimeout(function(){delete f;},1);
}
но, во-первых, это почему-то не работает и не даёт ошибку, во-вторых, функция не выполняется, но используется её SCOPE. Поэтому, возможно, она тоже не удалится. Работает так:c = function(){
//...
setTimeout(function(){delete c;},1);
}
c();
0
delete удаляет только переменную, ссылку. в нормальных браузерах мусор очистится, когда не будет ссылок. в остальных — как повезет.
и да, «delete varName» удаляет «varName» из глобального контекста, не локального. delete корректно работает только для полей объектов: «delete obj.field»
и да, «delete varName» удаляет «varName» из глобального контекста, не локального. delete корректно работает только для полей объектов: «delete obj.field»
+2
А точнее сказать локальным переменным присваивается флаг DontDelete.
+1
> в нормальных браузерах мусор очистится, когда не будет ссылок
ну, это похоже на ответ «я верю в то, что...». Например, функции, упомянутые в скрипте на некоторой странице, следовательно, никогда не удалятся? А если кто-то будет держать скопы через ссылки (создаст объект, запоминающий каждую временную функцию, создаваемую в скрипте) — тоже?
…
Если я напишу так: (f = глобальная), функция b тоже не удалится. Значит, дело не в локальности f.
ну, это похоже на ответ «я верю в то, что...». Например, функции, упомянутые в скрипте на некоторой странице, следовательно, никогда не удалятся? А если кто-то будет держать скопы через ссылки (создаст объект, запоминающий каждую временную функцию, создаваемую в скрипте) — тоже?
…
Если я напишу так: (f = глобальная), функция b тоже не удалится. Значит, дело не в локальности f.
b = function(){
//...
f = arguments.callee;
setTimeout(function(){delete f;},1);
}
0
В JavaScript, как и во многих других есть объекты и есть ссылки на объекты. Как только на объект перестают ссылаться он удаляется и освобождается память. delete удаляет ссылку тех объектов, у которых нет флага
В вашем примере вы создаете глобальную переменную f и удаляете её после выполнения тела функции b. Логично, что в глобалах будет только b. Что происходит:
Создается глобальная переменная b, которая ссылается на безымянный объект-функцию. При исполнении тела функции b создается глобальная переменная f, которая ссылается на ту же объект-функцию. (Сейчас у нас 2 ссылки на первую безымянную функцию) Потом вызывается setTimeout с порождением другой безымянной функции. Тело которой удаляет ссылку f. Вторая функция удаляется GC т.к. на неё никто не ссылается. В конце у нас 1 ссылка на первую безымянную функцию — b.
Вот ещё пример:
У нас есть глобальная переменная b которая ссылается на 100. Потом мы создаем безымянную функцию на которую ссылается a. Мы вызываем безымянную функцию с параметром b. Создается контекст функции в который входят 2 переменные bb и с. bb при инициализации принимает значение 100 и затем инициализируется с, которая тоже принимает значение 100. Дальше мы перемножаем c * bb и возвращаем значение из функции. Т.к. ссылок на переменных контекста нет, то контекст безымянной функции удаляется, с ним удаляются ссылки bb и c. Дальше мы переписываем ссылку а значением 10000. Теперь на безымянную функцию никто не ссылается и она удаляется. В конце остается 2 ссылки а и b.
[[DontDelete]]
.Например, функции, упомянутые в скрипте на некоторой странице, следовательно, никогда не удалятся? А если кто-то будет держать скопы через ссылки (создаст объект, запоминающий каждую временную функцию, создаваемую в скрипте) — тоже?Не удаляется.
В вашем примере вы создаете глобальную переменную f и удаляете её после выполнения тела функции b. Логично, что в глобалах будет только b. Что происходит:
Создается глобальная переменная b, которая ссылается на безымянный объект-функцию. При исполнении тела функции b создается глобальная переменная f, которая ссылается на ту же объект-функцию. (Сейчас у нас 2 ссылки на первую безымянную функцию) Потом вызывается setTimeout с порождением другой безымянной функции. Тело которой удаляет ссылку f. Вторая функция удаляется GC т.к. на неё никто не ссылается. В конце у нас 1 ссылка на первую безымянную функцию — b.
Вот ещё пример:
var b = 100;
var a = function (bb) {
var c = 100;
return c * bb;
}
a = a(b);
У нас есть глобальная переменная b которая ссылается на 100. Потом мы создаем безымянную функцию на которую ссылается a. Мы вызываем безымянную функцию с параметром b. Создается контекст функции в который входят 2 переменные bb и с. bb при инициализации принимает значение 100 и затем инициализируется с, которая тоже принимает значение 100. Дальше мы перемножаем c * bb и возвращаем значение из функции. Т.к. ссылок на переменных контекста нет, то контекст безымянной функции удаляется, с ним удаляются ссылки bb и c. Дальше мы переписываем ссылку а значением 10000. Теперь на безымянную функцию никто не ссылается и она удаляется. В конце остается 2 ссылки а и b.
+1
Вопрос по eval. Продолжение первого вопроса.
Хорошо, нет проблем, я согласен, что eval — это зло. Но бывают случаи, когда после загрузки страницы нужно выполнить текст. Казалось бы, без eval() или Function() тут не обойтись. Но есть ещё подгрузка скриптов. Она часто используется в штатных случаях, когда надо изолировать DOMContentLoaded от сторонних скриптов, чтобы страница прорисовалась быстро и надёжно. Ничто не мешает подгрузить в свою страницу свой скрипт (читай: текст). По определению, скрипт выполняется в window. Возможно, это тот же частный случай Function().
1) Что говорят в мире об этом?
2) Как быстро или насколько медленно подгрузка скрипта выполняется?
3) Имеем ли мы какие-то бонусы от такой подгрузки вместо Function()?
Пример такой подгрузки я недавно делал в spmbt.kodingen.com/habrahabr/habracut06.user.js — скрипте для показа Google "+1" иконок под статьями на Хабре. ( habrahabr.ru/blogs/google/124057/ ) Грузился сначала гугловский скрипт, затем — мой, который контролировал то, загрузились ли необходимые методы. (По-другому нельзя из-за особенностей исполнения юзер-скриптов, Function могла и не пройти.)
Хорошо, нет проблем, я согласен, что eval — это зло. Но бывают случаи, когда после загрузки страницы нужно выполнить текст. Казалось бы, без eval() или Function() тут не обойтись. Но есть ещё подгрузка скриптов. Она часто используется в штатных случаях, когда надо изолировать DOMContentLoaded от сторонних скриптов, чтобы страница прорисовалась быстро и надёжно. Ничто не мешает подгрузить в свою страницу свой скрипт (читай: текст). По определению, скрипт выполняется в window. Возможно, это тот же частный случай Function().
1) Что говорят в мире об этом?
2) Как быстро или насколько медленно подгрузка скрипта выполняется?
3) Имеем ли мы какие-то бонусы от такой подгрузки вместо Function()?
Пример такой подгрузки я недавно делал в spmbt.kodingen.com/habrahabr/habracut06.user.js — скрипте для показа Google "+1" иконок под статьями на Хабре. ( habrahabr.ru/blogs/google/124057/ ) Грузился сначала гугловский скрипт, затем — мой, который контролировал то, загрузились ли необходимые методы. (По-другому нельзя из-за особенностей исполнения юзер-скриптов, Function могла и не пройти.)
0
>Продолжение первого вопроса. — первого в смысле по счёту в статье.
0
Есть очень много решений, который контролируют порядок загрузки скриптов без каких-либо eval'ов, используя обычные script-теги: labjs, $script.js, yepnope,…
Отвечая на второй вопрос, я говорю, что eval в некоторых местах может быть невероятно выгодным, по сравнению с обычным подходом: шаблон Резига и парсинг JSON. В остальных случаях eval портит общепринятую концепцию в обработке данных, когда код обрабатывает данные и возвращает данные. Т.е. он не порождает другой код из данных во время обработки. Случаи когда без этого сложно обойтись (когда код должен порождать код): шаблон Резига и парсинг JSON. XSS это уже вторичная проблема.
Отвечая на второй вопрос, я говорю, что eval в некоторых местах может быть невероятно выгодным, по сравнению с обычным подходом: шаблон Резига и парсинг JSON. В остальных случаях eval портит общепринятую концепцию в обработке данных, когда код обрабатывает данные и возвращает данные. Т.е. он не порождает другой код из данных во время обработки. Случаи когда без этого сложно обойтись (когда код должен порождать код): шаблон Резига и парсинг JSON. XSS это уже вторичная проблема.
0
Шаблон Резига можно заменить таким решением.
делается скрытый элемент-образец.
например:
при создании нового элемента, делается клон элемента-образца.
потом рекурсивно проходим по этому элементу.
и заменяем prop_var на элементы из объекта.
var obj = {
id: 1,
id2: 2,
value: 'test',
}
примерно такой псевдокод.
var clone = $('#prop_id').clone();
вызов рекусивной функции
в рекурсивной функции проверяем.
if (element.id.match(/^prop_(.*)$/) {
element.id = obj[RegExp.$1];
}
if (element.value.match(/^prop_(.*)$/) {
element.value = obj[RegExp.$1];
}
Можно и innerHTML менять.
— Минус подхода в том, что нужно либо задавать набор свойств элементов, которые обходить (id, value, innerHTML).
Либо обходить сразу все свойства, что медленно.
Но обычно нужно обходить только id, value и innerHTML
Надо замерить этот способ шаблонизатор Резига
делается скрытый элемент-образец.
например:
при создании нового элемента, делается клон элемента-образца.
потом рекурсивно проходим по этому элементу.
и заменяем prop_var на элементы из объекта.
var obj = {
id: 1,
id2: 2,
value: 'test',
}
примерно такой псевдокод.
var clone = $('#prop_id').clone();
вызов рекусивной функции
в рекурсивной функции проверяем.
if (element.id.match(/^prop_(.*)$/) {
element.id = obj[RegExp.$1];
}
if (element.value.match(/^prop_(.*)$/) {
element.value = obj[RegExp.$1];
}
Можно и innerHTML менять.
— Минус подхода в том, что нужно либо задавать набор свойств элементов, которые обходить (id, value, innerHTML).
Либо обходить сразу все свойства, что медленно.
Но обычно нужно обходить только id, value и innerHTML
Надо замерить этот способ шаблонизатор Резига
0
*
делается скрытый элемент-образец.
например:
<div id=«prop_id»>
<input type=«text» value=«prop_id2» value=«prop_value»>
</div>
делается скрытый элемент-образец.
например:
<div id=«prop_id»>
<input type=«text» value=«prop_id2» value=«prop_value»>
</div>
0
> получился очень кривой инпут
Почитайте о Contenteditable
Почитайте о Contenteditable
+2
Совсем забыл! Столько кода наворотил, а ларчик то просто открывался. Спасибо, добавлю в статью.
html5demos.com/contenteditable
www.quirksmode.org/dom/execCommand/
html5demos.com/contenteditable
www.quirksmode.org/dom/execCommand/
0
Для звука есть ещё старый-престарый тег BGSOUND.
0
По вопросу 7, уточнение: приведённый код годится только для последнего потомка, appendChild кладёт объект в конец.
Пишем исправленную функцию:
Пишем исправленную функцию:
<script>onload = function(){
function resetEvents(element){
var newEl = element.parentNode.insertBefore(element.cloneNode(true), element);
element.parentNode.removeChild(element);
return newEl;
}
document.getElementById('bb').addEventListener('click', function(){alert(2)},!1);
resetEvents(document.getElementById('bb'))
}</script>
<div><b id="bb" onclick="alert(1)">пример</b> <i>шум</i></div>
+2
К ответу 13: на самом деле, лучше, наверное (для скорости), не к DOM-элементам приписывать атрибуты с хешами, а наоборот, к конструкциям JS приписывать DOM-элементы, создавая доступ к ним. Сравнивали ли где-то в публикациях разницу в скорости доступа?
К ответу 15: или предложить пользователю установить юзерскрипт/расширение, которое для того сервера будет грузить картинку, а затем отдавать её в бинарном виде своему серверу или перекидывать в свой фрейм методом window.name. Правда, с бинарными данными сложно работать, надо такое расширение сделать один раз… Не все произвольные пользователи согласятся установить юзерскрипт.
К ответу 15: или предложить пользователю установить юзерскрипт/расширение, которое для того сервера будет грузить картинку, а затем отдавать её в бинарном виде своему серверу или перекидывать в свой фрейм методом window.name. Правда, с бинарными данными сложно работать, надо такое расширение сделать один раз… Не все произвольные пользователи согласятся установить юзерскрипт.
0
1. Я не понял первый вопрос, пожалуйста, переформулируйте.
2. Предполагается, что пользователь не установит расширение — ничего не будет работать. Да и ставить расширение для того, чтобы работал сайт — это как-то не по вебски.
2. Предполагается, что пользователь не установит расширение — ничего не будет работать. Да и ставить расширение для того, чтобы работал сайт — это как-то не по вебски.
0
1. Это не вопрос, а рассуждение об эффективности (скорости) доступа. Если определим переменную JS у DOM-объекта — .., это работать будет, но время доступа в такой конструкции, скорее всего, будет дольше, чем у
0
(Оборвалось.)
1. Это не вопрос, а рассуждение об эффективности (скорости) доступа. Если определим переменную JS у DOM-объекта — .., это работать будет, но время доступа в такой конструкции, скорее всего, будет дольше, чем у
1. Это не вопрос, а рассуждение об эффективности (скорости) доступа. Если определим переменную JS у DOM-объекта — .., это работать будет, но время доступа в такой конструкции, скорее всего, будет дольше, чем у
-1
(А, понял, это иезутиские теги сайта.)
1. Это не вопрос, а рассуждение об эффективности (скорости) доступа. Если определим переменную JS у DOM-объекта — .., это работать будет, но время доступа в такой конструкции, скорее всего, будет дольше, чем у <object>.{ <property> :{method: ...}, element: <DOM>}. Поэтому, хотя такое возможно, лучше всегда избегать использования свойств у элементов. По крайней мере, там, где понадобится скорость. И это замечание по скорости лучше приписать к ответу. (Но у меня нет данных и простеньких тестов, чтобы это показать.)
2. Поставить, чтобы работали расширенные функции сайта — это вполне по веб. Например, «Что надо, чтобы проигрывались файлы *.mov? Установить в системе кодек от QuickTime иили аналогичный. А браузер чем хуже? Для него бывают плагины-движки для особых типов данных (моделирование 3D, игры). А тут всё гораздо проще, без особых технологий.
1. Это не вопрос, а рассуждение об эффективности (скорости) доступа. Если определим переменную JS у DOM-объекта — .., это работать будет, но время доступа в такой конструкции, скорее всего, будет дольше, чем у <object>.{ <property> :{method: ...}, element: <DOM>}. Поэтому, хотя такое возможно, лучше всегда избегать использования свойств у элементов. По крайней мере, там, где понадобится скорость. И это замечание по скорости лучше приписать к ответу. (Но у меня нет данных и простеньких тестов, чтобы это показать.)
2. Поставить, чтобы работали расширенные функции сайта — это вполне по веб. Например, «Что надо, чтобы проигрывались файлы *.mov? Установить в системе кодек от QuickTime иили аналогичный. А браузер чем хуже? Для него бывают плагины-движки для особых типов данных (моделирование 3D, игры). А тут всё гораздо проще, без особых технологий.
0
Как скопировать выделенный текст в буфер обмена кнопочкой (ссылкой)?
Спасибо.
Спасибо.
0
Универсальное решение есть только на флеше: Копируем в буфер обмена
Из JavaScript копирование поддерживает только IE и Safari
IE:
Safari: через выделение текста и execCommand(«Copy»)
Вообще нормальной практикой считается выделять текст и просить пользователя нажать
Из JavaScript копирование поддерживает только IE и Safari
IE:
window.clipboardData.setData("Text", "PewPewPew");
Safari: через выделение текста и execCommand(«Copy»)
Вообще нормальной практикой считается выделять текст и просить пользователя нажать
Ctrl+C
— см. goo.gl0
Может быть у вас есть идеи, как избавиться от проблемы расширения файлов, например, как здесь: jszip.stuartk.co.uk/, не используя флеш.
0
Cпасибо, много полезного получил
0
Ох, спасибо, ребята, спасли мне около полутора часов жизни :)
0
добавить бы якорных ссылок в оглавление…
+3
4. странно приводить в пример код, где большую часть времени занивают сложения, умножения, сравнения, пополнение динамического массива… конечно разницы между локальной и глобальной переменной не будет. по моим тестам присвоение значения локальной переменной в фф занимает 0.029 микросекунды, а глобальной — 0.176
0
Вопрос: в чём смысл capturing? То есть
Я понимаю его суть, но зачем он может использоваться? На примерах?
Как оно взаимодействует с ещё одним эвентом, на этом же элементе, который использует баблинг?
addEventListener(a, b, true);
?Я понимаю его суть, но зачем он может использоваться? На примерах?
Как оно взаимодействует с ещё одним эвентом, на этом же элементе, который использует баблинг?
0
Как говорится в придании, в начале было 2 браузера — один поддерживал capturing, а другой bubling. В итоге победил ИЕ. Ие старых версий поддерживал только баблинг, поэтому у разработчиков и не было особого выбора.
Вообще всплытие события — это наиболее логичный вариант. Например мы кликаем на элемент, создавая эпицентр события. Эхо этого события может донестись до внешних элементов. С капчем мы как-будто наводимся на элемент и в конце выстреливаем последний эвент.
capturing и bubling делят одно событие т.е. (это тоже событие, но с разных сторон) один может прервать другой. Как бы мы не забиндили события сперва всегда вызвается capturing (логично) начиная с окна и заканчивая целью и только потом идет фаза bubling в обратную сторону.
Сходу мне сложно придумать юзкейс для capturing. Вот что пришло в голову:
1. Временное терменирование всех баблинг событий, используя capturing и
2. Пикер элементов окна по координате.
Вот тест и пример 1 в одном месте. Надо раскоментить строку
Вообще всплытие события — это наиболее логичный вариант. Например мы кликаем на элемент, создавая эпицентр события. Эхо этого события может донестись до внешних элементов. С капчем мы как-будто наводимся на элемент и в конце выстреливаем последний эвент.
capturing и bubling делят одно событие т.е. (это тоже событие, но с разных сторон) один может прервать другой. Как бы мы не забиндили события сперва всегда вызвается capturing (логично) начиная с окна и заканчивая целью и только потом идет фаза bubling в обратную сторону.
Сходу мне сложно придумать юзкейс для capturing. Вот что пришло в голову:
1. Временное терменирование всех баблинг событий, используя capturing и
stopPropagation()
2. Пикер элементов окна по координате.
Вот тест и пример 1 в одном месте. Надо раскоментить строку
event.stopPropagation()
, чтобы сработал пример 1. jsfiddle.net/azproduction/bbQ42/0
Спасибо. механизм теперь понятен. Но таки интересны реальные юзкейсы, можт кто придумают. У меня есть впечатление, что я видел где-то в плагинах ДжиКвери связанных с инпутом. Но я так и не понял тогда тайного смысла использовать именно capturing.
0
По поводу колеса мыши:
На сколько я помню, у opera это работает через одно место. Т.е. наоборот: скролл вверх возвращает отрицательное значение. Когда-то очень сильно этому удивился и долго матюкался
На сколько я помню, у opera это работает через одно место. Т.е. наоборот: скролл вверх возвращает отрицательное значение. Когда-то очень сильно этому удивился и долго матюкался
0
Хочу с помощью JS, сохранить кусок страницы(определенный мной) как картинку (JPG например) и чтобы в картинке было все именно так как выглядет в браузере пользователя.
Бывает такое? или не родились еще такие стандарты?
левый софт не предлагать типа Gyazo или JetScreenshot или плагины к браузеру.
Бывает такое? или не родились еще такие стандарты?
левый софт не предлагать типа Gyazo или JetScreenshot или плагины к браузеру.
0
Только сегодня в Твиттере наткнулся: html2canvas.hertzen.com/screenshots.html
0
И вот ещё одна: bgrins.github.com/DrawWindow/
0
Я так понял что в КАнвасе можно хоть черта делать и затем этот канвас — выгрузить в виде битмапа, и это то что вы пишите уже костыли для того чтобы можно было обычный HTML пихать в канвас, да?
0
Что? Я вас не понял
0
Выгружать в JPG можно толкьо из CANVAS я так понял?
0
Да, при помощи Canvas2Image
0
Подскажите, после использования переменных в сильно AJAX приложении нужно ли обнулять переменные var в функциях? Что вообще с ними происходит после выхода из функций?
0
Не нужно. Как только удаляются все ссылки на объект/функцию или контексты память освобождается автоматически.
Вот тут небольшой пример что происходит habrahabr.ru/blogs/javascript/124327/#comment_4086833
Вот тут небольшой пример что происходит habrahabr.ru/blogs/javascript/124327/#comment_4086833
0
Существует ли способ в JS получить имя переменной в виде string для последующего использования?
0
Не понял, переформулируйте, пожалуйста, вопрос.
0
var MyVarName;
Существует ли способ получить
'MyVarName'
из JS?0
Если переменная объявлена в локальном контексте, то её имя получить нельзя(можно было в ФФ 3.6-, используя __parent__).
Если переменная объявлена глобально, то её имя можно получить, используя:
Можно получить все имена свойств объекта, можно получить имя функции (NFE, FD), можно так или иначе получить имена аргументов функции
Если переменная объявлена глобально, то её имя можно получить, используя:
for (var name in window) {
console.log(name);
}
Можно получить все имена свойств объекта, можно получить имя функции (NFE, FD), можно так или иначе получить имена аргументов функции
var test = function a(b,c,d) {};
// Function name
var name = test.name || // Modern browsers
String(test).match(/function(?:\s*)?([a-zA-z$_][a-zA-z$_]*)?/)[1]; // IE
// Arguments
var args = String(test).split(')')[0].split('(')[1].split(/,\s?/);
+1
Можно ли добраться до CSS псевдоэлементов
Для того, чтобы накидать/изменить их стили и узнать значение свойства
:before
и :after
через JS?Для того, чтобы накидать/изменить их стили и узнать значение свойства
content
.0
Через style это сделать нельзя, но можно пропатчить таблицы стилей.
Например, у нас есть элемент
Добавляем:
Ну и для ИЕ:
Вобщем можно написать обертку, которая будет делать всю эту магию за нас, ну или использовать jQuery#before/after.
Почитать www.w3.org/TR/DOM-Level-2-Style/Overview.html
Например, у нас есть элемент
#elem
. Мы хотим поменять css-свойство :before
те фактически добавить блок:#elem:before {content: "pewpew"; color: red;}
Добавляем:
document.styleSheets[0].insertRule('#elem:before {content: "pewpew"; color: red;}', 0);
document.styleSheets[0].cssRules[0].style.сolor= '#555'; // Меняем
Ну и для ИЕ:
document.styleSheets[0].addRule('#elem:before', 'content: "pewpew"; color: red;', 0);
document.styleSheets[0].rules[0].style.сolor= '#555;
Вобщем можно написать обертку, которая будет делать всю эту магию за нас, ну или использовать jQuery#before/after.
Почитать www.w3.org/TR/DOM-Level-2-Style/Overview.html
+1
UFO just landed and posted this here
for(var t=0;t<10;t++){
console.time('native'+t);
var res = 0;
for(var idx = 0; idx < 1000; idx++){
res = Math.round( Math.random()*((new Date()).getTime()/idx) )
};
console.timeEnd('native'+t);
console.time('eval'+t);
var res = 0;
for(var idx = 0; idx < 1000; idx++){
eval('res = Math.round( Math.random()*((new Date()).getTime()/idx) )')
};
console.timeEnd('eval'+t);
}
native0: 6.568ms VM11296:10
eval0: 28028.307ms VM11296:18
native1: 9.370ms VM11296:10
eval1: 28053.163ms VM11296:18
native2: 6.128ms VM11296:10
eval2: 28058.792ms VM11296:18
native3: 6.266ms VM11296:10
eval3: 28059.410ms VM11296:18
native4: 5.758ms VM11296:10
eval4: 28071.947ms VM11296:18
native5: 5.366ms VM11296:10
eval5: 28079.450ms VM11296:18
native6: 7.372ms VM11296:10
eval6: 28091.091ms VM11296:18
native7: 8.352ms VM11296:10
eval7: 28088.152ms VM11296:18
native8: 6.371ms VM11296:10
eval8: 28073.608ms VM11296:18
native9: 6.120ms VM11296:10
eval9: 28083.928ms VM11296:18
0
UFO just landed and posted this here
Вызвать код без ебала значительно быстрее, чем с евалом — об этом речь.
0
Что-то числа слишком большие. Вот правильные результаты:
Как видно, eval на порядок дольше исполняется, чем создание замыкания.
for(var t=0;t<10;t++){
console.time('native'+t);
var res = 0;
for(var idx = 0; idx < 1000; idx++){
res = Math.round( Math.random()*((new Date()).getTime()/idx) )
};
console.timeEnd('native'+t);
console.time('eval'+t);
var res = 0;
for(var idx = 0; idx < 1000; idx++){
eval('res = Math.round( Math.random()*((new Date()).getTime()/idx) )')
};
console.timeEnd('eval'+t);
console.time('func'+t);
var res = 0;
for(var idx = 0; idx < 1000; idx++){
void function( idx ){
res = Math.round( Math.random()*((new Date()).getTime()/idx) )
}( idx )
}
console.timeEnd('func'+t);
}
native0: 2.552ms VM40121:10
eval0: 75.564ms VM40121:18
func0: 4.598ms VM40121:28
native1: 4.724ms VM40121:10
eval1: 63.414ms VM40121:18
func1: 6.070ms VM40121:28
native2: 3.579ms VM40121:10
eval2: 66.886ms VM40121:18
func2: 6.601ms VM40121:28
native3: 4.170ms VM40121:10
eval3: 61.786ms VM40121:18
func3: 5.309ms VM40121:28
native4: 4.719ms VM40121:10
eval4: 69.186ms VM40121:18
func4: 5.035ms VM40121:28
native5: 4.029ms VM40121:10
eval5: 66.522ms VM40121:18
func5: 5.816ms VM40121:28
native6: 5.628ms VM40121:10
eval6: 72.350ms VM40121:18
func6: 4.726ms VM40121:28
native7: 4.374ms VM40121:10
eval7: 68.818ms VM40121:18
func7: 5.549ms VM40121:28
native8: 5.118ms VM40121:10
eval8: 73.261ms VM40121:18
func8: 6.945ms VM40121:28
native9: 5.579ms VM40121:10
eval9: 73.521ms VM40121:18
func9: 5.297ms VM40121:28
Как видно, eval на порядок дольше исполняется, чем создание замыкания.
0
Sign up to leave a comment.
JavaScript F.A.Q: Часть 2