A place to cache linked articles (think custom and personal wayback machine)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2 年之前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. title: How to update the URL of a page without causing a reload using vanilla JavaScript
  2. url: https://gomakethings.com/how-to-update-the-url-of-a-page-without-causing-a-reload-using-vanilla-javascript/
  3. hash_url: 2c67b87e1b880952bb277fc429cb8bf5
  4. <p>Yesterday, we looked at <a href="https://gomakethings.com/how-to-create-a-search-page-for-a-static-website-with-vanilla-js/">how to build a vanilla JavaScript search feature for a static website</a>. At the end, I mentioned…</p>
  5. <blockquote>
  6. <p>Tomorrow, I’ll show you how I update the URL with the search query, and run a search automatically on page load if there’s a query in the URL.</p>
  7. </blockquote>
  8. <p>Well, today is tomorrow, so let’s dig in!</p>
  9. <p><em><strong>Note:</strong> If you haven’t yet, you should probably read yesterday’s post first, or today’s won’t make much sense.</em></p>
  10. <h2 id="updating-the-url">Updating the URL</h2>
  11. <p>In our <code>search()</code> function, we create an array of regex patterns, get an array of matching items (sorted by how many matches they have), and then render them into the UI.</p>
  12. <p>Let’s create another function, <code>updateURL()</code>, to update the URL for us. We’ll pass in the search <code>query</code> as an argument.</p>
  13. <div class="highlight"><pre class="chroma"><code class="language-js" data-lang="js"><span class="cm">/**
  14. </span><span class="cm"> * Search for matches
  15. </span><span class="cm"> * @param {String} query The term to search for
  16. </span><span class="cm"> */</span>
  17. <span class="kd">function</span> <span class="nx">search</span> <span class="p">(</span><span class="nx">query</span><span class="p">)</span> <span class="p">{</span>
  18. <span class="c1">// ...
  19. </span><span class="c1"></span>
  20. <span class="c1">// Display the results
  21. </span><span class="c1"></span> <span class="nx">showResults</span><span class="p">(</span><span class="nx">results</span><span class="p">);</span>
  22. <span class="c1">// Update the URL
  23. </span><span class="c1"></span> <span class="nx">updateURL</span><span class="p">(</span><span class="nx">query</span><span class="p">);</span>
  24. <span class="p">}</span>
  25. </code></pre></div>
  26. <p>We’re going to use <a href="https://gomakethings.com/how-to-update-the-browser-url-without-refreshing-the-page-using-the-vanilla-js-history-api/">the <code>history.pushState()</code> method</a> to update our URL.</p>
  27. <p>This creates a new entry in the browser’s history (and updates the URL) <em>without</em> causing the page to reload. It accepts three arguments: the browser <code>state</code>, a <code>title</code> to use in the <code>document</code>, and the <code>url</code>.</p>
  28. <p>We’ll use the current <code>history.state</code>, no need to replace anything. We’ll also use the current <code>document.title</code>.</p>
  29. <p>For the <code>url</code>, we’ll combine the <code>location.origin</code> and <code>location.pathname</code>, then append the <code>?s</code> query string parameter, and use the <code>query</code> for its value. We’ll pass the <code>query</code> into the <code>encodeURI()</code> method to encode it.</p>
  30. <div class="highlight"><pre class="chroma"><code class="language-js" data-lang="js"><span class="cm">/**
  31. </span><span class="cm"> * Update the URL with a query string for the search string
  32. </span><span class="cm"> * @param {String} query The search query
  33. </span><span class="cm"> */</span>
  34. <span class="kd">function</span> <span class="nx">updateURL</span> <span class="p">(</span><span class="nx">query</span><span class="p">)</span> <span class="p">{</span>
  35. <span class="c1">// Create the properties
  36. </span><span class="c1"></span> <span class="kd">let</span> <span class="nx">state</span> <span class="o">=</span> <span class="nx">history</span><span class="p">.</span><span class="nx">state</span><span class="p">;</span>
  37. <span class="kd">let</span> <span class="nx">title</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">title</span><span class="p">;</span>
  38. <span class="kd">let</span> <span class="nx">url</span> <span class="o">=</span> <span class="nb">window</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">origin</span> <span class="o">+</span> <span class="nb">window</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">pathname</span> <span class="o">+</span> <span class="s1">'?s='</span> <span class="o">+</span> <span class="nb">encodeURI</span><span class="p">(</span><span class="nx">query</span><span class="p">);</span>
  39. <span class="p">}</span>
  40. </code></pre></div>
  41. <p>Finally, we can pass all three into the <code>history.pushState()</code> method to update the URL.</p>
  42. <div class="highlight"><pre class="chroma"><code class="language-js" data-lang="js"><span class="cm">/**
  43. </span><span class="cm"> * Update the URL with a query string for the search string
  44. </span><span class="cm"> * @param {String} query The search query
  45. </span><span class="cm"> */</span>
  46. <span class="kd">function</span> <span class="nx">updateURL</span> <span class="p">(</span><span class="nx">query</span><span class="p">)</span> <span class="p">{</span>
  47. <span class="c1">// Create the properties
  48. </span><span class="c1"></span> <span class="c1">// ...
  49. </span><span class="c1"></span>
  50. <span class="c1">// Update the URL
  51. </span><span class="c1"></span> <span class="nx">history</span><span class="p">.</span><span class="nx">pushState</span><span class="p">(</span><span class="nx">state</span><span class="p">,</span> <span class="nx">title</span><span class="p">,</span> <span class="nx">url</span><span class="p">);</span>
  52. <span class="p">}</span>
  53. </code></pre></div>
  54. <h2 id="running-a-search-on-page-load">Running a search on page load</h2>
  55. <p>If the URL has an <code>s</code> query string parameter when the page loads, we should also run a search immediately. This lets users bookmark search pages for later.</p>
  56. <p>First, we’ll create an <code>onload()</code> function to run immediately with the script.</p>
  57. <div class="highlight"><pre class="chroma"><code class="language-js" data-lang="js"><span class="c1">// Create a submit handler
  58. </span><span class="c1"></span><span class="nx">form</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="s1">'submit'</span><span class="p">,</span> <span class="nx">submitHandler</span><span class="p">);</span>
  59. <span class="c1">// Check for query strings onload
  60. </span><span class="c1"></span><span class="nx">onload</span><span class="p">();</span>
  61. </code></pre></div>
  62. <p>We’ll use <a href="https://gomakethings.com/getting-values-from-a-url-with-vanilla-js/">the <code>new URLSearchParams()</code> constructor</a> to create a <code>URLSearchParams</code> object from the <code>location.search</code> property.</p>
  63. <p>Then, we’ll use the <code>URLSearchParams.get()</code> method to look for a query string parameter with a key of <code>s</code>.</p>
  64. <p>If one is <em>not</em> found, we’ll use the <code>return</code> operator to end our function.</p>
  65. <div class="highlight"><pre class="chroma"><code class="language-js" data-lang="js"><span class="cm">/**
  66. </span><span class="cm"> * If there's a query string search term, search it on page load
  67. </span><span class="cm"> */</span>
  68. <span class="kd">function</span> <span class="nx">onload</span> <span class="p">()</span> <span class="p">{</span>
  69. <span class="kd">let</span> <span class="nx">query</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">URLSearchParams</span><span class="p">(</span><span class="nb">window</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">search</span><span class="p">).</span><span class="nx">get</span><span class="p">(</span><span class="s1">'s'</span><span class="p">);</span>
  70. <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">query</span><span class="p">)</span> <span class="k">return</span><span class="p">;</span>
  71. <span class="p">}</span>
  72. </code></pre></div>
  73. <p>If a <code>query</code> exists, we’ll update the <code>input.value</code> property with it so that the search field contains the search <code>query</code>. Then, we’ll pass the <code>query</code> into the <code>search()</code> function to run a search.</p>
  74. <p>The <code>URLSearchParams.get()</code> method automatically decodes the parameter for us, so we don’t need to worry about that.</p>
  75. <div class="highlight"><pre class="chroma"><code class="language-js" data-lang="js"><span class="cm">/**
  76. </span><span class="cm"> * If there's a query string search term, search it on page load
  77. </span><span class="cm"> */</span>
  78. <span class="kd">function</span> <span class="nx">onload</span> <span class="p">()</span> <span class="p">{</span>
  79. <span class="kd">let</span> <span class="nx">query</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">URLSearchParams</span><span class="p">(</span><span class="nb">window</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">search</span><span class="p">).</span><span class="nx">get</span><span class="p">(</span><span class="s1">'s'</span><span class="p">);</span>
  80. <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">query</span><span class="p">)</span> <span class="k">return</span><span class="p">;</span>
  81. <span class="nx">input</span><span class="p">.</span><span class="nx">value</span> <span class="o">=</span> <span class="nx">query</span><span class="p">;</span>
  82. <span class="nx">search</span><span class="p">(</span><span class="nx">query</span><span class="p">);</span>
  83. <span class="p">}</span>
  84. </code></pre></div>
  85. <p>Now, when someone reloads or revists a search page, a new search will automatically run.</p>