Имя: Пароль:
IT
 
Помогите с javascript
,
0 Эльниньо
 
11.03.13
23:14
Мой первый джава-скрипт, сильно не пинайте.
Надо отобрать в случайном порядке 6 картинок и вывести в блоке.
В случае неимения файла - вывести c.jpg
Цикл отрабатывает (алерт показывает), но выводится только последняя картинка.
Гугля с Яндехом наизнанку вывернул, но решения не нашёл.

    <script type="text/javascript">
       function getrandom(min_r, max_r) {
          var range = max_r;
       return Math.floor(Math.random() * (max_r - min_r + 1)) + min_r;
       }
       var Kod;
       for (var i = 1; i <= 6; i++) {
          Kod = String(getrandom(1, 116));
          alert(Kod); // нормуль
          img = new Image();
          img.src = 'http://elninio.ru/i/p/s/'+Kod+'.jpg';
          img.onload = function(){document.write('<a href="http://elninio.ru/s/p'+Kod+'"> <img src="http://elninio.ru/i/p/s/'+Kod+'.jpg" border="1" height="70">')}
          img.onerror = function(){document.write('<img src="http://elninio.ru/i/m/C.jpg" border="1" height="70">')};
       }
    </script>
1 jsmith82
 
11.03.13
23:26
нафейхуа ява там, где должен быть пэхэпэ
2 jsmith82
 
11.03.13
23:28
ну и к тому же инициализируешь одну переменную
я давно не яваскриптил, но сдаётся мне, это всё фигня
учит PHP
3 jsmith82
 
11.03.13
23:31
попробуй массив картинок в худшем случае
4 Юрий Лазаренко
 
11.03.13
23:34
(1) Можно и без ПХП, яваскрипт вполне справится
5 Юрий Лазаренко
 
11.03.13
23:37
(0) У тебя "в блоке" (пока не понял, где это - в блоке) должны быть заранее, еще HTMLем, забиты 6 картинок, которые по дефолту ведут на картинку-заглушку типа "Фото загружается". Далее в цикле генеришь 6 случайных номеров и каждой картинке по очереди присваиваешь путь, примерно так: document.img[0].src = 'http://elninio.ru/i/p/s/'+Kod+'.jpg
6 Юрий Лазаренко
 
11.03.13
23:40
Только обрати внимание на нумерацию картинок: img[0] не прокатит, если до твоего блока с картинками в документе уже будут другие картинки. Можно каждой картинке присвоить id типа MyImgNumber1, MyImgNumber2 и т.д. и получать к ним доступ через document.getElementById("MyImgNumber" + ImgNumber).src, где ImgNumber - итератор для картинок.
7 Юрий Лазаренко
 
11.03.13
23:41
А вообще (1) прав, ПХП тут лучше справится, но если задачка что называется "одноразовая", сделать и забыть, то можно и яваскриптом.
8 Asmody
 
12.03.13
00:26
обработчики событий поставь до img.src=
9 Эльниньо
 
12.03.13
09:41
Спасибо. Буду копать дальше.
Чувствую себя в шкуре тех, кого дятлами обзывают, предлагают купить СП и покурить ЖКК.
10 Fragster
 
гуру
12.03.13
09:42
не надо документ.врайт
11 Эльниньо
 
12.03.13
17:58
(10) img.onload = function(){Что?
12 Fragster
 
гуру
12.03.13
18:22
(11)
<img src="http://s017.radikal.ru/i414/1303/8c/1c83c3f2a6dc.png" style="display:none" onload="this.style.display='block'">onload="this.style.display='block'">
13 Fragster
 
гуру
12.03.13
18:22
kbiytt jnhtpfnm
14 Fragster
 
гуру
12.03.13
18:22
лишнее отрезать
15 Fragster
 
гуру
12.03.13
18:23
или с jquery $(this).toggle()
16 Fragster
 
гуру
12.03.13
18:24
а зачем загружать картинки предварительно?
17 Fragster
 
гуру
12.03.13
18:27
<img src="http://s017.radikal.ru/i414/1303/8c/1c83c3f2a6dc.png" style="display:none" onload="$(this).toggle()">
18 IOL
 
12.03.13
18:27
(9) Ну все, будут у тебя сорванные нервы, ставь огнелиса и плагин под него. FireBug очень сильно сохраняет нервы, и очень мощный инструмент для отладки JS, ну и помни, что клиенту доверять нельзя и все данные нужно проверять на стороне сервака.

Удачи в этом нелегком деле.
19 IOL
 
12.03.13
18:28
(15) Классная шняга, вообще удачный js фремворк.
20 kokamoonga
 
12.03.13
18:43
(0)  c jQuery попроще будет. Что-то типа:


//здесь устанавливаешь обработчики
//теги <img> можно заранее заготовить или по ходу дела аппендить это неважно
$(document).ready(function() {

 $('.rand_img').on('load', function () {

       // при изменении src onLoad будет повторно отрабатывать поэтому нужно как-то проверить
       if ($(this).attr('src') !== 'http://elninio.ru/i/m/C.jpg') {
           $(this).wrap('<a href="http://elninio.ru/s/p' + $(this).attr("src") + '"></a>');
       }

   });

   $('.rand_img').on('error', function () {
       $(this).attr('src', "http://elninio.ru/i/m/C.jpg");
   });

});


//здесь собственно выполняешь код в цикле
$('.rand_img').each(function() {
   $(this).attr('src', Kod)
});
21 Fragster
 
гуру
12.03.13
18:46
(20) тебе за количество строк платят?
22 kokamoonga
 
12.03.13
18:47
(20)  + ыы, хрень написал:) вот тут:

$(this).wrap('<a href="http://elninio.ru/s/p' + $(this).attr("src") + '"></a>');
23 kokamoonga
 
12.03.13
18:47
(21) не понял вопрос
24 Fragster
 
гуру
12.03.13
18:51
(23) много кода. Задача показа случайной картинки чисто средствами JS решается короче
25 Fragster
 
гуру
12.03.13
18:52
если уж jquery применять
26 kokamoonga
 
12.03.13
18:53
(24) это переложение алгоритма выбранного ТС на jQuery. я с удовольствием послушаю как это сделать оптимально ибо сам с такой задачей никогда не сталкивался.
27 kokamoonga
 
12.03.13
19:00
(24)  код в (17), например, действительно короче. но  он хорош только в случае, если есть возможность заранее подготовить html.

а если клиент по ajax периодически получает некоторое количество src картинок, которые рандомно нужно показать?
28 kokamoonga
 
12.03.13
19:02
(27) + ну и да. при наличии jQuery назначать обработчики через аттрибуты тега кажется мне спорной идеей.
29 Fragster
 
гуру
12.03.13
19:37
(28) да я про то же. я вообще против указывания тегов напрямую, хоть это и меньше места занимает. вот так, примерно (вставил переносы строк для читаемости):
http://jsfiddle.net/WT83f/
30 Fragster
 
гуру
12.03.13
19:39
var a забыл. В примере - не принципиально, но вообще - не лишне
31 kokamoonga
 
12.03.13
20:14
(29) но в этом коде нет даже намека на заглушку, а в (0) прямо сказано, что нужно показать заглушку по onError.

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

зачем hide() и show() непонятно, ни <a>, ни <img> не показываются на странице не имея содержания. в этом контексте(без обработки onError) в принципе не нужны обработчики, достаточно просто в цикле $('body').append(a) и все что внутри цикла спокойно переписывается в одну строку.

вобщем код безусловно написан куда эстетичнее чем у меня. только он не делает половину из того, что обозначено в (0). а если эту половину добавить, то получится ненамного короче чем в моем варианте. а если эту половину не добавлять непонятно зачем все так растянуто.

кроме того непонятно зачем каждый раз create(). если вдруг представить ситуацию что html-скелет уже есть, каждый раз создавать его заново?

на мой взгляд ТС предложил вполне годный алгоритм. все важные телодвижения в обработчиках onload и onerror, с поправкой на .on() для jQuery (к слову сказать .bind() также как и .live() не рекомендуются к применению в версиях выше 1.7)
32 Fragster
 
гуру
12.03.13
22:04
(31) обновил с добавлением заглушки.
а hide и show - потому что в (0) - показ после загрузки. Можно убрать, оставить только
   img = $(create('img'))
       .attr('src', 'http://fragster.ru/images/counter1.png')
       .bind('error', function(){
           $(this).attr('src', 'http://fragster.ru/images/counter.png')
       });

create заместо document.write, что предполагает отсутсвие структуры, но позволяет этот блок вставить в любое место
33 Fragster
 
гуру
12.03.13
22:04
34 Fragster
 
гуру
12.03.13
22:06
35 Fragster
 
гуру
12.03.13
22:16
и с отсутствием ссылки: http://jsfiddle.net/WT83f/7/
36 kokamoonga
 
12.03.13
22:55
(34) (35)  этот код по-прежнему не предусматривает существующего html-скелета. но вобщем я не настаиваю на своей точке зрения. мне лично твой код видится не без недостатков, но это возможно оттого, что я вижу задачу немного по-своему.

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


Google Closure дает после сжатия (а только о сжатом коде и можно говорить в контексте длиннее-короче) твой код 320 байт, мой 364. Не столь уж велика разница оказывается


//что собственно сжимаем.
$(document).ready(function () {
   $('.rand_img').on('load', function () {
       if ($(this).attr('src') !== 'http://elninio.ru/i/m/C.jpg') {
           $(this).wrap('<a href="' + $(this).attr("src") + '"></a>');
       }
   });
   $('.rand_img').on('error', function () {
       $(this).attr('src', 'http://elninio.ru/i/m/C.jpg');
       $(this).parent('a').replaceWith($(this)); //да это дельная мысль
   });
});
$('.rand_img').each(function () {
   $(this).attr('src', Kod)
});
37 Fragster
 
гуру
12.03.13
23:40
(36) так ведь код в (0) не предусматривает тоже.

а код (36) - это html с js, что не очень хорошо. я про wrap('<a href="' + $(this).attr("src") + '"></a>');
38 Fragster
 
гуру
12.03.13
23:40
помесь
39 Fragster
 
гуру
12.03.13
23:40
это html с js,
40 kokamoonga
 
13.03.13
00:14
(37) (38) (39)  официальная документация jQuery приводит массу таких примеров.

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

>>>так ведь код в (0) не предусматривает тоже.

я и говорю, что вижу задачу несколько шире, чем просто здесь и сейчас показать 6 картинок. а что если завтра нужно будет показать не 6, а 12? а что если раз в минуту их нужно будет рандомно менять? а что если нужно будет по ajax запрашивать еще и показывать их? пересоздавать заново элементы просто ни к чему. достаточно поменять src у такого количества <img> которое необходимо, дальше отработает то что прописано в onLoad или onError
41 Юрий Лазаренко
 
13.03.13
11:09
Мда, с ПХП было бы проще )
42 Fragster
 
гуру
13.03.13
11:13
(41) а если хостинг без ПХП?
43 Fragster
 
гуру
13.03.13
11:15
ну и да, http://pastebin.com/jtaxdgpi - индекс.пхп от фрагстер.ру
44 Fragster
 
гуру
13.03.13
11:17
если не юзать всякие wrap('<a href="' + $(this).attr("src") + '"></a>'); , а юзать DOM, получается автоматическая защита от XSS
45 Fragster
 
гуру
13.03.13
11:19
также, как если юзать prepared statements - получается автоматическая защита от sql injection
46 Юрий Лазаренко
 
13.03.13
12:10
(42) Тогда конечно с js извращаться
47 kokamoonga
 
13.03.13
17:05
(44) извини, можно с этого места поподробнее? каким образом использование строк в аргументах функций и методов js способствует реализации XSS-атак?
48 Fragster
 
гуру
13.03.13
17:19
допустим, "переменная" берется откуда-то из базы, соответственно, ее надо фильтровать. а если не фильтровать, то возможно так:

//переменная = 'http://evil.com'" onclick="alert(document.cookies)";
'<a href="' + переменная + '"></a>'

если же устанавливать через .attr то такой фигни не получится. правда все равно можно сделать подлянку, что-то типа переменная  = 'javascript:alert("xss")'; фильтровать все равно надо, но тогда это хоть в статусбаре будет отображаться.
49 kokamoonga
 
13.03.13
17:38
(48) допустим прежде чем вываливать что-то на страницу это в принципе надо фильтровать.

чем принципиально отличается

'<a href="' + жутко_опасная_переменная + '"></a>'

от

a.attr('href', жутко_опасная_переменная)

?

допустим переменная берется из базы, а также допустим, что она жутко_опасная. внимание вопрос: а как вообще потенциально опасная запись попала в базу? если некто позволяет юзерам писать в базу все что ни попадя без фильтрации, то он ССЗБ, а техника написания js-скриптов здесь вообще сбоку.

XSS это атака основанная на внедрении стороннего кода на страницу и совершенно никак не зависит от качества и техники написания js-скриптов
50 Fragster
 
гуру
13.03.13
17:45
(49) если писать attr, то пассивный xss (который не требует действий пользователя, кроме как открытия страницы) не получится. а рассчитывать на то, что где-то в другом месте нет sql-injection, который позволяет все, что угодно через допустим форму поиска в базу записывать, нельзя. особенно, если допиливаешь чье-то наследство.
51 Fragster
 
гуру
13.03.13
17:50
52 kokamoonga
 
13.03.13
19:45
(51)
var evil = alert("xss") === undefined && 'http://evil.com';
$('body').append($(document.createElement('a')).attr('href', evil).text('dom'));
53 Fragster
 
гуру
13.03.13
19:48
(52) тогда уж
evil = 'alert("xss") === undefined && \'http://evil.com\'';
это же просто строка из БД/гет/откуда там еще
54 kokamoonga
 
13.03.13
20:14
(53) да, согласен, в (52) чушь.

и согласен, что .attr() отчасти защищает от XSS. при полной безалаберности на стороне сервера становится актуально да.

но, положа руку на сердце, много ты знаешь рядовых пользователей которые смотрят в статусбар? 'javascript:alert("xss")'  отработает на ура у 99% пользователей и они ничего не заметят. да и это не главная проблема, если в базе проходной двор и отсутствует фильтрация перед отдачей.