- 13, May 2024
- #1
Я использую решение по адресу: https://www.cssscript.com/rss-feed-scroller-marquee/
чтобы создать щекотку для моей веб-страницы.
Все бы ничего, но тиклер просто показывал тексты rss ленты, но по ним невозможно было перейти к статье.
Поэтому я попытался вмешаться в него, создав правильный URL-адрес и попытавшись анимировать его.
Тем не менее, элемент кажется хорошо сконструированным, но когда я его анимирую, ничего не происходит.
Это код модифицированного класса js: /*! * RSS-выделение * *Лицензия MIT * Авторские права (c) 2020 г. [Сэмюэль Каррейра] */ класс RSSMarquee { /** *
*/
конструктор (feedURLs, elementContainer, параметры = {скорость: 110, maxItems: null, hostnameSelector: null }) {
this._feedURLs = новый массив();
если (Array.isArray(feedURLs)) {
this._feedURLs = фидURLs;
} еще {
this._feedURLs[0] = фидURLs;
}
const URLvalidation = this._feedURLs.every(this.validateURL);
если (!URLvalidation) {
throw new TypeError('Неверный URL в списке');
}
this._urlIndex = 0;
this._anim = ноль;
this._newsText = '';
this._lastTime = Date.now();
если (elementContainer === null) {
throw new TypeError('Неверный селектор элемента');
}
this._elementContainer = elementContainer;
this.styleElementContainer();
this._options = {
скорость: this.validateSpeed(options.speed),
maxItems: options.maxItems,
hostnameSelector: options.hostnameSelector,
// ...параметры
};
это.getRSS();
}
validateSpeed (скорость) {
if (!Number(скорость) || скорость < 50 || скорость > 300) { вернуть 110; // безопасное значение по умолчанию } еще { скорость возврата; } } /**
*/ set setSpeed(скорость) { this._options.speed = this.validateSpeed(скорость); } получить getSpeed() { верните this._options.speed; } /** * Проверка URL-адреса (используется интерфейс URL-адреса) *
*/ validateURL (URL) { пытаться { const u = новый URL (url); вернуть истину; } поймать (е) { вернуть ложь; } } /** * Получить имя хоста из строки URL *
*
*/
getHostname (URL) {
пытаться {
const u = новый URL (url);
вернуть имя u.host;
} поймать (е) {
возвращаться '';
}
}
получитьRSS() {
const url = this._feedURLs[this._urlIndex];
this.fetchRSS(url)
.then((xmlText) => {
this._newsText = this.parseXMLFeed(xmlText);
this.showMarquee(this._newsText);
this.showHostname(url);
})
.catch((ошибка) => {
console.error(ошибка);
это.handleErrors();
});
}
handleErrors() {
const diffTime = Date.now() - this._lastTime;
если (diffTime > 5000) {
console.log('Пробуем URL следующего канала...');
этот.следующийURL();
this._lastTime = Date.now();
} еще {
если (this._newsText === '') {
console.log('задержка...');
setTimeout(() => {
этот.следующийURL();
}, 5000);
} еще {
console.log('показать еще раз кэшированные сохраненные новости');
this.showMarquee(this._newsText);
}
}
}
следующийURL() {
это.increaseIndex();
это.getRSS();
}
styleElementContainer() {
this._elementContainer.style.overflow = 'скрытый';
this._elementContainer.style.whiteSpace = 'nowrap';
}
showHostname (URL) {
если (!this._options.hostnameSelector) {
возвращаться;
}
this._options.hostnameSelector.innerText = this.getHostname(url);
}
showMarquee(aCollection) {
пытаться {
const animKeyframes = [{
преобразование: 'translateX (0)'
},
{
преобразование: 'translateX(-100%)'
}
];
const animOptions = {
длительность: 25000, // Число миллисекунд, необходимое для завершения каждой итерации анимации.
По умолчанию — 0. Хотя это технически необязательно, имейте в виду, что ваша анимация не будет запускаться, если это значение равно 0. easing: 'linear', // Скорость изменения анимации со временем.
Принимает предопределенные значения «линейный», «ease», «ease-in», «ease-out» и «ease-in-out» или пользовательское значение «cubic-bezier», например «cubic-bezier( 0,42, 0, 0,58, 1)". По умолчанию «линейный». итераций: 1, // Сколько раз должна повторяться анимация.
По умолчанию установлено значение 1, а также может принимать значение бесконечности, чтобы оно повторялось до тех пор, пока существует элемент. задержка: 0, // Количество миллисекунд для задержки начала анимации.
По умолчанию 0. endDelay: 0 // Количество миллисекунд задержки после окончания анимации.
Это в первую очередь используется при упорядочивании анимации на основе времени окончания другой анимации.
По умолчанию 0.
};
animOptions.duration = aCollection.length * this._options.speed;
const elementChildNode = document.createElement('span');
elementChildNode.style.display = 'inline-block';
elementChildNode.style.paddingLeft = '100%';
//const textNode = document.createTextNode(text);
console.log(aCollection.lenght);
aCollection.forEach(функция(элемент, индекс, массив) {
elementChildNode.appendChild(пункт)
})
console.log("Итого:");
console.log(elementChildNode);
//elementChildNode.appendChild(textNode);
//this._elementContainer.appendChild(elementChildNode);
this._anim = elementChildNode.animate(animKeyframes, animOptions);
console.log('начать анимацию');
this._anim.onfinish = () => {
console.log('конец');
в то время как (this._elementContainer.firstChild) {
this._elementContainer.firstChild.remove();
}
удалить это._anim.onfinish;
этот.следующийURL();
};
this._lastTime = Date.now();
} поймать (ошибиться) {
console.error(ошибка);
}
}
увеличениеИндекс() {
this._urlIndex += 1;
if (this._urlIndex > this._feedURLs.length - 1) { this._urlIndex = 0; } } /**
*/ выборкаRSS (feedURL) { вернуть новое обещание((разрешить, отклонить) => { console.info(
fetch (feedURL, {режим: «корс», перенаправление: «следовать» })
.then((ответ) => {
вернуть ответ.текст();
})
.then((xmlTxt) => {
вернуть разрешение (xmlTxt);
})
.catch(() => {
console.error('Ошибка при получении RSS-канала');
отклонять();
})
});
}
/**
* Анализирует RSS XML-канал.
*
*
*/
parseXMLFeed (xmlText) {
пытаться {
const parser = новый DOMParser();
const doc = parser.parseFromString(xmlText, "text/xml");
пусть новости = '';
пусть aCollection=[];
пусть итоги = 0;
for (пусть элемент doc.querySelectorAll('item')) {
let title = item.getElementsByTagName("title")[0].childNodes[0].nodeValue;
// let описание = item.getElementsByTagName("description")[0].childNodes[0].nodeValue;
let link = item.getElementsByTagName("ссылка")[0].childNodes[0].nodeValue;
если (название) {
если (news.length) {
новости += '\xa0' + ' • ' + '\xa0';
}
заголовок = this.remoteCData(title);
заголовок = this.stripTags(title);
новости += заголовок;
var a = document.createElement('a');
вар linkText = document.createTextNode(title);
а.appendChild(linkText);
а.титул = заголовок;
а.href = ссылка;
aCollection.push(а);
итоги += 1;
}
if (this._options.maxItems !== null & & итоги >= this._options.maxItems) { console.info('Достигнуто максимальное количество элементов!'); перерыв; } } //console.log(aCollection); //console.log(новости); console.info(
вернуть коллекцию;
} поймать (ошибиться) {
console.error(ошибка);
возвращаться ' ';
}
}
StripTags (textWithTags) {
return textWithTags.replace(/<(.|\n)*?>/g, '');
}
удаленныйCData (оригинальныйтекст) {
return originalText.replace("", "");
}
}
Непроисходящая анимация находится в функции: showMarquee(aCollection). На оригинальном сайте показано, как это проверить.
Спасибо,
чтобы создать щекотку для моей веб-страницы.
Все бы ничего, но тиклер просто показывал тексты rss ленты, но по ним невозможно было перейти к статье.
Поэтому я попытался вмешаться в него, создав правильный URL-адрес и попытавшись анимировать его.
Тем не менее, элемент кажется хорошо сконструированным, но когда я его анимирую, ничего не происходит.
Это код модифицированного класса js: /*! * RSS-выделение * *Лицензия MIT * Авторские права (c) 2020 г. [Сэмюэль Каррейра] */ класс RSSMarquee { /** *
- @param {string[]}feedURLs URL-адреса каналов
- @param {object} elementContainer — селектор контейнера выделения.
- @param {число} options.speed длительность в мс на символ. Большие значения = низкая скорость
- @param {number} options.maxItems указывает максимальное количество отображаемых заголовков (полезно для отладки)
- @param {object} options.hostnameSelector Селектор элемента, в котором вы хотите отобразить URL-адрес источника ленты новостей (полезно для указания авторских прав).
*/
конструктор (feedURLs, elementContainer, параметры = {скорость: 110, maxItems: null, hostnameSelector: null }) {
this._feedURLs = новый массив();
если (Array.isArray(feedURLs)) {
this._feedURLs = фидURLs;
} еще {
this._feedURLs[0] = фидURLs;
}
const URLvalidation = this._feedURLs.every(this.validateURL);
если (!URLvalidation) {
throw new TypeError('Неверный URL в списке');
}
this._urlIndex = 0;
this._anim = ноль;
this._newsText = '';
this._lastTime = Date.now();
если (elementContainer === null) {
throw new TypeError('Неверный селектор элемента');
}
this._elementContainer = elementContainer;
this.styleElementContainer();
this._options = {
скорость: this.validateSpeed(options.speed),
maxItems: options.maxItems,
hostnameSelector: options.hostnameSelector,
// ...параметры
};
это.getRSS();
}
validateSpeed (скорость) {
if (!Number(скорость) || скорость < 50 || скорость > 300) { вернуть 110; // безопасное значение по умолчанию } еще { скорость возврата; } } /**
- Установите скорость анимации
- @param {number} значение скорости от 50 до 300.
*/ set setSpeed(скорость) { this._options.speed = this.validateSpeed(скорость); } получить getSpeed() { верните this._options.speed; } /** * Проверка URL-адреса (используется интерфейс URL-адреса) *
- @param {string} url URL для проверки
- @returns {boolean} true, если оно действительно
*/ validateURL (URL) { пытаться { const u = новый URL (url); вернуть истину; } поймать (е) { вернуть ложь; } } /** * Получить имя хоста из строки URL *
- Образец: "https://www.dnoticias.pt/rss/desporto.xml
"
- возвращает URL
*
- @param {string} URL строка URL
- @returns {строка} имя хоста
*/
getHostname (URL) {
пытаться {
const u = новый URL (url);
вернуть имя u.host;
} поймать (е) {
возвращаться '';
}
}
получитьRSS() {
const url = this._feedURLs[this._urlIndex];
this.fetchRSS(url)
.then((xmlText) => {
this._newsText = this.parseXMLFeed(xmlText);
this.showMarquee(this._newsText);
this.showHostname(url);
})
.catch((ошибка) => {
console.error(ошибка);
это.handleErrors();
});
}
handleErrors() {
const diffTime = Date.now() - this._lastTime;
если (diffTime > 5000) {
console.log('Пробуем URL следующего канала...');
этот.следующийURL();
this._lastTime = Date.now();
} еще {
если (this._newsText === '') {
console.log('задержка...');
setTimeout(() => {
этот.следующийURL();
}, 5000);
} еще {
console.log('показать еще раз кэшированные сохраненные новости');
this.showMarquee(this._newsText);
}
}
}
следующийURL() {
это.increaseIndex();
это.getRSS();
}
styleElementContainer() {
this._elementContainer.style.overflow = 'скрытый';
this._elementContainer.style.whiteSpace = 'nowrap';
}
showHostname (URL) {
если (!this._options.hostnameSelector) {
возвращаться;
}
this._options.hostnameSelector.innerText = this.getHostname(url);
}
showMarquee(aCollection) {
пытаться {
const animKeyframes = [{
преобразование: 'translateX (0)'
},
{
преобразование: 'translateX(-100%)'
}
];
const animOptions = {
длительность: 25000, // Число миллисекунд, необходимое для завершения каждой итерации анимации.
По умолчанию — 0. Хотя это технически необязательно, имейте в виду, что ваша анимация не будет запускаться, если это значение равно 0. easing: 'linear', // Скорость изменения анимации со временем.
Принимает предопределенные значения «линейный», «ease», «ease-in», «ease-out» и «ease-in-out» или пользовательское значение «cubic-bezier», например «cubic-bezier( 0,42, 0, 0,58, 1)". По умолчанию «линейный». итераций: 1, // Сколько раз должна повторяться анимация.
По умолчанию установлено значение 1, а также может принимать значение бесконечности, чтобы оно повторялось до тех пор, пока существует элемент. задержка: 0, // Количество миллисекунд для задержки начала анимации.
По умолчанию 0. endDelay: 0 // Количество миллисекунд задержки после окончания анимации.
Это в первую очередь используется при упорядочивании анимации на основе времени окончания другой анимации.
По умолчанию 0.
};
animOptions.duration = aCollection.length * this._options.speed;
const elementChildNode = document.createElement('span');
elementChildNode.style.display = 'inline-block';
elementChildNode.style.paddingLeft = '100%';
//const textNode = document.createTextNode(text);
console.log(aCollection.lenght);
aCollection.forEach(функция(элемент, индекс, массив) {
elementChildNode.appendChild(пункт)
})
console.log("Итого:");
console.log(elementChildNode);
//elementChildNode.appendChild(textNode);
//this._elementContainer.appendChild(elementChildNode);
this._anim = elementChildNode.animate(animKeyframes, animOptions);
console.log('начать анимацию');
this._anim.onfinish = () => {
console.log('конец');
в то время как (this._elementContainer.firstChild) {
this._elementContainer.firstChild.remove();
}
удалить это._anim.onfinish;
этот.следующийURL();
};
this._lastTime = Date.now();
} поймать (ошибиться) {
console.error(ошибка);
}
}
увеличениеИндекс() {
this._urlIndex += 1;
if (this._urlIndex > this._feedURLs.length - 1) { this._urlIndex = 0; } } /**
- Получить RSS
- @param {string} URL-адрес RSS XML-канала
*/ выборкаRSS (feedURL) { вернуть новое обещание((разрешить, отклонить) => { console.info(
Начать получение ${feedURL}...
);fetch (feedURL, {режим: «корс», перенаправление: «следовать» })
.then((ответ) => {
вернуть ответ.текст();
})
.then((xmlTxt) => {
вернуть разрешение (xmlTxt);
})
.catch(() => {
console.error('Ошибка при получении RSS-канала');
отклонять();
})
});
}
/**
* Анализирует RSS XML-канал.
*
- - Выберите титровальный элементContainer
- - добавить точку-разделитель между «заголовками»
- - удалить строку * - удалить html-теги
*
- @param {строка} xmlText
- @returns {строка} проанализированного канала
*/
parseXMLFeed (xmlText) {
пытаться {
const parser = новый DOMParser();
const doc = parser.parseFromString(xmlText, "text/xml");
пусть новости = '';
пусть aCollection=[];
пусть итоги = 0;
for (пусть элемент doc.querySelectorAll('item')) {
let title = item.getElementsByTagName("title")[0].childNodes[0].nodeValue;
// let описание = item.getElementsByTagName("description")[0].childNodes[0].nodeValue;
let link = item.getElementsByTagName("ссылка")[0].childNodes[0].nodeValue;
если (название) {
если (news.length) {
новости += '\xa0' + ' • ' + '\xa0';
}
заголовок = this.remoteCData(title);
заголовок = this.stripTags(title);
новости += заголовок;
var a = document.createElement('a');
вар linkText = document.createTextNode(title);
а.appendChild(linkText);
а.титул = заголовок;
а.href = ссылка;
aCollection.push(а);
итоги += 1;
}
if (this._options.maxItems !== null & & итоги >= this._options.maxItems) { console.info('Достигнуто максимальное количество элементов!'); перерыв; } } //console.log(aCollection); //console.log(новости); console.info(
Проанализировано ${totals} title(s)
);вернуть коллекцию;
} поймать (ошибиться) {
console.error(ошибка);
возвращаться ' ';
}
}
StripTags (textWithTags) {
return textWithTags.replace(/<(.|\n)*?>/g, '');
}
удаленныйCData (оригинальныйтекст) {
return originalText.replace("", "");
}
}
Непроисходящая анимация находится в функции: showMarquee(aCollection). На оригинальном сайте показано, как это проверить.
Спасибо,