Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Скрипт "картинка-ссылка" на каждый день недели (https://javascript.ru/forum/dom-window/84633-skript-kartinka-ssylka-na-kazhdyjj-den-nedeli.html)

Тапочек 04.11.2022 11:10

Скрипт "картинка-ссылка" на каждый день недели
 
Всем привет и здрасьте!

Очень нужен скрипт, который будет отображать рандомную картинку-ссылку (например, из 50 штук) каждый день. То есть, новый день - новая картинка. Я перелопатил кучу сайтов, но ничего подходящего не нашёл...

Здесь сидят люди разбирающиеся в теме, помогите!
Всем добра!

voraa 04.11.2022 11:30

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

Тапочек 04.11.2022 11:31

Цитата:

Сообщение от voraa (Сообщение 548744)
Проще иметь массив url картинок и каждый день циклически показывать следующую.

Тоже верно. Как это сделать?

Тапочек 04.11.2022 11:41

Цитата:

Сообщение от voraa (Сообщение 548744)
Если показывать рандомно, то есть вероятность, что два (а то и три) дня подряд будет показываться одна и та же картинка.

Хотя и это меня не смущает. Массив из 56 картинок. Даже если что-то будет подряд показываться - да пусть, не принципиально. Важен именно ежедневный рандом (пусть и с повторами)

voraa 04.11.2022 11:52

Показывать циклически можно так.
const picurls = [
	'http://serv/pic1.jpg',
	'http://serv/pic2.jpg',
...
	'http://serv/picN.jpg',
];

const now = Date.now();  // мс с 01.01.1970
const msinday = 1000*60*60*24; // мс в сутках
const nowDay = Math.trunc(now/msinday); // дней с 01.01.1970

const ind = nowDay % picurls.length;

const url = picurls[ind];


Именно рандом на каждый день сделать труднее. Если это рандом для каждого пользователя (разные пользователи в один и тот же день будут видеть разные картинки), то каждый раз надо проверять заходил ли это т пользователь в этот день. Если нет, то вычислять рандомно индекс картинки и запоминать его, например в localStorage. Если уже заходил в этот день, то брать запомненный индекс.
Если все пользователи в этот день должны видеть одну и туже рандомную картинку, то это либо проблема сервера, либо придумывать какой то хеш по дате (например md5). и уже по хешу (беря младшую часть, вычисляя остаток) вычислять номер картинки, которую надо показать. Но нет гарантии, что это будет действительно равномерно распределенное случайное число.

Тапочек 04.11.2022 14:41

Я вижу это примерно так (если не прав - пните): например, есть скрипт, который показывает рандомную картинку при обновлении страницы (но это не подходит). А если сделать так, что в, например, час ночи (по дате пользователя) скрипт рандомно выбирает картинку из массива и показывает её пользователю (всем пользователям). Это нечто вроде "фото дня". Пусть будут повторы - не принципиально

Можно сделать и цикличность (тоже выход, но не совсем), но хотелось бы всё же рандом

Вот как-то так

voraa 04.11.2022 18:14

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

Тапочек 04.11.2022 19:53

Цитата:

Сообщение от voraa (Сообщение 548761)
Тогда это должен сервер делать - выбирать, какую картинку показывать пользователям.

Окай, можно решить вопрос и с цикличностью (сделать псевдорандом - картинки показываются не 1,2,3,4,5... а 3,1,5,4,2 - это не проблема), но я упорно не понимаю, как настроить скрипт на смену картинки каждые 24 часа. Я в JS не силён от слова совсем. Мне бы готовый скрипт... :(

рони 04.11.2022 21:36

Цитата:

Сообщение от Тапочек
Мне бы готовый скрипт...

чем не устраивает код в #3?

Тапочек 04.11.2022 21:58

Цитата:

Сообщение от рони (Сообщение 548763)
чем не устраивает код в #3?

Если это уже готовый скрипт, который меняет картинку каждые 24 часа - меня полностью устраивает (отредактировать я понимаю как). Только вот вместо картинки нужна картинка-ссылка. Как это сделать?

А как сделать, чтобы картинка менялась раз неделю, раз в месяц и раз в год? По аналогии с "фото недели" и "фото месяца"

voraa 04.11.2022 21:58

Цитата:

Сообщение от Тапочек
(сделать псевдорандом - картинки показываются не 1,2,3,4,5... а 3,1,5,4,2 - это не проблема)

Какая разница? Разместите урл картинок в другом порядке.
Требуется ведь, что бы ВСЕ пользователи в какой то день видели одну и ту же определенную картинку. Если каждый пользователь в этот день будет независимо от других считать рандом, то картинки у всех будут разные.
Значит либо строго определенная цикличность, скрипт у каждого пользователя должен вычислять один и тот же номер картинки для данного дня. Либо это должен делать сервер - вычислять номер, для каждого дня разный но одинаковый для всех пользователей.

voraa 04.11.2022 21:59

Цитата:

Сообщение от Тапочек
Только вот вместо картинки нужна картинка-ссылка. Как это сделать?

Что такое картинка ссылка?

voraa 04.11.2022 22:01

Цитата:

Сообщение от Тапочек
А как сделать, чтобы картинка менялась раз неделю, раз в месяц и раз в год? По аналогии с "фото недели" и "фото месяца"

Аналогично. Получать номер недели или номер месяца от начала года.

Тапочек 04.11.2022 22:32

Цитата:

Сообщение от voraa (Сообщение 548765)
Какая разница? Разместите урл картинок в другом порядке.

Да, так и сделаю, в принципе - выход. Я в этой теме не сильно подкован, сами понимаете

Цитата:

Сообщение от voraa (Сообщение 548766)
Что такое картинка ссылка?

<a href=index.htm><img scr="img.jpg"></a>

Примерно так

Цитата:

Сообщение от voraa (Сообщение 548767)
Аналогично. Получать номер недели или номер месяца от начала года.

Я всё равно не понимаю, извините

А скрипт (у меня) не работает, просто пустая страница. Если что - вот код:

<html>
    <head>
<title>Страница</title>
    </head>
<body>
<script>
    const picurls = [
'/images/1.jpg',
'/images/2.jpg',
'/images/3.jpg',

];

const now = Date.now();  // мс с 01.01.1970
const msinday = 1000*60*60*24; // мс в сутках
const nowDay = Math.trunc(now/msinday); // дней с 01.01.1970
 
const ind = nowDay % picurls.length;

const url = picurls[ind];

</script>
 
</body>
</html>

voraa 04.11.2022 22:50

Так я написал только как урл получать.
Откуда же я знаю куда вам надо его запихивать?
Где тот img, куда его надо запихнуть?
Или я всю страницу формироввать должен?

voraa 04.11.2022 22:54

<html>
    <head>
<title>Страница</title>
    </head>
<body>

<a href=index.htm><img id='pd'></a>

<script>
    const picurls = [
'/images/1.jpg',
'/images/2.jpg',
'/images/3.jpg',
 
];
 
const now = Date.now();  // мс с 01.01.1970
const msinday = 1000*60*60*24; // мс в сутках
const nowDay = Math.trunc(now/msinday); // дней с 01.01.1970
  
const ind = nowDay % picurls.length;
 
const url = picurls[ind];

document.getElementById('pd').src = url
 
</script>
  
</body>
</html>

voraa 04.11.2022 22:57

Цитата:

Сообщение от voraa
Аналогично. Получать номер недели или номер месяца от начала года.

Получение номера дня, недели и месяца от 01.01.1970
const picurls = [
    'http://serv/pic1.jpg',
    'http://serv/pic2.jpg',
...
    'http://serv/picN.jpg',
];
 
const now = Date.now();  // мс с 01.01.1970
const msinday = 1000*60*60*24; // мс в сутках
const nDay = Math.trunc(now/msinday); // дней с 01.01.1970

const nWeek = Math.trunc((nDay - 4)/7);  // недель с 01.01.1970 (переключается в понедельник)

const year = new Date (now).getFullYear()
const month = new Date (now).getMonth()
const nMonth = (year - 1970)*12 + month // мeсяцев с 01.01.1970 
 
const indDay = nDay % picurls.length;
const indWeek = nWeek % picurls.length;
const indMonth = nMonth % picurls.length;

рони 04.11.2022 22:58

новая картинка каждый день
 
Тапочек,
<!DOCTYPE html>
<html>

<head>
    <title>Страница</title>
</head>

<body>
    <img src="" class="pic">
    <script>
        const picurls = [ //порядок картинок зависит только от вас, тасуйте как хотите
            'https://picsum.photos/300/100?1',
            'https://picsum.photos/300/100?2',
            'https://picsum.photos/300/100?3',
            'https://picsum.photos/300/100?4',
            'https://picsum.photos/300/100?5',
            'https://picsum.photos/300/100?6',
            'https://picsum.photos/300/100?7'
        ];

        const now = Date.now() -(new Date().getTimezoneOffset()) * 60000;
 // мс с 01.01.1970
        const msinday = 1000 * 60 * 60 * 24; // мс в сутках
        const nowDay = Math.trunc(now / msinday); // дней с 01.01.1970

        const ind = nowDay % picurls.length;

        const url = picurls[ind];
        document.querySelector(".pic").src = url;
    </script>
</body>

</html>

voraa 04.11.2022 23:29

Цитата:

Сообщение от voraa
const now = Date.now();  // мс с 01.01.1970

Вернее будет так
const now = Date.now() -(new Date().getTimezoneOffset()) * 60000;

Что бы день менялся в 00:00:00 по местному времени.

Тапочек 05.11.2022 01:12

Voraa, да, коряво объяснил. Мне нужно, чтобы по клику на картинку открывалась ссылка (на каждую картинку своя ссылка). В вашем скрипте только ссылка на картинку ('http://serv/pic1.jpg'), она не кликабельна, то есть, она не ссылка, а просто картинка

рони, если менять часы системные часы, то вроде ничего не меняется. Хотя наступил новый день и картинка сменилась... Не понимаю, как это происходит 0_0

Тапочек 05.11.2022 13:39

Цитата:

Сообщение от voraa (Сообщение 548774)
Что бы день менялся в 00:00:00 по местному времени.

Со скриптом я более-менее разобрался, но открытым остаётся вопрос, как сделать картинку кликабельной. Я так понял, что вот это в коде
<a href=index.htm><img id='pd'></a>

не просто так

рони 05.11.2022 13:50

Тапочек,
наверно надо создать массив href и выбирать также
const href = arr[ind];
document.querySelector("#pd").parentNode.href = href;

Тапочек 05.11.2022 15:22

Цитата:

Сообщение от рони (Сообщение 548781)
Тапочек,
наверно надо создать массив href и выбирать также

Да я и не спорю. Вопрос как? =)
Я вот что-то наваял как смог, код вроде работает, но он кривой до чёртиков. Я не знаю, что, как и куда правильно писать, для меня это магия
<a href=index.htm><img id='pd'>
	<img src="" class="pic">
    
<script>

const picurls = [

'http://00.gif?1',
'http://01.gif?2',
'http://02.gif?3',
'http://03.gif?4',

        	];

const now = Date.now(); // мс с 01.01.1970
const msinday = 1000 * 60 * 60 * 24; // мс в сутках
const nowDay = Math.trunc(now / msinday); // дней с 01.01.1970

const ind = nowDay % picurls.length;

const url = picurls[ind];

document.querySelector(".pic").src = url;


// разделитель

const arr = [

'http://google.com?1',
'http://yahoo.com?2',
'http://yandex.ru?3',
'http://rambler.ru?4',

		];

const href = arr[ind];
document.querySelector("#pd").parentNode.href = href;

</script>

рони 05.11.2022 17:28

Тапочек,
<a href=index.htm id='pd'>
    <img src="" class="pic"></a>
<script>
    const picurls = [{
        src: 'http://00.gif?1',
        href: 'http://google.com?1'
    }, {
        src: 'http://01.gif?2',
        href: 'http://yahoo.com?2'
    }, {
        src: 'http://02.gif?3',
        href: 'http://yandex.ru?3'
    }, {
        src: 'http://03.gif?4',
        href: 'http://rambler.ru?4'
    }];

    const now = Date.now(); // мс с 01.01.1970
    const msinday = 1000 * 60 * 60 * 24; // мс в сутках
    const nowDay = Math.trunc(now / msinday); // дней с 01.01.1970

    const ind = nowDay % picurls.length;

    const obj = picurls[ind];

    document.querySelector(".pic").src = obj.src;
    document.querySelector("#pd").href = obj.href;
</script>

Тапочек 05.11.2022 19:03

Цитата:

Сообщение от рони (Сообщение 548783)
рони

А вот теперь огромнейшее спасибо! :victory:

Тапочек 18.11.2022 21:18

Цитата:

Сообщение от Тапочек (Сообщение 548784)
А вот теперь огромнейшее спасибо! :victory:

Рано я порадовался. Скрипт не работает, как его не настраимвай и перенастраивай

voraa 18.11.2022 21:24

Какой именно скрипт и что конкретно не работает?

Тапочек 18.11.2022 21:37

Цитата:

Сообщение от voraa (Сообщение 549054)
Какой именно скрипт и что конкретно не работает?

Последний скрипт от рони. Я заменил адреса картинок, закинул его в файл script.js и подключил к странице. Никакая картинка не отображается, вообще ничего не отображается

voraa 18.11.2022 21:52

Где вызываете этот скрипт? В начале html файла или в конце?
Какие ошибки в консоле?

Если в начеле подключили так, как он написан, то конечно не будет работать. DOM дерева еще нет и
document.querySelector(".pic").src = obj.src;
document.querySelector("#pd").href = obj.href;
вызовут ошибку

Тапочек 18.11.2022 22:22

Цитата:

Сообщение от voraa (Сообщение 549057)
Где вызываете этот скрипт? В начале html файла или в конце?
Какие ошибки в консоле?

Если в начеле подключили так, как он написан, то конечно не будет работать. DOM дерева еще нет и
document.querySelector(".pic").src = obj.src;
document.querySelector("#pd").href = obj.href;
вызовут ошибку

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

<Script Language="JavaScript">
  now = new Date()
  if (now.getDay() == 0)
    document.write("Отдыхайте, завтра рабочий день...")
  if (now.getDay() == 1)
    document.write("Сегодня понедельник - настраивайтесь на работу")
  if (now.getDay() == 2)
    document.write("Уже вторник, понедельник к счастью позади!")
  if (now.getDay() == 3)
    document.write("Половина недели позади - сегодня уже среда")
  if (now.getDay() == 4)
    document.write("Сегодня четверг, скоро выходные...")
  if (now.getDay() == 5)
    document.write("Сегодня пятница - последний рабочий день")
  if (now.getDay() == 6)
    document.write("Сегодня первый день выходных!")
</Script>


Мне нужно, чтобы картинка менялась не 7 раз, а 50. Я попытался его изменить, что бы после ==6 шло ==7, а не опять ==0, но не выходит, он опять начинает "с понедельника"

Вот примерно я такой скрипт и просил, но, по видимому, это уж чересчур сложная задача

voraa 18.11.2022 22:31

Это не сложная задача.
Просто то, что вы делаете (document.write) - какой то ад.
Нужно просто правильно написать html файл, и правильно подключить скрипт.
Если подключаете в начале html файла, в разделе <head> то скрипт должен быть таким

const picurls = [{
        src: 'http://00.gif?1',
        href: 'http://google.com?1'
    }, {
        src: 'http://01.gif?2',
        href: 'http://yahoo.com?2'
    }, {
        src: 'http://02.gif?3',
        href: 'http://yandex.ru?3'
    }, {
        src: 'http://03.gif?4',
        href: 'http://rambler.ru?4'
    }];
 
    const now = Date.now(); // мс с 01.01.1970
    const msinday = 1000 * 60 * 60 * 24; // мс в сутках
    const nowDay = Math.trunc(now / msinday); // дней с 01.01.1970
 
    const ind = nowDay % picurls.length;
 
    const obj = picurls[ind];

    window.addEventListener('DOMContentLoaded', () => {

        document.querySelector(".pic").src = obj.src;
        document.querySelector("#pd").href = obj.href;
    })


А если в конце (перед </body>) то можно так, как у рони

Тапочек 18.11.2022 22:49

Цитата:

Сообщение от voraa (Сообщение 549061)
Это не сложная задача.
Если подключаете в начале html файла, в разделе <head> то скрипт должен быть таким

Хорошо, я подключу его между <head>, но как мне вывести картинку в нужном месте страницы?

voraa 18.11.2022 22:53

Цитата:

Сообщение от Тапочек (Сообщение 549065)
Хорошо, я подключу его между <head>, но как мне вывести картинку в нужном месте страницы?

Поместить в нужное место страницы
<a href=index.htm id='pd'>
    <img src="" class="pic">
</a>

Тапочек 18.11.2022 22:58

Цитата:

Сообщение от voraa (Сообщение 549067)
Поместить в нужное место страницы
<a href=index.htm id='pd'>
    <img src="" class="pic">
</a>

У меня на каждую картинку идёт отдельная страница с описанием. То есть, 50 картинок - 50 страниц

voraa 18.11.2022 23:03

Я уже совсем не понимаю, что вы делаете.
То вы пишете, что при открытии страницы, каждый раз на ней (на одной странице) должна показываться разная картинка.
Теперь вы пишете, что страниц 50.
Так, что каждый день должна открываться разная страница?

Тапочек 18.11.2022 23:23

Начинаем заново, теперь максимально подробно. У меня одностраничный сайт по картам Таро (там древовидная система разделов). Слева в колонке есть место под т.н. "карту дня", которая должна меняться каждый день (она идёт картинкой-ссылкой, то есть кликаешь по ней и открывается новое окно (для каждой карты своя страница с описанием карты и прогнозом). С тем скриптом, который для вас "какой-то ад" это вроде как можно сделать, но там новая картинка (с ссылкой) циклически меняется только каждые 7 дней, а нужно каждые 56 дней (так как картинок-ссылок 56)
Я уже совсем не понимаю, как ещё можно объяснить. Я об этом писал ещё в первом сообщении

voraa 19.11.2022 08:46

Цитата:

Сообщение от Тапочек
У меня одностраничный сайт

Цитата:

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

Так страница одна или 57 (56+1)?

На вашей странице (которая одна), слева в колонке, в коде HTML вставляете элементы
<a href=index.htm id='pd'>
    <img src="" class="pic">
</a>

И подключаете скрипт. a - это ссылка на одну из 56 страниц. img - это одна из 56 картинок.
Скрипт в эти элементы сам запишет нужный href и нужный src.

Как вы открываете окно под картинкой, что в нем и откуда берется информация для него, вы не писали.

Тапочек 19.11.2022 10:14

Цитата:

Сообщение от voraa (Сообщение 549078)
Так страница одна или 57 (56+1)?

Отписался вам в личку

Тапочек 21.11.2022 02:11

К сожалению, готового решения пока что не нашлось. Тот скрипт, который давался сверху, не работает (ну или просто это не то, что нужно). Ещё раз попробую обрисовать, так сказать, техническое задание

Есть массив из 56 картинок. Нужно, чтобы на сайте каждый день показывалась новая картинка. Но не просто картинка, а картинка-ссылка (то есть, кликаешь по картинке и открывается новая страница - для каждой картинки своя). Вот примерный скрипт:

now = new Date()
  if (now.getDay() == 0)
    document.write("<a href=1.htm><img src=1.jpg></a>") // первая картинка-ссылка
  if (now.getDay() == 1)
    document.write("<a href=2.htm><img src=2.jpg></a>") // вторая картинка-ссылка
  if (now.getDay() == 2)
    document.write("<a href=3.htm><img src=3.jpg></a>") // третья картинка-ссылка и так далее
  if (now.getDay() == 3)
    document.write("<a href=4.htm><img src=4.jpg></a>")
  if (now.getDay() == 4)
    document.write("<a href=5.htm><img src=5.jpg></a>")
  if (now.getDay() == 5)
    document.write("<a href=6.htm><img src=6.jpg></a>")
  if (now.getDay() == 6)
    document.write("<a href=7.htm><img src=7.jpg></a>")


Конретно в этом скрипте (да, устаревшем, но он работает - это главное) циклично меняются только 7 картинок, а нужно 56. Идеально было бы, чтобы картинки менялись рандомно, но это, насколько я понял, сделать сложно. Надеюсь, рассказал доходчиво. Всем, кто откликнулся или откликнется - благодарочка и респект :thanks:

Белый шум 21.11.2022 10:55

Тапочек, скрипт для вас. Полагаю, что такая псевдослучайность для вашей задачи приемлема.
function getDayOfYear() {
  var now = new Date();
  var start = new Date(now.getFullYear(), 0, 0);
  var diff = (now - start) + ((start.getTimezoneOffset() - now.getTimezoneOffset()) * 60 * 1000);
  var oneDay = 1000 * 60 * 60 * 24;
  return Math.floor(diff / oneDay);
}
function random(day) {
  var r0 = day * 33 + 85017801 + (new Date()).getFullYear();
  var left = ((parseInt('01111111110000000000000000000000', 2) & r0) >>> 23);
  var r1 = (r0 << 9 >>> 1) | left;
  var right = ((parseInt('111111111', 2)) & r0) << 24 >>> 1;
  var r2 = (r0 >>> 8) | right;
  r0 = r1 + r2;
  return 1 + ((Math.floor(r0 / 99) + day) % 56);
}

var pic = random(getDayOfYear());
document.write('<a href="'+pic+'.htm"><img src="'+pic+'.jpg"></a>');


Проверка работоспособности (результат в консоли):
<body>
<div>Номер года:
<input id="checkyear" type="number" value="2022"></div>
<div>День года (число от 1 до 366):
<input id="checkday" type="number">
<button onclick="testday();">Проверить дату</button></div>
<button onclick="testyear();">Вся статистка за год</button>
(результат в консоли браузера)

<script>
var inp = document.getElementById("checkday");
inp.value = getDayOfYear();
function testday(){
  console.log("Проверка " + inp.value + ":", random(+inp.value));
}
function testyear(){
  var o = {};
  for( var i=1; i<=56; i++ ) o[i] = NaN;
  for( var i=1; i<=366; i++){
    var pic = random(i);
    o[pic] = o[pic] ? o[pic] + 1 : 1;
    console.log("День "+i+": картинка "+pic);
  }
  console.log( "Сколько раз в "+document.getElementById("checkyear").value+" году каждая картинка будет появляться:", o );
}

function getDayOfYear() {
  var now = new Date();
  var start = new Date(now.getFullYear(), 0, 0);
  var diff = (now - start) + ((start.getTimezoneOffset() - now.getTimezoneOffset()) * 60 * 1000);
  var oneDay = 1000 * 60 * 60 * 24;
  return Math.floor(diff / oneDay);
}
console.log('Day of year: ' + getDayOfYear());

function random(day) {
  var year = +document.getElementById("checkyear").value;
  var r0 = day * 33 + 85017801 + year;
  var left = ((parseInt('01111111110000000000000000000000', 2) & r0) >>> 23);
  var r1 = (r0 << 9 >>> 1) | left;
  var right = ((parseInt('111111111', 2)) & r0) << 24 >>> 1;
  var r2 = (r0 >>> 8) | right;
  r0 = r1 + r2;
  return 1 + ((Math.floor(r0 / 99) + day) % 56);
}
</script>
</body>


Часовой пояс GMT +3, время: 21:10.