簡體   English   中英

使用冒號分隔的參數合並 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 庫更新,所有鏈接都需要“手動”更改。

例如:如果我點擊像https://example.com/page/topic:foo這樣的過濾器鏈接,頁面內容會刷新,但所有過濾器都需要更新: https://example.com/page/format:bar應變為https://example.com/page/topic:foo/format:bar等。每當單擊任何過濾器時,如果現有參數尚不存在,則需要覆蓋或附加它們,並在他們不存在。

我以為我已經通過映射對象數組中的所有參數來解決它,然后使用我在 StackOverflow 上找到的片段進行合並並返回字符串,但我的邏輯似乎有錯誤,我無法確定它…

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}`;
}

這是我嘗試過的codepen的鏈接。

https://codepen.io/moevbiz/pen/OJRNNex?editors=0011

感謝任何提示或建議...

解決方案:我沒有從 URL 參數創建 object 並嘗試合並它們,而是使用正則表達式替換現有參數。

代碼筆: 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, '$1/'); // remove double slashes except after https://
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM