Инкапсуляция, чтение файла и event в firefox
Здравствуйте, уважаемые специалисты. Очень расчитываю на Вашу помощь и поддержку.
Вот код topmenu = (function() { return { filesload: function(evt,func) { var reader = new FileReader(); var files = evt.target.files; reader.onload = function(e) { func(e.target.result,files[0]); } reader.readAsArrayBuffer(files[0]); }, replace: function(s,e) { this[s](event,e); } } }()); Если вызвать так, то работает и в опере и хром и файрфоркс topmenu.sub(document.getElementById("inpField"),"change",function(e) { topmenu.filesload(e,function(s) { alert(s); }); }); А так только в хром и опере topmenu.sub(document.getElementById("inpField"),"change",function(e) { topmenu.replace.call(topmenu,"filesload",function(u,f) { alert(u+" = "+f.name); }) }); Файр фокс выдает event is not defined Вопрос 1) почему? и как поправить? Вопрос 2) Как я могу вернуть e.target.result, чтобы потом их обработать? Я так понимаю причина в onload. Вопрос 3) И последний вопрос касательно инкапсуляции. Какую роль играют в этом коде function(s){}(v) s и v? |
Вы, наверно, неполный код привели - у вас в topmenu нет свойства sub.
|
Цитата:
http://www.w3schools.com/jsref/jsref_sub.asp |
Цитата:
|
Цитата:
в асинхронных процессах вернуть с помощью return нельзя |
Код не полный, полный бы здесь не поместился.
Вот sub sub: function(elem,type,block) { try { try { elem.addEventListener(type, block, false); } catch(e) { elem.attachEvent("on"+type, block); } } catch(e){} } |
Цитата:
|
Цитата:
|
Цитата:
Цитата:
Цитата:
|
Цитата:
С помощью callback так же удобно все обрабатывается в первом случае у Вас это function(s){alert(s)} здесь передавайте свою функцию обработки-в чем проблема? при этом s это будет e.target.result можно добавить второй параметр-это будет files[0] function(s,fl){} |
Спасибо за ответы. В данном случае проблема не велика. Т.е. все необходимые действия я могу выполнить и так. Но мне было бы удобнее получить данные, чтобы впоследствии с ними работать.
Больше всего, честно говоря, интересуют вопрос 1 и 3 |
Цитата:
v -фактический рекомендуется писать так (function(s){})(v) |
Цитата:
Цитата:
Цитата:
|
Цитата:
|
Цитата:
объявляем функцию и сразу выполняем |
Цитата:
|
Цитата:
Я все правильно понимаю??? |
Цитата:
|
Цитата:
основной смысл что мы не создаем на глобальном уровне имени функции (не засоряем) с именем так бы выглядело function f(s){alert(s)}; f(5); |
Цитата:
не определен-но я так и не понял его смысла-ведь он делает тоже что и filesload только более сложным образом? Или еще что то? |
блин код не читаемые вообще....
вы бы сначала почитали про стиль написания (это не троллинг, говорю как есть) |
Цитата:
http://habrahabr.ru/post/38642/ в частности Напоследок хочу описать распространённую ошибку, которая многих вгоняет в ступор в случае незнания того, как работают замыкания. Пускай у нас есть массив ссылок, и наша задача — сделать так, чтобы при клике на каждую выводился алертом ее порядковый номер. Первое решение, что приходит в голову, выглядит так: for (var i = 0; i < links.length; i++) { links[i].onclick = function() { alert(i); } } На деле же оказывается, что при клике на любую ссылку выводится одно и то же число — значение links.length. Почему так происходит? В связи с замыканием объявленная вспомогательная переменная i продолжает существовать, при чём и в тот момент, когда мы кликаем по ссылке. Поскольку к тому времени цикл уже прошёл, i остаётся равным кол-ву ссылок — это значение мы и видим при кликах. Решается эта проблема следующим образом: for (var i = 0; i < links.length; i++) { (function(i) { links[i].onclick = function() { alert(i); } })(i); } Здесь с помощью еще одного замыкания мы «затеняем» переменную i, создавая ее копию в его локальной области видимости на каждом шаге цикла. Благодаря этому всё теперь работает как задумывалось. |
или так=)
for (var i = 0; i < links.length; i++) (function(i) { links[i].onclick = function() { alert(i); } })(i); а лучше использовать делегирование |
Цитата:
topmenu.replace.call(topmenu,"filesload",function( u,f) { alert(u+" = "+f.name);}) Эти два кода по сути аналогичный, но последний реализован через call В данном случае мы через call получаем topmenu["filesload"](e,function(s){ alert(s); }); |
Цитата:
Наверное есть какой то смысл и он может и связан с этим event который не везде работает Вы код откуда взяли? |
Цитата:
Насколько я понимаю в указанном мною примере в цикле идет перебор всех ссылок, и назначается каждому событие клик которое выполняет функцию алерт со значением i. Без инкапсуляции значение i после исполнения кода остается глобальным и при вызове функции в алерте вызывается глобальная переменная i. С инкапсуляцией видимо ей передается не сама переменная, а ее значение, уже после исполнения кода. Я правильно понимаю? Или я чего-то не понимаю? При этом на вновь созданную ссылку данный код уже не действует, и остается вопрос, как его получить? for (var i = 0; i < document.links.length; i++) { (function(i) { document.links[i].onclick = function() { alert(i); var newElem = document.createElement("a"); newElem.href = "#"; newElem.innerHTML = "Новая ссылка"; document.body.insertBefore(newElem, document.body.firstChild); return false; } })(i); } С делегированием я к сожалению еще не знаком, если только в джиквери, но думаю, что это не совсем то, или скорее совсем не то. |
Цитата:
|
там получается замыкание , при каждой итерации цикла вызывается функция,а в замыкание значения переменных (как бы правильно сказать) не обнуляются
|
Спасибо всем ответившим. В принципе остался только вопрос с event. Надеюсь, и на него найдется ответ.
|
Цитата:
topmenu.replace.call(topmenu,"filesload",e,function(u,f){... ... replace: function(s,evn,e) { this[s](evn,e); } |
Цитата:
Спасибо еще раз |
Здравствуйте, подскажите пожалуйста, есть примерно следующий плагин на jquery, те. плагин как и все плагины на jquery, но я никак не соображу как получить доступ к объекту и его методам
(function ($) { var C = function () { defaults = { ...... }, fillRGBFields = function (a, b) { ...... } }); })(jQuery); Как мне сделать что-то навроде for(i in C) alert(i + " : " + C[i]) |
Подскажите, пожалуйста, а почему
если при инкапсуляции вызвать Блок return { и поставить скобку на новую строку, return не работает |
Цитата:
то что возвращает return ,должно быть записано в одну строчку с ним. Иначе, перенос интерпретатор\компилятор воспринимает как окончание команды return, воспринимает как- ; |
Спасибо за ответ.
Я к тому что for if и тд. Нормально обрабатывают блок, когда { на другой строке, а чем return так отличился? |
Цитата:
Цитата:
Цитата:
Цитата:
что не ясного в ответе,чтоб задавать вопрос повторно ? что это особенность "языка" с return? чем отличается особенная ситуация от обычной? тем, что она особенная -она исключение. |
Я понял особенности, просто может еще где-то есть подобные особенности, а я не знаю.
|
Подскажите, как правильно выполнить следующее
for(var i=0; i<document.getElementsByName("my_name").length; i++) { document.getElementsByName("my_name")[i].onkeyup = function(i) { console.log(i); } } |
Цитата:
Кстати так: for(var i=0; i<document.getElementsByName("my_name").length; i++){ document.getElementsByName("my_name")[i].onkeyup = ... }делать не рекомендуется, ибо каждую итерацию цикла у вас сначала идёт получение заново всех элементов ByName("my_name"), затем получение заново длины, а после, в теле цикла, ещё раз получение всех элементов ByName("my_name"). Всё это вещи тратящие вычислительное время. В современных браузерах предусмотрено всяческое кеширование подобных случаев на уровне движка, но я бы не рекомендовал слишком уж полагаться на это. Более экономичный вариант: for(var i=0, my_name=document.getElementsByName("my_name"), l=my_name.length; i<l; i++){ my_name[i].onkeyup = ... } P.S. Ну и лично мне больше всего нравится для таких случаев использовать обратный перебор:) : var my_name=document.getElementsByName("my_name"), i=my_name.length; while(i--){ my_name[i].onkeyup = ... } Пример: Если не разобрались сами с замыканиями.
for(var i=0, my_name=document.getElementsByName("my_name"), l=my_name.length; i<l; i++){ my_name[i].onkeyup = function(i){ return function(){ console.log(i); } }(i) } |
Большое спасибо.
Посмотрел пример и вышло так for(var i=0; i<document.getElementsByName("my_name").length; i++) { document.getElementsByName("my_name")[i].onkeyup = function(x) { return function(){console.log(x)}; }(i) } Не ясно только, почему не выходит так for(var i=0; i<document.getElementsByName("my_name").length; i++) { document.getElementsByName("my_name")[i].onkeyup = function(x) { console.log(x) }(i) } Буду благодарен за разъяснения |
Часовой пояс GMT +3, время: 22:16. |