【问题标题】:Merge URLs with colon-separated parameters使用冒号分隔的参数合并 URL
【发布时间】:2020-12-05 12:48:29
【问题描述】:

我正在尝试编写一个脚本来更新 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 上找到的 sn-p 进行合并并返回字符串来解决这个问题,但我的逻辑似乎有错误,我可以'别把我的手指放在上面……

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

这是我尝试过的代码笔的链接。

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

感谢任何提示或建议...

【问题讨论】:

    标签: javascript ajax kirby barbajs


    【解决方案1】:

    解决方案:我没有从 URL 参数创建对象并尝试合并它们,而是使用正则表达式替换现有参数。

    Codepen: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://
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-19
      • 1970-01-01
      • 1970-01-01
      • 2014-04-08
      • 1970-01-01
      相关资源
      最近更新 更多