使用冒号分隔的参数合并 URL
Merge URLs with colon-separated parameters
我正在尝试编写一个脚本来更新 JS 中以冒号分隔的参数的 URL,因为页面内容是通过 AJAX.
加载的
文档结构是这样的:
Format:
<div class="filter" id="formats">
<a class="active" href="https://cdpn.io/page/">All</a>
<a href="https://cdpn.io/page/format:foo">Foo</a>
<a href="https://cdpn.io/page/format:bar">Bar</a>
<a href="https://cdpn.io/page/format:baz">Baz</a>
<div>
<br>
Topic:
<div class="filter" id="topics">
<a class="active" href="https://cdpn.io/page/">All</a>
<a href="https://cdpn.io/page/topic:foo">Foo</a>
<a href="https://cdpn.io/page/topic:bar">Bar</a>
<a href="https://cdpn.io/page/topic:baz">Baz</a>
</div>
<br>
Sort By:
<div class="filter" id="sort">
<a href="https://cdpn.io/page/sort:topic-asc">Topic Asc</a>
<a href="https://cdpn.io/page/sort:topic-desc">Topic Desc</a>
<br>
<a href="https://cdpn.io/page/sort:title-asc">Title Asc</a>
<a href="https://cdpn.io/page/sort:title-desc">Title Desc</a>
</div>
<br>
Url loaded:
<div id="content">
https://cdpn.io/page
</div>
只有 #content
由 AJAX 库更新,所有 link 都需要“手动”更改。
例如:如果我点击一个过滤器-link,比如https://example.com/page/topic:foo
,页面内容被刷新,但是所有的过滤器都需要更新:https://example.com/page/format:bar
应该变成https://example.com/page/topic:foo/format:bar
等。每当单击任何过滤器时,如果现有参数不存在,则需要覆盖或附加现有参数,如果不存在,则将其删除。
我以为我已经通过将所有参数映射到一个对象数组中,然后使用我在 Whosebug 上找到的片段合并并返回字符串来解决这个问题,但我的逻辑似乎有错误,我不能'不要把我的手指放在上面......
const mergeByProperty = (target, source, prop) => {
source.forEach(sourceElement => {
let targetElement = target.find(targetElement => {
return sourceElement[prop] === targetElement[prop];
})
targetElement ? Object.assign(targetElement, sourceElement) : target.push(sourceElement);
})
}
for (el of document.querySelectorAll('a')) {
el.addEventListener('click', (e) => {
e.preventDefault();
loadNewContent(e.target);
})
}
const loadNewContent = (target) => {
document.querySelector('#content').innerText = target
// this is where page content is fetched & appended etc, then:
updateLinks(target)
}
const updateLinks = (trigger) => {
document.querySelectorAll('a').forEach(linkToUpdate => {
linkToUpdate.href = mergeURLs(linkToUpdate.href, trigger.href);
})
}
function mergeURLs(url1, url2) {
let params1 = getParams(url1)
let params2 = getParams(url2)
mergeByProperty(params1, params2, 'param')
let newParamString = params1.map(s => `${s.param}:${s.value}`).join('/');
return `${window.location.origin}/page/${newParamString}`;
}
这是我尝试过的代码笔的 link。
https://codepen.io/moevbiz/pen/OJRNNex?editors=0011
感谢任何提示或建议…
解决方案:我没有使用 URL 参数创建对象并尝试合并它们,而是使用正则表达式替换现有参数。
代码笔:https://codepen.io/moevbiz/pen/gOwrKYO?editors=0011
链接获取如下数据属性:
<a data-param="format" data-param-string="format:foo" href="https://cdpn.io/page/format:foo">Foo</a>
工作代码:
for (el of document.querySelectorAll('a')) {
el.addEventListener('click', (e) => {
e.preventDefault();
loadNewContent(e.target);
})
}
const loadNewContent = (trigger) => {
document.querySelector('#content').innerText = trigger;
updateLinks(trigger)
}
const updateLinks = (trigger) => {
document.querySelectorAll('a').forEach(linkToUpdate => {
if (linkToUpdate.dataset.param != trigger.dataset.param) { // only update links that don't belong to the same group of elements
linkToUpdate.href = merge(linkToUpdate.href, trigger.dataset.param, trigger.dataset.paramString);
}
})
}
const merge = (url, param, paramString) => {
let newUrl;
let regex = new RegExp(`(${param}:[^\/]*)`, "g")
function replaceParam(url, newParamString) {
return url.replace(regex, newParamString)
}
if (url.includes(`${param}:`)) { // replace param if it already exists, else append it to the href
newUrl = replaceParam(url, paramString)
} else {
newUrl = url.concat('/' + paramString)
}
return newUrl.replace(/([^:])(\/\/+)/g, '/'); // remove double slashes except after https://
}
我正在尝试编写一个脚本来更新 JS 中以冒号分隔的参数的 URL,因为页面内容是通过 AJAX.
加载的文档结构是这样的:
Format:
<div class="filter" id="formats">
<a class="active" href="https://cdpn.io/page/">All</a>
<a href="https://cdpn.io/page/format:foo">Foo</a>
<a href="https://cdpn.io/page/format:bar">Bar</a>
<a href="https://cdpn.io/page/format:baz">Baz</a>
<div>
<br>
Topic:
<div class="filter" id="topics">
<a class="active" href="https://cdpn.io/page/">All</a>
<a href="https://cdpn.io/page/topic:foo">Foo</a>
<a href="https://cdpn.io/page/topic:bar">Bar</a>
<a href="https://cdpn.io/page/topic:baz">Baz</a>
</div>
<br>
Sort By:
<div class="filter" id="sort">
<a href="https://cdpn.io/page/sort:topic-asc">Topic Asc</a>
<a href="https://cdpn.io/page/sort:topic-desc">Topic Desc</a>
<br>
<a href="https://cdpn.io/page/sort:title-asc">Title Asc</a>
<a href="https://cdpn.io/page/sort:title-desc">Title Desc</a>
</div>
<br>
Url loaded:
<div id="content">
https://cdpn.io/page
</div>
只有 #content
由 AJAX 库更新,所有 link 都需要“手动”更改。
例如:如果我点击一个过滤器-link,比如https://example.com/page/topic:foo
,页面内容被刷新,但是所有的过滤器都需要更新:https://example.com/page/format:bar
应该变成https://example.com/page/topic:foo/format:bar
等。每当单击任何过滤器时,如果现有参数不存在,则需要覆盖或附加现有参数,如果不存在,则将其删除。
我以为我已经通过将所有参数映射到一个对象数组中,然后使用我在 Whosebug 上找到的片段合并并返回字符串来解决这个问题,但我的逻辑似乎有错误,我不能'不要把我的手指放在上面......
const mergeByProperty = (target, source, prop) => {
source.forEach(sourceElement => {
let targetElement = target.find(targetElement => {
return sourceElement[prop] === targetElement[prop];
})
targetElement ? Object.assign(targetElement, sourceElement) : target.push(sourceElement);
})
}
for (el of document.querySelectorAll('a')) {
el.addEventListener('click', (e) => {
e.preventDefault();
loadNewContent(e.target);
})
}
const loadNewContent = (target) => {
document.querySelector('#content').innerText = target
// this is where page content is fetched & appended etc, then:
updateLinks(target)
}
const updateLinks = (trigger) => {
document.querySelectorAll('a').forEach(linkToUpdate => {
linkToUpdate.href = mergeURLs(linkToUpdate.href, trigger.href);
})
}
function mergeURLs(url1, url2) {
let params1 = getParams(url1)
let params2 = getParams(url2)
mergeByProperty(params1, params2, 'param')
let newParamString = params1.map(s => `${s.param}:${s.value}`).join('/');
return `${window.location.origin}/page/${newParamString}`;
}
这是我尝试过的代码笔的 link。
https://codepen.io/moevbiz/pen/OJRNNex?editors=0011
感谢任何提示或建议…
解决方案:我没有使用 URL 参数创建对象并尝试合并它们,而是使用正则表达式替换现有参数。
代码笔:https://codepen.io/moevbiz/pen/gOwrKYO?editors=0011
链接获取如下数据属性:
<a data-param="format" data-param-string="format:foo" href="https://cdpn.io/page/format:foo">Foo</a>
工作代码:
for (el of document.querySelectorAll('a')) {
el.addEventListener('click', (e) => {
e.preventDefault();
loadNewContent(e.target);
})
}
const loadNewContent = (trigger) => {
document.querySelector('#content').innerText = trigger;
updateLinks(trigger)
}
const updateLinks = (trigger) => {
document.querySelectorAll('a').forEach(linkToUpdate => {
if (linkToUpdate.dataset.param != trigger.dataset.param) { // only update links that don't belong to the same group of elements
linkToUpdate.href = merge(linkToUpdate.href, trigger.dataset.param, trigger.dataset.paramString);
}
})
}
const merge = (url, param, paramString) => {
let newUrl;
let regex = new RegExp(`(${param}:[^\/]*)`, "g")
function replaceParam(url, newParamString) {
return url.replace(regex, newParamString)
}
if (url.includes(`${param}:`)) { // replace param if it already exists, else append it to the href
newUrl = replaceParam(url, paramString)
} else {
newUrl = url.concat('/' + paramString)
}
return newUrl.replace(/([^:])(\/\/+)/g, '/'); // remove double slashes except after https://
}