Javascript-форум (https://javascript.ru/forum/)
-   (X)HTML/CSS (https://javascript.ru/forum/xhtml-html-css/)
-   -   javascript в html - переход по случайной ссылке из списка (https://javascript.ru/forum/xhtml-html-css/78176-javascript-v-html-perekhod-po-sluchajjnojj-ssylke-iz-spiska.html)

Vikal 06.08.2019 01:16

javascript в html - переход по случайной ссылке из списка
 
Здравствуйте, товарищи.

Вопрос следующий:
есть таблица на 6 ячеек. В каждой ячейке ссылка-картинка.

Задача:
сделать так, чтобы при клике на каждую ссылку-картинку открывалась случайная страница по ссылке из заранее подготовленного списка ссылок.
При этом, у каждой ссылки-картинки свой список ссылок.

Пробовал несколько способов, и наиболее рабочими оказались вот эти два:

1.
<table>
<tr>
<td>
<a id="link" href=""><img src="pic01.png" alt="123"></a> </td>
</tr>
</table>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<script>
var a = [];
a[0] = '0001.html';
a[1] = '0002.html';
a[2] = '0003.html';
function rand( min, max ) {
    if( max ) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
    } else {
        return Math.floor(Math.random() * (min + 1));
    }
}

window.document.getElementById('link').onmouseover = function() { this.setAttribute('href', a[rand(0,2)]); };
</script>



2.
<script>
var links = ['0001.html','0002.html','0003.html','0004.html','0005.html'];
window.onload = function() {
window.location.href = links[Math.round(Math.random() * 4)];
}
</script>

НО!

По факту оба не подходят. Первый работает, если такая ссылка-картинка одна на страницу. Если их несколько, то скрипт дает сбой, и работает только по одному из списков, но на все ссылки-картинки сразу.

Второй работает круто, но переход по ссылке-картинке ведет сначала на пустую страницу чисто со скриптом, которая уже сама автоматом перекидывает на случайную ссылку из списка. Т.е. в цепочке появляется еще одна страница, функция которой только в выполнении скрипта. Излишние движения.

Что посоветуете, товарищи?

Спасибо заранее.

Malleys 20.08.2019 22:53

Цитата:

Сообщение от Vikal
сделать так, чтобы при клике на каждую ссылку-картинку открывалась случайная страница по ссылке из заранее подготовленного списка ссылок.
При этом, у каждой ссылки-картинки свой список ссылок.

Вы, например, можете определить атрибут data-links на каждой ссылке, в котором будет храниться массив ссылок, из которого каждый раз при заходе на страницу будет выбираться одна из них.

<section class="random-links">
	<a data-links="['https://google.com/', 'https://youtube.com/', 'https://facebook.com/']">
		<img src="https://picsum.photos/id/110/250/250">
	</a>
	<a data-links="['https://wikipedia.org/', 'https://yahoo.com/', 'https://amazon.com/']">
		<img src="https://picsum.photos/id/238/250/250">
	</a>
	<a data-links="['https://twitter.com/', 'https://live.com/', 'https://instagram.com/']">
		<img src="https://picsum.photos/id/239/250/250">
	</a>
	<a data-links="['https://reddit.com/', 'https://netflix.com/', 'https://blogspot.com/']">
		<img src="https://picsum.photos/id/240/250/250">
	</a>
	<a data-links="['https://twitch.tv/', 'https://linkedin.com/', 'https://pinterest.com/']">
		<img src="https://picsum.photos/id/241/250/250">
	</a>
	<a data-links="['https://github.com/', 'https://stackoverflow.com/', 'https://whatsapp.com/']">
		<img src="https://picsum.photos/id/242/250/250">
	</a>
</section>

<script>

for(const link of document.querySelectorAll("section.random-links a")) {
	const urls = eval(link.dataset.links || "[]");
	if(urls.length === 0) continue;
	link.href = urls[urls.length * Math.random() | 0];
	link.target = "_blank";
}
	
</script>

Vikal 21.08.2019 23:37

Мужик, спасибо большое что ответил.
Я не думал, что тут вообще кто-то отвечает, уже забил на эту тему.

Пока шло это время я нашел другие решения, но вопросов меньше не стало. Обрисую новые данные, может что посоветуешь, т.к. я в js и прочем разбираюсь плохо, все приходится осваивать почти с 0.

Вообще передо мной стоит задача такая:
Есть несколько таблиц. Текст в эти таблицы добавляется из единого css-файла, из таблицы стилей через div и content. Это все работает.

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

Однако! Таких таблиц на данный момент уже 100, и планируется вводить новые, оттого с 100 страницами копаться это просто ад. Я нашел такое решение - рандомайзер для таблиц на 1 странице. Если надо припишу код, но суть в том, что в 1 HTML документ забивается сразу несколько таблиц (у меня по 20 штук) и при обновлении этой страницы выдается только 1 из них.

Это работает. Но только на компе. С телефона пробую - почему-то бесится размер шрифта, это просто ад. Часть таблиц с одним размером, часть с другим, я перерыл весь код, но ВСЕ таблицы одинаковые в плане форматирования, но размер РАЗНЫЙ, и это только на телефоне, на компе все ровно.

Вот теперь ищу альтернативу этому мракобесию.

Пока вижу вариант с твоим кодом (спасибо еще раз), сделать так - 1 страница, на ней 20 таблиц, у каждой таблицы anchor и ссылки ведут к анчерам, т.е. при клике на картинку-ссылку перекидывает на страницу со всеми таблицами и просто отматывает на нужный анчер. Но это криво... Остальные таблицы, по идее, должны быть скрыты.

В идеале мне нужен код, чтобы при обновлении страницы он выдавал 1 из ххх таблиц, записанных в этом же html-документе.

Пример таблицы:
<table>
<tr><td colspan="2">
<div class="con1-01"><!--ТЕКСТ--></div><br>
<div class="con2-01"><!--ТЕКСТ--></div><br>
<div class="con3-01"><!--ТЕКСТ--></div><br>
</td></tr>
<tr>
<td class="button1"><div class="imgbutton2">
<a href="1.html">
<img src="img/01.png" alt="123"></a></div></td>
<td class="button1"><a href="index.html">
<div class="button3">next</div></a></td></tr>
</table>

Вот таких таблиц, только с разными <div class="con-ХХХ"> 20 штук на 1 странице. Как сделать так, чтобы при обновлении страницы отображалась только 1 случайная из них?

Спасибо.

рони 21.08.2019 23:48

Vikal,
Пожалуйста, отформатируйте свой код!

Для этого его можно заключить в специальные теги: js/css/html и т.п., например:
[html run]
... минимальный код страницы с вашей проблемой
[/html]

О том, как вставить в сообщение исполняемый javascript и html-код, а также о дополнительных возможностях форматирования - читайте http://javascript.ru/formatting.

рони 21.08.2019 23:59

Vikal,
таблицам присвоить класс, в css на этот класс пропиcать скрытие, сделать выборку всех элементов с этим классом, выбрать один элемент по индексу (смотри выше строка 27), убрать класс с выбранного элемента.

Vikal 22.08.2019 12:05

Спасибо, я примерно так и представлял себе решение задачи. Но проблема в том, что я понимаю, о чем ты говоришь, но совершенно не знаю нюансов, чтобы воплотить это в коде.

Присвоить класс таблицам, я полагаю, можно по аналогии с классом для ячеек:
<table class="123"></table>



И видимо, скрыть так:
.123
{
display: none;
}


А далее я понятия не имею, что именно делать.
В чем и прошу помочь.
Спасибо.

рони 22.08.2019 12:30

Vikal,
<!DOCTYPE html>

<html>
<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">
  .hide{
      display: none;
  }
 </style>
 <script>
addEventListener("DOMContentLoaded", function() {
    const tables = document.querySelectorAll("table.hide"),
          table = tables[tables.length * Math.random() | 0];
          table.classList.remove("hide");
})

 </script>

</head>

<body>
<table class="hide">
    <tr>
        <td>1</td>
    </tr>
</table>
<table class="hide">
    <tr>
        <td>2</td>
    </tr>
</table>
<table class="hide">
    <tr>
        <td>3</td>
    </tr>
</table>
<table class="hide">
    <tr>
        <td>4</td>
    </tr>
</table>
<table class="hide">
    <tr>
        <td>5</td>
    </tr>
</table>

</body>
</html>

Vikal 22.08.2019 16:23

Спасибо, попробую.

Vikal 22.08.2019 16:44

Спасибо все работает. Но не работает как надо на телефоне. Может кто-то сталкивался и подскажет, потому как я уже с ума схожу. Вот документ с таблицами:
<!--v1-52-01--><table><tr><td colspan="2"><div class="con2-t-52-01"><!--ТЕКСТ--></div><br><div class="con4-t-52-01"><!--ТЕКСТ--></div><br><div class="con1-v-52"><!--ТЕКСТ--></div><br></td></tr></table>

<!--v2-52-01--><table><tr><td colspan="2"><div class="con1-t-52-01"><!--ТЕКСТ--></div><br><div class="con2-t-52-01"><!--ТЕКСТ--></div><br><div class="con4-v-52"><!--ТЕКСТ--></div><br></td></tr></table>

<!--v1-52-02--><table><tr><td colspan="2"><div class="con2-t-52-02"><!--ТЕКСТ--></div><br><div class="con4-t-52-02"><!--ТЕКСТ--></div><br><div class="con1-v-52"><!--ТЕКСТ--></div><br></td></tr></table>

<!--v2-52-02--><table><tr><td colspan="2"><div class="con1-t-52-02"><!--ТЕКСТ--></div><br><div class="con2-t-52-02"><!--ТЕКСТ--></div><br><div class="con4-v-52"><!--ТЕКСТ--></div><br></td></tr></table>


Как вы поняли, есть css файл, в котором находится ТЕКСТ, и который загружается в html в дивы <div class="con2-t-52-02"> и т.д. МАГИЯ в том, что если стоит 52 или 42 - шрифт скачет, он мелкий и не реагирует на css стили (или реагирует рандомно), но если в диве вместо 52 (один текст) поставить 11 (это другой текст) - ВСЕ РАБОТАЕТ, как надо. Какого дьявола? Разница между документами в 2х цифрах в диве css, но один работает, а другой нет!

То же самое, уважаемый Рони, и с вашим кодом. Сам по себе он работает отлично, но только не на телефоне. Все, что с 52 отображается мелко, ставишь 11 - то крупно, то мелко.
Телефон на андройде, браузер - яндекс.

Есть идеи почему так может быть?

Vikal 22.08.2019 17:14

Решил (НО ЭТО НЕ ТОЧНО) данный вопрос следующим образом.
Изначально все мои страницы управлялись через 1 файл таблицы стилей.

Теперь я добавил в каждую страницу код:
[head]
<style type="text/css">
  table   {      font-size: 40px;  } 
  </style>
[/head]


И шрифт (ВРОДЕ КАК) выровнялся... Но я уже ничему не верю.

Vikal 22.08.2019 17:52

Проверил еще раз на предмет изменения шрифта. С твоим кодом не работает шрифт, даже если его вписать в каждый отдельный документ. То большой, то маленький отображается. Я не могу понять в чем дело. Такое впечатление, что в части таблиц 40px шрифта урезается до 10-20, при этом магия та же, связана она с 42 и 52 в номере div.

Malleys 23.08.2019 05:17

Цитата:

Сообщение от Vikal
С телефона пробую - почему-то бесится размер шрифта

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

В мобильной версии Safari появился "мета тег viewport" (viewport meta tag), который позволяет веб-разработчикам контролировать размер окна просмотра и масштаб страницы. Многие другие мобильные браузеры также поддерживают этот тег, хотя он не является частью какого-либо веб-стандарта. Документация от Apple хорошо описывает, как веб-разработчики могут использовать этот тег. Например, вы можете добавить
<meta name="viewport" content="user-scalable=no, width=device-width">


Цитата:

Сообщение от Vikal
Вот таких таблиц, только с разными <div class="con-ХХХ"> 20 штук на 1 странице. Как сделать так, чтобы при обновлении страницы отображалась только 1 случайная из них?

Зачем вам 20 таблиц, если вы всё-равно показываете только одну? Храните свои данные в виде объекта (например, в формате JSON), которые вы сможете легко обрабатывать, и отрисовывать, как захотите. При таком подходе вы сможете легко менять шаблон.

Цитата:

Сообщение от Vikal
Пока вижу вариант с твоим кодом (спасибо еще раз), сделать так - 1 страница, на ней 20 таблиц, у каждой таблицы anchor и ссылки ведут к якорям, т.е. при клике на картинку-ссылку перекидывает на страницу со всеми таблицами и просто отматывает на нужный анчер. Но это криво... Остальные таблицы, по идее, должны быть скрыты.

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

Для того, чтобы это сделать, вам достаточно описать только одну таблицу, в которую будут вставляться данные. Это может, например, выглядеть так... (часть файла index.html)
<section id="home"></section>
<section id="gallery">
	<a class="home" href="#page=home">⌂ Home</a>
	<h2 id="title"></h2>
	<table>
		<tr>
			<td colspan="2" id="text"></td>
		</tr>
		<tr>
			<td>
				<a id="launchPlayerLink">
					<img id="poster">
				</a>
			</td>
			<td>
				<a id="next">Next</a>
			</td>
		</tr>
	</table>
	<button id="closeButton" hidden>×</button>
	<iframe id="videoPlayer" hidden width="560" height="315" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</section>
Данные будут вставляться через скрипт, и чтобы показать, насколько гибким является такой подход, я ещё в шаблон добавил видео и заголовок. (И все сотни представления таблиц теперь такие!)

Теперь нужно написать скрипт, который поместит на главную страницу картинки-ссылки на основе данных. Вот пример того, как могут выглядеть данные в JSON. (файл data.json)
{
	"songs": {
		"title": "Random Songs",
		"background": "https://picsum.photos/id/145/400/200",
		"items": [
			{
				"title": "It’s not safe to turn off your computer",
				"videoId": "vCwnsu_tNIs",
				"text": "Nothing stays alike from another perspective..."
			}, {
				"title": "Radioactive",
				"videoId": "2r0bx7R8UIg",
				"text": "I'm waking up, I feel it in my bones\nEnough to make my systems blow..."
			}
		]
	},
	"cooking": {
		"title": "Random Cooking",
		"background": "https://picsum.photos/id/1060/400/200",
		"items": [
			{
				"title": "Steak",
				"videoId": "h5gcJjOSDv4",
				"text": "How to cook steak"
			}, 
			{
				"title": "Fish’n’Chips",
				"videoId": "UtiI9Gy-De8",
				"text": "How to cook Classic Fish and Chips"
			}
		]
	}
}
Здесь указано две картинки-ссылки (а по сути раздел), указано какой текст выводить на ссылке, какую картинку использовать, указаны данные для таблиц внутри раздела. А вообще эти данные можно отрисовать каким угодно способом, возможности безграничны!

Теперь сам скрипт (недописанный файл tables_app.js)
const pg = {
	data: null,
	page: null,
	category: null,
	id: null,
	settings: {
		updateIdOnPageReload: true
	}
};

document.addEventListener("DOMContentLoaded", event => {
	fetch("data.json")
		.then(response => response.json())
		.then(data => {
			pg.data = data;
			urlHandler({ newURL: location.hash = location.hash || "#page=home" });
		
			if(pg.settings.updateIdOnPageReload) {
				var params = new URLSearchParams(location.hash.replace(/^#/g, ""));
				params.delete("id");
				location.replace(`#${params}`);
			}
		})
	;
});

addEventListener("hashchange", urlHandler);

function urlHandler(event) {
	var params = new URLSearchParams(new URL(event.newURL, location).hash.replace(/^#/g, ""));
	
	pg.page = params.get("page") || "home";
	pg.category = params.get("category");
	pg.id = params.get("id");
	pg.isPlayer = params.has("player");
	
	for(const section of $$("body > section[id]"))
		section.hidden = true;
	
	$(`body > section#${pg.page}`).hidden = false;
	
	// здесь происходит изменение вида, подстановка данных в зависимости от значении в pg
}

function $(selector, node) {
	return (node || document).querySelector(selector);
}

function $$(selector, node) {
	return (node || document).querySelectorAll(selector);
}
Сначала в скрипте загружается файл data.json. Каждый раз, когда происходит изменение в хеше URL (например, когда нажимают на ссылку, обновляют страницу), происходит вызов функции urlHandler, в которой происходит изменение страницы, чтобы она соответствовала нужным данным. Также вызов происходит сразу после загрузки данных, чтобы страница соответствовала виду, описываемому в хеше URL.

Вот полный рабочий пример с картинками-ссылками, при нажатии на которые открывается случайная таблица, построенная на основе данных... https://charm-launch.glitch.me/tables/
Чтобы посмотреть весь код, откройте сайт в инструментах разработчика (например в Chrome DevTools вкладка Sources)

Vikal 31.08.2019 16:37

Большое спасибо за такой развернутый ответ.
Согласен с вами, json действительно решает этот вопрос лучше.


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