1, review

Finally, the exciting part of integration

OK, continue to open our WebStorm 2021, vsCode party please open VSCode, news_Frontend project

Review index.html and news-view.html

<! DOCTYPEhtml>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8">
    <title>News Recommendation system</title>
    <link rel="stylesheet" href="css/normalize.css">
    <link rel="stylesheet" href="css/index.css">
    <script src="js/jQuery.js"></script>
  </head>
  <body>
    <! -- Page container -->
    <div id="app">
      <! - the head -- -- >
      <div class="header">
        <h3 class="header-title">NewsDemo</h3>
      </div>

      <! - main body - - >
      <div class="main clearfix">

        <! - the left column -- -- >
        <div class="main-left">
          <! -- Search box -->
          <div class="search">
            <label>
              <input type="text" class="search-input">
            </label>
            <button class="search-btn">search</button>
          </div>

          <p class="tips">Search keywords:<span>heyuan</span>And time consuming:<span>1234</span>Milliseconds, return:<span>456</span>news</p>

          <div class="container">
            <h3 class="news-list-title">The search results</h3>
            <ul>
              <li class="news-list-item">
                <a href="https://www.baidu.com" target="_blank">1. Jack is awesome hahaha</a>
              </li>
            </ul>
          </div>
        </div>

        <! -- > - the right hand column
        <div class="main-right">
          <div class="container">
            <h3 class="news-list-title">The search results</h3>
            <ul>
              <li class="news-list-item">
                <a href="https://www.baidu.com" target="_blank">1. Jack is awesome hahaha</a>
              </li>
            </ul>
          </div>
        </div>
      </div>

      <! - the footer - >
      <div class="footer">
        <p>Copyright 2021-2077 Jack All rights reserved.</p>
      </div>
    </div>
  </body>
</html>
Copy the code
<! DOCTYPEhtml>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8">
    <title>News details</title>
    <link rel="stylesheet" href="css/normalize.css">
    <link rel="stylesheet" href="css/news-view.css">
    <script src="js/jQuery.js"></script>
  </head>
  <body>
    <! -- Page container -->
    <div id="app">
      <! - the head -- -- >
      <div class="header">
        <h3 class="header-title">NewsDemo</h3>
      </div>

      <! - main body - - >
      <div class="main clearfix">

        <! - the left column -- -- >
        <div class="main-left">
          <div class="container">
            <p class="breadcrumb">Home >> News</p>
            <h3 class="news-title">News headlines</h3>
            <p class="news-info">Id: 1234 docno: abcd1234efgh5678 url:http://news.sohu.com/121342.html</p>
            <p class="news-content">News news news content news content content news news news content news content content news news news content news content content news news news content news content content news news news content news content content news news content news content news content News content News content News news news content news content content news news news content news content content news news news content news content content news news news content news content content news news news content news content content news news content news content news content News content News content</p>
          </div>
        </div>

        <! -- > - the right hand column
        <div class="main-right">
          <div class="container">
            <h3 class="news-list-title">The search results</h3>
            <ul>
              <li class="news-list-item">
                <a href="https://www.baidu.com" target="_blank">1. Jack is awesome hahaha</a>
              </li>
            </ul>
          </div>
        </div>
      </div>

      <! - the footer - >
      <div class="footer">
        <p>Copyright 2021-2077 Jack All rights reserved.</p>
      </div>
    </div>
  </body>
</html>
Copy the code

2. Realize the interaction between home page and back end

1. Test the communication before and after the end

Create a new script tag between the app and the body and start writing our logic. Without further comment, let’s throw a jQuery Ajax override

<script>
	$.ajax({
		url: 'http://localhost:8080/demo/article-view'.method: 'get'.data: {
			id: 1
		},
		success: function (result) {
			console.log(result)
		}
	})
</script>
Copy the code

Open a browser, found an error, obviously, I am a little experience of friend should see that this is the cross domain problems, cross-domain was caused by a browser security mechanism, if the current url protocol, domain name or port any different trigger the cross-domain, specific details can baidu, here only talk about the solution, of course, there are many ways to solve We chose to use the backend CORS (Cross-domain Resource Sharing, W3C standard) approach, which is the recommended approach

Therefore, we create a new class CorsFilter under the filter package of the back-end project and configure it with annotations. By default, all paths are blocked

package com.example.demo.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebFilter("/*")
public class CorsFilter implements Filter {
  @Override
  public void init(FilterConfig filterConfig) {}@Override
  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) servletRequest;
    HttpServletResponse response = (HttpServletResponse) servletResponse;
    String originalURL = request.getHeader("Origin");
    if(originalURL ! =null) {
      response.addHeader("Access-Control-Allow-Origin", originalURL);
    }
    response.addHeader("Access-Control-Allow-Credentials"."true");
    filterChain.doFilter(request, response);
  }

  @Override
  public void destroy(a) {}}Copy the code

Then restart the project, and you will find that the startup error is due to the servlet version being too high, just change it to 3.1.0 (this echoes the points mentioned in the System Framework Design – Backend section).

<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>javax.servlet-api</artifactId>
  <version>3.1.0</version>
  <scope>provided</scope>
</dependency>
Copy the code

Then refresh Maven and restart the server again. Refresh the news recommendation system home page and find that the console has obtained the data from the back end

2. Develop search

Start by adding an ID to the search button and search box

<! -- Search box -->
<div class="search">
  <label>
    <input id="search-input" type="text" class="search-input">
  </label>
  <button id="search-btn" class="search-btn">search</button>
</div>
Copy the code

And then there’s a ton of requests

<script>
  $('#search-btn').click(function() {
    // Get the input value of the search box and remove the first and last Spaces
    let word = $('#search-input').val().trim();
    // The keyword is empty or blank
    if (word === "") {
      // Prompt the user to enter keywords before searching
      alert('What are you looking for, dear?');
      return;
    }
    // Make a network request to invoke the back-end search interface
    $.ajax({
      url: 'http://localhost:8080/demo/article-search'.method: 'get'.data: {
        word: word
      },
      success: function (result) {
        console.log(result)
      }
    })
  })
</script>
Copy the code

At this point, you can see the data from the backend (wait more than 5 seconds)

Then it’s time to render the search results to the page by replacing the template strings in a more understandable way

Look at my operation to know ~

Let’s start by wrapping the search result item Li with a template layer so we can get the HTML code

<div class="container">
  <h3 class="news-list-title">The search results</h3>
  <ul>
    <template id="search-result-template">
      <li class="news-list-item">
        <a href="https://www.baidu.com" target="_blank">1. Jack is awesome hahaha</a>
      </li>
    </template>
  </ul>
</div>
Copy the code

Why do I call it template? Because I like it easy to understand, it doesn’t matter what we call it, as long as we can get our template, but template hides the elements inside, so it doesn’t show up until the result is rendered, okay

<li class="news-list-item">
  <a href="https://www.baidu.com" target="_blank">1. Jack is awesome hahaha</a>
</li>
Copy the code

You can use the familiar ${}, {{}}, etc., but here I’ve used the simplest {} for the sake of missing a few symbols

<li class="news-list-item">
  <a href="{url}" target="_blank">
    {title}
  </a>
</li>
Copy the code

Then you can do whatever you want in the callback function

success: function (result) {
  // Get the template string
  let template = $('#search-result-template').html();
  // Store the total HTML code for the list
  let html =' ';
  // News URL prefix
  let baseUrl = "news-view.html? id=";
  // Iterate over the result set
  result.list.forEach(function(item) {
    // Replace the template string with the specific content and concatenate the template
    html += template.replace('{url}', baseUrl + item.id)
      .replace('{title}', item.title);
  })
  // Place the concatenated HTML code in the appropriate location
  $('#search-result').html(html)
}
Copy the code

A little hard to understand? Here’s a picture to calm the nerves

Well, that’s pretty much the basic idea, it’s just a matter of replacing the specified string, but there are a lot of solutions, and this is the easy one

The effect

3. Develop random recommendations

This is the code for the right column

<! -- > - the right hand column
<div class="main-right">
  <div class="container">
    <h3 class="news-list-title">The search results</h3>
    <ul>
      <li class="news-list-item">
        <a href="https://www.baidu.com" target="_blank">1. Jack is awesome hahaha</a>
      </li>
    </ul>
  </div>
</div>
Copy the code

This is the code for the search results

<div class="container">
  <h3 class="news-list-title">The search results</h3>
  <ul id="search-result">
    <template id="search-result-template">
      <li class="news-list-item">
        <a href="{url}" target="_blank">
          {title}
        </a>
      </li>
    </template>
  </ul>
</div>
Copy the code

Careful friends may notice that the right column is similar to the search results code, even the title is not changed, this is to improve reusability, so we take the same approach, not to repeat here

<! -- > - the right hand column
<div class="main-right">
  <div class="container">
    <h3 class="news-list-title">The news is recommended</h3>
    <ul>
      <template id="recommend-result-template">
        <li class="news-list-item">
          <a href="{url}" target="_blank">
            {title}
          </a>
        </li>
      </template>
    </ul>
  </div>
</div>
Copy the code
// Make a network request to invoke the back-end recommendation interface
$.ajax({
  url: 'http://localhost:8080/demo/article-random'.method: 'get'.data: {
    size: 10
  },
  success: function (result) {
    let template = $('#recommend-result-template').html();
    let html =' ';
    let baseUrl = "news-view.html? id=";
    result.forEach(function(item) {
      html += template.replace('{url}', baseUrl + item.id)
        .replace('{title}', item.title); $(})'#recommend-result').html(html)
  }
})
Copy the code

Refresh the page to see the effect

The effect

4. Develop search result information

Next, develop the search result information

First look at the structure of the search result information

<p class="tips">Search keywords:<span>heyuan</span>And time consuming:<span>1234</span>Milliseconds, return:<span>456</span>news</p>
Copy the code

I’m going to add an ID to get the element

<p id="tips" class="tips">Search keywords:<span>{word}</span>And time consuming:<span>{duration}</span>Milliseconds, return:<span>{size}</span>news</p>
Copy the code

Then we do the same thing, but we need to replace after we get the search results, so we need to write the logic in the callback function

success: function (result) {
  // The original logic
  // let template = $('#search-result-template').html();
  // let html ='';
  // let baseUrl = "news-view.html? id=";
  // result.list.forEach(function(item) {
  // html += template.replace('{url}', baseUrl + item.id)
  // .replace('{title}', item.title);
  // })
  // $('#search-result').html(html)
	
  // Add logic
  // Render the search result information
  let tips = $('#tips').html().replace('{word}', word)
  .replace('{duration}', result.duration)
  .replace('{size}', result.size);
  $('#tips').html(tips)
}
Copy the code

Then open the browser to refresh and find…

The default display with {} is a little unfriendly, so what should I do? Let’s add another layer of template ~

<p id="tips" class="tips">
  <template id="real-tips">Search keywords:<span>{word}</span>And time consuming:<span>{duration}</span>Milliseconds, return:<span>{size}</span>news</template>
</p>
Copy the code

Of course, the JS part also needs a little change

// Render the search result information
let tips = $('#real-tips').html().replace('{word}', word)
.replace('{duration}', result.duration)
.replace('{size}', result.size);
$('#tips').html(tips)
Copy the code

Then it’s hidden by default until we’re done searching it

5. Improve search

Search now there are still some details, such as keyword and press enter didn’t help me to search, and then there are the search process should be modal dialog prompt lets users wait for search results, then the search results to paging, of course, the paging to cooperate the back-end, however, now temporarily do not intend to use the paging, in subsequent tutorial will perfect the paging, Let’s get started

First, the js code in the home page already has some volume, so let’s move it to index.js

// Click the search button
$('#search-btn').click(function () {
  // Get the input value of the search box and remove the first and last Spaces
  let word = $('#search-input').val().trim();
  // The keyword is empty or blank
  if (word === "") {
    // Prompt the user to enter keywords before searching
    alert('What are you looking for, dear?');
    return;
  }
  // Make a network request to invoke the back-end search interface
  $.ajax({
    url: 'http://localhost:8080/demo/article-search'.method: 'get'.data: {
      word: word
    },
    success: function (result) {
      let template = $('#search-result-template').html();
      let html = ' ';
      let baseUrl = "news-view.html? id=";
      result.list.forEach(function (item) {
        html += template.replace('{url}', baseUrl + item.id)
          .replace('{title}', item.title); $(})'#search-result').html(html)

      // Render the search result information
      let tips = $('#real-tips').html().replace('{word}', word)
      .replace('{duration}', result.duration)
      .replace('{size}', result.size);
      $('#tips').html(tips)
    }
  })
})

// Make a network request to invoke the back-end recommendation interface
$.ajax({
  url: 'http://localhost:8080/demo/article-random'.method: 'get'.data: {
    size: 10
  },
  success: function (result) {
    let template = $('#recommend-result-template').html();
    let html = ' ';
    let baseUrl = "news-view.html? id=";
    result.forEach(function (item) {
      html += template.replace('{url}', baseUrl + item.id)
        .replace('{title}', item.title); $(})'#recommend-result').html(html)
  }
})

Copy the code

Since the callback for search is also used for the return search, let’s extract it and make it the search method

// Search the callback function
function search() {
  // Get the input value of the search box and remove the first and last Spaces
  let word = $('#search-input').val().trim();
  // The keyword is empty or blank
  if (word === "") {
    // Prompt the user to enter keywords before searching
    alert('What are you looking for, dear?');
    return;
  }
  // Make a network request to invoke the back-end search interface
  $.ajax({
    url: 'http://localhost:8080/demo/article-search'.method: 'get'.data: {
      word: word
    },
    success: function (result) {
      let template = $('#search-result-template').html();
      let html = ' ';
      let baseUrl = "news-view.html? id=";
      result.list.forEach(function (item) {
        html += template.replace('{url}', baseUrl + item.id)
          .replace('{title}', item.title); $(})'#search-result').html(html)

      // Render the search result information
      let tips = $('#real-tips').html().replace('{word}', word)
        .replace('{duration}', result.duration)
        .replace('{size}', result.size);
      $('#tips').html(tips)
    }
  })
}

// Click the search button
$('#search-btn').click(search)
Copy the code

1. Press Enter to search

$('#search-input').keyup(function(e) {
  // If the key pressed is enter on the keypad or Enter on the keypad
  if (e.code === "NumpadEnter" || e.code=== "Enter") {
    // Perform a search
    search()
  }
})
Copy the code

2. Mode box

Modal box plug-in many, but in this project we can use, but not necessary, direct hand tear him not sweet, so we directly develop their own modal box

Development process is more boring, also pretty simple, you must not in the mood to see, so this code directly calculate, tell you how to use it, in order to try with other plug-ins naming conflicts, I gave a name to this modal box jk – modal, as to why called jk, because my English name is Jack, cough cough cough, better don’t talk nonsense, Begin to enter the topic ~

  • Create a new folder jk-modal under the project, and create jk-modal. CSS and jk-modal.js to store the style and logic respectively

  • Jk – modal. CSS:

    #jk-modal {    position: fixed;    width: 100%;    height: 100%;    top: 0;    left: 0;    right: 0;    bottom: 0;    background-color: rgba(0.0.0.5);    transition: all .15slinear; }.jk-modal-box {    box-sizing: border-box;    position: absolute;    top: 50%;    left: 50%;    transform: translate(-50%, -200%);    transition: all .15s ease-in-out;    min-width: 300px;    min-height: 130px;    background-color: #fff;    border-radius: 5px;    padding: 15px; }.jk-modal-title {    margin: 0;    padding-bottom: 15px;    border-bottom: 1px solid #eee; }.jk-modal-text {    padding: 15px 0;    margin: 0;    font-size: 15px;    line-height: 25px; }.jk-show {    opacity: 1;    visibility: visible; }.jk-show .jk-modal-box {    transform: translate(-50%, -50%); }.jk-hide {    opacity: 0;    visibility: hidden; }Copy the code
  • jk-modal.js

    function Modal(config) {  this.width = config.width  this.height = config.height  this.title = config.title  this.text = config.text  this.init = function() {    let template =      '<div class="jk-modal-box" style="width={width}; height={height}"><h3 class="jk-modal-title">{title}</h3><p class="jk-modal-text">{text}</p></div>'    template = template.replace("{width}".this.width + 'px')      .replace("{height}".this.height + 'px')      .replace("{title}".this.title)      .replace("{text}".this.text)    let div = document.createElement('div')    div.id = "jk-modal"    div.className = "jk-hide"    div.innerHTML = template    document.body.appendChild(div)  }  this.show = function() {$('#jk-modal').removeClass('jk-hide').addClass('jk-show')}this.hide = function() {$('#jk-modal').removeClass('jk-show').addClass('jk-hide')}}Copy the code
  • The test case is modal.html

    <! DOCTYPEhtml><html lang="zh-CN">  <head>    <meta charset="UTF-8">    <title>Test the modal box</title>    <link rel="stylesheet" href="jk-modal/jk-modal.css">  </head>  <body>    <button id="btn">Click on me to bring up the mode box</button>    <script src="js/jQuery.js"></script>    <script src="jk-modal/jk-modal.js"></script>    <script>      let modal = new Modal({        width: 300.height: 200.title: "A title".text: "Jack, don't..."      });      modal.init()      $('#btn').click(function() {        modal.show();      })    </script>  </body></html>
    Copy the code

    Note: This plugin relies on jquery, so import jquery before using it

Introduce jK-modal.css and jK-modal.js in index.html, and then modify the code in index.js

// Initialize the mode box
let modal = new Modal({
  width: 300.height: 200.title: "Tip".text: "Ongoing search..."
});
modal.init();

function search() {
  let word = $('#search-input').val().trim();
  if (word === "") {
    alert('What are you looking for, dear?');
    return;
  }
  
  // Display the mode box
  modal.show();

  $.ajax({
    url: 'http://localhost:8080/demo/article-search'.method: 'get'.data: {
      word: word
    },
    success: function (result) {
      let template = $('#search-result-template').html();
      let html = ' ';
      let baseUrl = "news-view.html? id=";
      result.list.forEach(function (item) {
        html += template.replace('{url}', baseUrl + item.id)
          .replace('{title}', item.title); $(})'#search-result').html(html);
      let tips = $('#real-tips').html().replace('{word}', word)
        .replace('{duration}', result.duration)
        .replace('{size}', result.size);
      $('#tips').html(tips);

      // Hide the mode box
      modal.hide()
    }
  })
}

$('#search-btn').click(search);
$('#search-input').keyup(function (e) {
  if (e.code === "NumpadEnter" || e.code === "Enter") {
    search();
  }
})

$.ajax({
  url: 'http://localhost:8080/demo/article-random'.method: 'get'.data: {
    size: 10
  },
  success: function (result) {
    let template = $('#recommend-result-template').html();
    let html = ' ';
    let baseUrl = "news-view.html? id=";
    result.forEach(function (item) {
      html += template.replace('{url}', baseUrl + item.id)
        .replace('{title}', item.title); $(})'#recommend-result').html(html); }})Copy the code

The annotated sections above are the ones that need to be modified

Try the effect ~

Note: If there is no response, it is not the code, but the browser cache, and you can force a refresh (hold down SHIFT and hit the refresh button).

Of course, the mode frame can be changed to make it more delicate, but I’ll leave the details to you

3. Realize the interaction between the news details page and the back end

1. Develop random recommendations

Because the random recommendation of the news details page is the same as the first page, you can copy it directly

Review news – the HTML

<! DOCTYPEhtml>
<html lang="zh-CN">
<head>
 <meta charset="UTF-8">
 <title>News details</title>
 <link rel="stylesheet" href="css/normalize.css">
 <link rel="stylesheet" href="css/news-view.css">
 <script src="js/jQuery.js"></script>
</head>
<body>
<! -- Page container -->
<div id="app">
 <! - the head -- -- >
 <div class="header">
  <h3 class="header-title">NewsDemo</h3>
 </div>

 <! - main body - - >
 <div class="main clearfix">

  <! - the left column -- -- >
  <div class="main-left">
   <div class="container">
    <p class="breadcrumb">Home >> News</p>
    <h3 class="news-title">News headlines</h3>
    <p class="news-info">Id: 1234 docno: abcd1234efgh5678 url:http://news.sohu.com/121342.html</p>
    <p class="news-content">News news news content news content content news news news content news content content news news news content news content content news news news content news content content news news news content news content content news news content news content news content News content News content News news news content news content content news news news content news content content news news news content news content content news news news content news content content news news news content news content content news news content news content news content News content News content</p>
   </div>
  </div>

  <! -- > - the right hand column
  <div class="main-right">
   <div class="container">
    <h3 class="news-list-title">The search results</h3>
    <ul>
     <li class="news-list-item">
      <a href="https://www.baidu.com" target="_blank">1. Jack is awesome hahaha</a>
     </li>
    </ul>
   </div>
  </div>
 </div>

 <! - the footer - >
 <div class="footer">
  <p>Copyright 2021-2077 Jack All rights reserved.</p>
 </div>
</div>
</body>
</html>
Copy the code

Replace the right column

<! -- > - the right hand column
<div class="main-right">
  <div class="container">
    <h3 class="news-list-title">The news is recommended</h3>
    <ul id="recommend-result">
      <template id="recommend-result-template">
        <li class="news-list-item">
          <a href="{url}" target="_blank">
            {title}
          </a>
        </li>
      </template>
    </ul>
  </div>
</div>
Copy the code

Of course, we have to copy the JS logic, but it would be redundant to copy it directly, so we extract this part of the logic into a separate JS file named common.js

// Make a network request to invoke the back-end recommendation interface
$.ajax({
  url: 'http://localhost:8080/demo/article-random'.method: 'get'.data: {
    size: 10
  },
  success: function (result) {
    let template = $('#recommend-result-template').html();
    let html = ' ';
    let baseUrl = "news-view.html? id=";
    result.forEach(function (item) {
      html += template.replace('{url}', baseUrl + item.id)
        .replace('{title}', item.title); $(})'#recommend-result').html(html); }})Copy the code

Then the two pages can import the file in the header respectively

Effect:

2, development news details

First create news-view.js to write the logic of the news detail page, and then introduce it under the app

Then there’s the request

First of all to get the path inside the ID value, directly with JS hand tear

function getQueryVariable(name) {
  let query = window.location.search.substring(1);
  let params = query.split("&");
  for (let i = 0; i < params.length; i++) {
    let pair = params[i].split("=");
    if (pair[0] === name) {
      return pair[1]; }}return false;
}
Copy the code

And then you can do Ajax

// Make a network request to invoke the back-end to get news details interface
$.ajax({
  url: 'http://localhost:8080/demo/article-view'.method: 'get'.data: {
    id: getQueryVariable("id") | |1
  },
  success: function (result) {
    let template = $('#news-detail-template').html();
    let html = template.replace('{id}', result.id)
      .replace('{docno}', result.docno)
      .replace('{url}', result.url)
      .replace('{title}', result.title)
      .replace('{content}', result.content);
    $('#news-detail').html(html); }})Copy the code

Note: use a js common optimization code written in getQueryVariable (” id “) | | 1, if no pass id come getQueryVariable (” id “) has a value of false id value is 1

Effect:

This is the end of the second tutorial on jquery