中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

用vs2010做的網(wǎng)站網(wǎng)頁設(shè)計模板圖片

用vs2010做的網(wǎng)站,網(wǎng)頁設(shè)計模板圖片,廣州市民政局網(wǎng)站建設(shè),網(wǎng)站被降權(quán)如何恢復(fù)零 項目背景/原理/技術(shù)棧 1.介紹boost準(zhǔn)標(biāo)準(zhǔn)庫 2.項目實現(xiàn)效果 3.搜索引擎宏觀架構(gòu)圖 這是一個基于Web的搜索服務(wù)架構(gòu) 客戶端-服務(wù)器模型:采用了經(jīng)典的客戶端-服務(wù)器模型,用戶通過客戶端與服務(wù)器交互,有助于集中管理和分散計算。簡單的用戶…

零 項目背景/原理/技術(shù)棧

1.介紹boost準(zhǔn)標(biāo)準(zhǔn)庫

2.項目實現(xiàn)效果

3.搜索引擎宏觀架構(gòu)圖

這是一個基于Web的搜索服務(wù)架構(gòu)

  1. 客戶端-服務(wù)器模型:采用了經(jīng)典的客戶端-服務(wù)器模型,用戶通過客戶端與服務(wù)器交互,有助于集中管理和分散計算。
  2. 簡單的用戶界面:客戶端似乎很簡潔,用戶通過簡單的HTTP請求與服務(wù)端交互,易于用戶操作。
  3. 搜索引擎功能:服務(wù)器端的搜索器能夠接收查詢請求,從數(shù)據(jù)存儲中檢索信息,這是Web搜索服務(wù)的核心功能。
  4. 數(shù)據(jù)存儲:有專門的存儲系統(tǒng)用于存放數(shù)據(jù)文件(如HTML文件),有助于維護數(shù)據(jù)的完整性和持久性。
  5. 模塊分離:搜索器、存儲和處理請求的模塊被分開,這有助于各模塊獨立更新和維護.

4.搜索過程的原理~正排,倒排索引

5.技術(shù)棧和項目環(huán)境,工具

技術(shù)棧:C/C++ C++11 STL boost準(zhǔn)標(biāo)準(zhǔn)庫 JsonCPP cppjieba cpp-httplib?
html css js jQuery Ajax

項目環(huán)境:Centos7? 華為云服務(wù)器 gcc/g++/makefile Vscode

一 Paser數(shù)據(jù)清洗,獲取數(shù)據(jù)源模塊


const std::string src_path = "data/input/";
const std::string output_file = "data/output/dest.txt";
class DocInfo
{
public:std::string _title;std::string _content;std::string _url;
};

Paser模塊主邏輯?

int main()
{std::vector<std::string> files_list;// 第一步 把搜索范圍src_path內(nèi)的所有html的路徑+文件名放到 files_list中if (!EnumFileName(src_path, &files_list)){lg(_Error,"%s","enum filename err!");exit(EnumFileNameErr);}// 第二步 將files_list中的文件打開,讀取并解析為DocInfo后放到 web_documents中std::vector<DocInfo> html_documents;if (!ParseHtml(files_list, &html_documents)){lg(_Error,"%s","parse html err!");exit(ParseHtmlErr);}// 第三步 將web_documents的信息寫入到 output_file文件中, 以\3為每個文檔的分隔符if (!SaveHtml(html_documents, output_file)){lg(_Error,"%s","save html err!");exit(SaveHtmlErr);}
}
  1. 枚舉文件:從給定的源路徑(src_path)中枚舉所有HTML文件,并將它們的路徑和文件名放入files_list中。

  2. 解析HTML:讀取files_list中的每個文件,解析它們?yōu)?strong>DocInfo對象(可能包含標(biāo)題、URL、正文等元素),然后存儲到html_documents向量中。

  3. 保存文檔:將html_documents中的文檔信息寫入到指定的輸出文件output_file中,文檔之間用\3(ASCII碼中的End-of-Text字符)分隔。

EnumFileName

bool EnumFileName(const std::string &src_path, std::vector<std::string> *files_list)
{namespace fs = boost::filesystem;fs::path root_path(src_path);if (!fs::exists(root_path)) // 判斷路徑是否存在{lg(_Fatal,"%s%s",src_path.c_str()," is not exist");return false;}// 定義一個空迭代器,用來判斷遞歸是否結(jié)束fs::recursive_directory_iterator end;// 遞歸式遍歷文件for (fs::recursive_directory_iterator it(src_path); it != end; it++){if (!fs::is_regular(*it))continue; // 保證是普通文件if (it->path().extension() != ".html")continue; // 保證是.html文件files_list->push_back(it->path().string()); // 插入的都是合法 路徑+.html文件名}return true;
}

ParseHtml

bool ParseHtml(const std::vector<std::string> &files_list, std::vector<DocInfo> *html_documents)
{for (const std::string &html_file_path : files_list){// 第一步 遍歷files_list,根據(jù)路徑+文件名,讀取html文件內(nèi)容std::string html_file;if (!ns_util::FileUtil::ReadFile(html_file_path, &html_file)){lg(_Error,"%s","ReadFile err!");continue;}DocInfo doc_info;// 第二步 解析html文件,提取titleif (!ParseTitle(html_file, &doc_info._title)){lg(_Error,"%s%s","ParseTitle err! ",html_file_path.c_str());continue;}// 第三步 解析html文件,提取content(去標(biāo)簽)if (!ParseContent(html_file, &doc_info._content)){lg(_Error,"%s","ParseContent err!");continue;}// 第四步 解析html文件,構(gòu)建urlif (!ParseUrl(html_file_path, &doc_info._url)){lg(_Error,"%s","ParseUrl err!");continue;}// 解析html文件完畢,結(jié)果都保存到了doc_info中// ShowDcoinfo(doc_info);html_documents->push_back(std::move(doc_info)); // 尾插會拷貝,效率不高,使用move}lg(_Info,"%s","ParseHtml success!");return true;
}

1.ReadFile

    class FileUtil{public:static bool ReadFile(const std::string &file_path, std::string *out){std::ifstream in(file_path, std::ios::in); // 以輸入方式打開文件if (!in.is_open()){lg(_Fatal,"%s%s%s","ReadFile:",file_path.c_str()," open err!");return false;}std::string line;while (std::getline(in, line)){*out += line;}in.close();return true;}};

2.ParseTitle

static bool ParseTitle(const std::string &html_file, std::string *title)
{size_t left = html_file.find("<title>");if (left == std::string::npos)return false;size_t right = html_file.find("</title>");if (right == std::string::npos)return false;int begin = left + std::string("<title>").size();int end = right;// 截取[begin,end-1]內(nèi)的子串就是標(biāo)題內(nèi)容if (end-begin<0){lg(_Error,"%s%s%s","ParseTitle:",output_file.c_str(),"has no title");return false;}std::string str = html_file.substr(begin, end - begin);*title = str;return true;
}

3.ParseContent

static bool ParseContent(const std::string &html_file, std::string *content)
{// 利用簡單狀態(tài)機完成去標(biāo)簽工作enum Status{Lable,Content};Status status = Lable;for (char ch : html_file){switch (status){case Lable:if (ch == '>')status = Content;break;case Content:if (ch == '<')status = Lable;else{// 不保留html文本中自帶的\n,防止后續(xù)發(fā)生沖突if (ch == '\n')ch = ' ';content->push_back(ch);}break;default:break;}}return true;
}

4.ParseUrl

static bool ParseUrl(const std::string &html_file_path, std::string *url)
{std::string url_head = "https://www.boost.org/doc/libs/1_84_0/doc/html";std::string url_tail = html_file_path.substr(src_path.size());*url = url_head + "/" + url_tail;return true;
}

SaveHtml

doc_info內(nèi)部用\3分隔,doc_info之間用\n分隔

//doc_info內(nèi)部用\3分隔,doc_info之間用\n分隔
bool SaveHtml(const std::vector<DocInfo> &html_documents, const std::string &output_file)
{const char sep = '\3';std::ofstream out(output_file, std::ios::out | std::ios::binary|std::ios::trunc);if (!out.is_open()){lg(_Fatal,"%s%s%s","SaveHtml:",output_file.c_str()," open err!");return false;}for(auto &doc_info:html_documents){std::string outstr;outstr += doc_info._title;outstr += sep;outstr += doc_info._content;outstr += sep;outstr+= doc_info._url;outstr+='\n';out.write(outstr.c_str(),outstr.size());}out.close();lg(_Info,"%s","SaveHtml success!");return true;
}

二 Index建立索引模塊

索引的相關(guān)結(jié)構(gòu)

 class DocInfo // 解析后的html文檔的相關(guān)信息{public:std::string _title;std::string _content;std::string _url;uint64_t _doc_id;};class InvertedElem{public:uint64_t _doc_id;std::string _word;int _weight; // 關(guān)鍵詞word在該文檔內(nèi)的權(quán)重,方便后續(xù)查找時按順序顯示};

  1. 私有化構(gòu)造函數(shù)和析構(gòu)函數(shù):通過將構(gòu)造函數(shù)和析構(gòu)函數(shù)設(shè)為私有,禁止了外部通過常規(guī)方式創(chuàng)建Index類的實例。

  2. 禁用拷貝構(gòu)造函數(shù)和拷貝賦值操作符:通過將拷貝構(gòu)造函數(shù)和賦值操作符標(biāo)記為delete,防止了類的拷貝,確保了單例的唯一性。

  3. 靜態(tài)實例和互斥鎖:用靜態(tài)成員變量instance來存儲這個類的唯一實例,并使用靜態(tài)互斥鎖_mutex來保證在多線程環(huán)境下的線程安全。

  4. GetInstance方法:這是一個靜態(tài)方法,用于獲取Index類的唯一實例。如果instance為空,則實例化一個新的Index對象。這個方法在創(chuàng)建實例之前和之后都有一次判斷實例是否為空的邏輯,這是“雙重檢查鎖定”模式,它可以減少每次調(diào)用GetInstance方法時所需的鎖定操作,從而提高性能。

  5. 正向索引和倒排索引的存儲結(jié)構(gòu):類中定義了兩個私有成員變量來存儲正向索引_forward_index和倒排索引_inverted_index。正向索引是一個vector,存儲文檔信息DocInfo對象,而倒排索引是一個unordered_map,它映射一個字符串(關(guān)鍵詞)到一個InvertedListvector<InvertedElem>)。

  6. 構(gòu)建索引的方法:類提供了兩個方法BuildForwardIndexBuildInvertedIndex,分別用于構(gòu)建正向索引和倒排索引。這兩個方法的具體實現(xiàn)在這個代碼片段中沒有給出。

  7. 檢索功能的方法BuildIndex方法可能用于建立索引,GetForwardIndexGetInvertedList方法分別用于獲取正向索引和倒排索引中的數(shù)據(jù)。

BuildIndex

     bool BuildIndex(const std::string &input_path) // 構(gòu)建索引{std::fstream in(input_path, std::ios::in | std::ios::binary);if (!in.is_open()){lg(_Fatal,"%s%s%s","BuildIndex fail! ",input_path.c_str()," cannot open");return false;}std::string html_line; // 每個html的的DocInfo以\n間隔int cnt=1; //debugwhile (std::getline(in, html_line)){DocInfo *doc_info = BuildForwardIndex(html_line);if (doc_info == nullptr){lg(_Error,"%s%s%s%s","BuildForwardIndex fail! ","who? ",html_line.c_str(),"  continue next html");continue;}if (!BuildInvertedIndex(*doc_info)){lg(_Error,"%s%s%d","BuildInvertedIndex fail! ","id: ",doc_info->_doc_id);continue;}++cnt;if(cnt%100 == 0)std::cout<<"cnt:"<<cnt<<std::endl; }lg(_Info,"%s%d","BuildIndex over cnt:",cnt);in.close();return true;}

字符串切分

 class StringUtil{public:static void SplitString(const std::string &str, std::vector<std::string> *ret_strs, const std::string &sep){boost::split(*ret_strs, str, boost::is_any_of(sep), boost::token_compress_on);}};const char *const DICT_PATH = "./dict/jieba.dict.utf8";const char *const HMM_PATH = "./dict/hmm_model.utf8";const char *const USER_DICT_PATH = "./dict/user.dict.utf8";const char *const IDF_PATH = "./dict/idf.utf8";const char *const STOP_WORD_PATH = "./dict/stop_words.utf8";class JiebaUtil{public:static void CutString(const std::string &src,std::vector<std::string> *ret){_jieba.CutForSearch(src,*ret);}private:static cppjieba::Jieba _jieba;};cppjieba::Jieba JiebaUtil::_jieba(DICT_PATH,HMM_PATH,USER_DICT_PATH,IDF_PATH,STOP_WORD_PATH);

這段代碼展示了兩個C++工具類StringUtilJiebaUtil,它們都包含靜態(tài)方法,用于處理字符串分割和中文分詞功能。

  1. StringUtil

    • 這個類提供了一個靜態(tài)方法SplitString,它使用Boost庫的split函數(shù)來將字符串str依據(jù)分隔符sep分割,并將結(jié)果存儲在傳入的向量ret_strs中。
    • boost::token_compress_on參數(shù)指定如果分隔符在字符串中連續(xù)出現(xiàn),那么多個分隔符將被視作一個。
  2. JiebaUtil

    • 這個類提供了一個靜態(tài)方法CutString,它用于中文的分詞。方法接受一個源字符串src和一個用于存儲分詞結(jié)果的向量ret。
    • 類包含一個私有靜態(tài)成員_jieba,它是cppjieba::Jieba類的一個實例。cppjieba::Jieba是一個中文分詞庫的C++實現(xiàn)。
    • 類在底部使用_jieba成員的靜態(tài)初始化語法來初始化這個Jieba分詞器實例。

常量路徑定義: 代碼中還定義了一些指向分詞所需字典文件的路徑常量:

  • DICT_PATH:指向基礎(chǔ)字典文件。
  • HMM_PATH:指向用于HMM(隱馬爾可夫模型)的模型文件。
  • USER_DICT_PATH:指向用戶自定義的詞典文件。
  • IDF_PATH:指向逆文檔頻率(IDF)字典文件。
  • STOP_WORD_PATH:指向停用詞字典文件。

BuildForwardIndex

  DocInfo *BuildForwardIndex(const std::string &html_line){// 1~ 切分字符串std::vector<std::string> ret_strs;const std::string sep = "\3";ns_util::StringUtil::SplitString(html_line, &ret_strs, sep);if (ret_strs.size() < 3)return nullptr;// 2~ 填充doc_infoDocInfo doc_info;doc_info._title = ret_strs[0];doc_info._content = ret_strs[1];doc_info._url = ret_strs[2];doc_info._doc_id = _forward_index.size(); // 插入第一個時id== size ==0// 3~ 插入到正排索引_forward_index_forward_index.push_back(std::move(doc_info));return &_forward_index.back();}

BuildInvertedIndex

 bool BuildInvertedIndex(const DocInfo &doc_info){struct words_cnt{int title_cnt = 0;int content_title = 0;};// 1~ 對doc_info的title和content進行分詞std::unordered_map<std::string, words_cnt> words_frequency;std::vector<std::string> words_title;//保存title分詞后的結(jié)果std::vector<std::string> words_content;//保存content分詞后的結(jié)果ns_util::JiebaUtil::CutString(doc_info._title, &words_title);ns_util::JiebaUtil::CutString(doc_info._content, &words_content);// 2~ 統(tǒng)計詞頻填充words_frequencyfor (auto &word : words_title)//to_lower轉(zhuǎn)換不能是const修飾{boost::to_lower(word); // 需要統(tǒng)一轉(zhuǎn)化成為小寫,因為搜索時不區(qū)分大小寫//boost::to_lower_copy(word);words_frequency[word].title_cnt++;}for (auto &word : words_content){boost::to_lower(word); // 需要統(tǒng)一轉(zhuǎn)化成為小寫,因為搜索時不區(qū)分大小寫//boost::to_lower_copy(word);words_frequency[word].content_title++;}// 3~ 自定義權(quán)重 title:content = 10:1static const int title_weight = 10;static const int content_weight = 1;// 4~ 對words_frequency內(nèi)的每個關(guān)鍵詞創(chuàng)建InvertedElem并填充for (const auto &kv : words_frequency){InvertedElem inverted_ele;inverted_ele._doc_id = doc_info._doc_id;inverted_ele._word = kv.first;inverted_ele._weight =title_weight * kv.second.title_cnt +content_weight * kv.second.content_title;// 5~ 將該文檔的所有InvertedElem分別插入到倒排索引 _inverted_index中InvertedList &inverted_list = _inverted_index[kv.first];inverted_list.push_back(std::move(inverted_ele));//_inverted_index[kv.first].push_back(std::move(inverted_ele));}return true;}

三 Searcher搜索模塊

InitSearcher

Search

  1. 分詞處理: 用戶輸入的查詢字符串 query 通過 ns_util::JiebaUtil::CutString 函數(shù)進行分詞,分詞結(jié)果存儲在 key_words 向量中。

  2. 搜索和去重: 遍歷分詞后的關(guān)鍵詞。對每個關(guān)鍵詞,都先將其轉(zhuǎn)換為小寫以實現(xiàn)大小寫不敏感的搜索,然后獲取對應(yīng)的倒排索引鏈(InvertedList)。如果倒排索引鏈存在,遍歷鏈中的每個元素,并在 tokens_map 中以文檔ID為鍵聚合數(shù)據(jù),合并權(quán)重和關(guān)鍵詞,實現(xiàn)對同一文檔的去重。

  3. 排序: 將 tokens_map 中聚合的結(jié)果轉(zhuǎn)移到一個向量 inverted_ele_all 中,并根據(jù)權(quán)重對其進行降序排序,這樣權(quán)重高的(更相關(guān)的)文檔會排在前面。

  4. 構(gòu)建JSON結(jié)果: 遍歷排序后的 inverted_ele_all 向量,對于每個元素,使用它的文檔ID去查詢正向索引獲取文檔的詳細信息,如標(biāo)題、內(nèi)容和URL。將這些信息構(gòu)建成一個JSON對象,并添加到一個 Json::Value 類型的 ret 數(shù)組中。函數(shù)最后使用 Json::FastWriterret 轉(zhuǎn)換成JSON格式的字符串并存儲在 json_str 指針指向的字符串中。

        // query是用戶輸入的搜索關(guān)鍵字// json_str是返回給用戶瀏覽器的搜索結(jié)果void Search(const std::string &query, std::string *json_str){// 1~對query進行分詞std::vector<std::string> key_words;ns_util::JiebaUtil::CutString(query, &key_words);std::unordered_map<uint64_t,InvertedElemDedup> tokens_map;//去重id后的結(jié)果for (auto &key_word : key_words){// 查詢的關(guān)鍵詞全部轉(zhuǎn)換為小寫,提取出來的信息不區(qū)分大小寫boost::to_lower(key_word);// 2~對分詞結(jié)果 分別進行搜索ns_index::Index::InvertedList *inverted_list =_index->GetInvertedList(key_word);if (inverted_list == nullptr){continue; // 這個詞沒能找到 對應(yīng)的倒排拉鏈}for(auto &elem: *inverted_list){auto& dedup_ele = tokens_map[elem._doc_id];dedup_ele._doc_id = elem._doc_id;dedup_ele._weight += elem._weight;dedup_ele._words.push_back(elem._word);}}// 優(yōu)化點:對所有的ele合并后指向的doc_id進行去重 這里只關(guān)心weight和idstd::vector<InvertedElemDedup> inverted_ele_all;for(auto &kv:tokens_map){inverted_ele_all.push_back(std::move(kv.second));}// 3~對所有的inverted_element按照wegiht排序sort(inverted_ele_all.begin(), inverted_ele_all.end(),[](InvertedElemDedup& left,InvertedElemDedup& right){return left._weight > right._weight;});// 4~序列化,構(gòu)建json串返回給用戶 -- 使用jsoncppJson::Value ret;int cnt = 0; // debugfor (auto &ele : inverted_ele_all){ns_index::DocInfo *doc_info = _index->GetForwardIndex(ele._doc_id);if (doc_info == nullptr)continue;Json::Value element;element["title"] = doc_info->_title;// 搜索時需要摘要,不是所有的content,后面優(yōu)化element["desc"] = GetDesc(doc_info->_content, ele._words[0]);element["url"] = doc_info->_url;// element["weight"] = ele._weight;// element["word"] = ele._words[0];// element["id"] = (int)ele._doc_id; // json自動將int轉(zhuǎn)化為stringret.append(element);}//Json::StyledWriter writer;Json::FastWriter writer;*json_str = writer.write(ret);}private:std::string GetDesc(const std::string &html_content, const std::string &word){// 找到word在content中首次出現(xiàn)的位置,向前截取prev_stepbyte,向后截取next_stepbyte// 向前<prev_step則從content開頭開始,向后不足next_step則到content結(jié)尾// 1~ 找到word首次出現(xiàn)的位置std::cout << word << std::endl; // debugauto iter = std::search(html_content.begin(), html_content.end(), word.begin(), word.end(),[](int l, int r){return std::tolower(l) == std::tolower(r);});if (iter == html_content.end()){lg(_Error,"%s","content里面沒找到word");return "None1";}// 找到了int pos = std::distance(iter, html_content.end());const int prev_step = 50;const int next_step = 50;// 2~ 確定begin和end位置int begin = pos >= prev_step ? pos - prev_step : 0;int end = (pos + next_step) < html_content.size() ? pos + next_step : html_content.size();// 3~ 截取描述子串[begin,end)并返回if (begin >= end) // end一定大于begin{lg(_Error,"%s","begin > end 越界了");return "None2";}std::string desc = html_content.substr(begin, end - begin);desc += "...";return desc;}};

四 http_server模塊

const std::string input = "data/output/dest.txt";//從input里讀取數(shù)據(jù)構(gòu)建索引
const std::string root_path = "./wwwroot";
int main()
{std::unique_ptr<ns_searcher::Searcher> searcher(new ns_searcher::Searcher());searcher->SearcherInit(input);httplib::Server svr;svr.set_base_dir(root_path.c_str()); // 設(shè)置根目錄// 重定向到首頁svr.Get("/", [](const httplib::Request &, httplib::Response &rsp){ rsp.set_redirect("/home/LZF/boost_searcher_project/wwwroot/index.html"); });svr.Get("/s",[&searcher](const httplib::Request &req,httplib::Response &rsp){if(!req.has_param("word")){rsp.set_content("無搜索關(guān)鍵字!","test/plain,charset=utf-8");return;}std::string json_str;std::string query = req.get_param_value("word");std::cout<<"用戶正在搜索: "<<query<<std::endl;searcher->Search(query,&json_str);rsp.set_content(json_str,"application/json");});svr.listen("0.0.0.0", 8800);
}
  1. 初始化: 定義了 inputroot_path 兩個字符串常量,分別表示索引文件的路徑和服務(wù)器的根目錄。

  2. 創(chuàng)建搜索對象: 使用 std::unique_ptr 創(chuàng)建了 Searcher 類的一個實例,并通過 SearcherInit 方法初始化,以從指定的 input 文件中構(gòu)建索引。

  3. 創(chuàng)建和配置服務(wù)器: 使用 httplib::Server 類創(chuàng)建了一個HTTP服務(wù)器實例,設(shè)置了服務(wù)器的根目錄為 root_path

  4. 首頁重定向: 服務(wù)器對根路徑 / 的GET請求進行處理,通過 set_redirect 方法將請求重定向到指定的HTML頁面路徑。

  5. 搜索請求處理: 對路徑 /s 的GET請求進行處理,這是搜索功能的實現(xiàn)部分。服務(wù)器檢查請求中是否包含名為 word 的參數(shù):

    • 如果請求中沒有 word 參數(shù),則返回錯誤信息。
    • 如果有,它將提取 word 參數(shù)的值,打印出查詢的內(nèi)容,并調(diào)用 Searcher 實例的 Search 方法來進行搜索。搜索的結(jié)果是一個JSON字符串,它會設(shè)置為響應(yīng)體的內(nèi)容。
  6. 啟動服務(wù)器: 使用 svr.listen 方法監(jiān)聽 0.0.0.0 上的 8800 端口,使服務(wù)器開始接受連接和處理請求。

httplib::Serverhttplib 庫中用于創(chuàng)建和管理HTTP服務(wù)器的類。

五 前端模塊

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><script src="http://code.jquery.com/jquery-2.1.1.min.js"></script><title>boost 搜索引擎</title><style>/* 去掉網(wǎng)頁中的所有的默認內(nèi)外邊距,html的盒子模型 */* {/* 設(shè)置外邊距 */margin: 0;/* 設(shè)置內(nèi)邊距 */padding: 0;}/* 將我們的body內(nèi)的內(nèi)容100%和html的呈現(xiàn)吻合 */html,body {height: 100%;}/* 類選擇器.container */.container {/* 設(shè)置div的寬度 */width: 800px;/* 通過設(shè)置外邊距達到居中對齊的目的 */margin: 0px auto;/* 設(shè)置外邊距的上邊距,保持元素和網(wǎng)頁的上部距離 */margin-top: 15px;}/* 復(fù)合選擇器,選中container 下的 search */.container .search {/* 寬度與父標(biāo)簽保持一致 */width: 100%;/* 高度設(shè)置為52px */height: 52px;}/* 先選中input標(biāo)簽, 直接設(shè)置標(biāo)簽的屬性,先要選中, input:標(biāo)簽選擇器*//* input在進行高度設(shè)置的時候,沒有考慮邊框的問題 */.container .search input {/* 設(shè)置left浮動 */float: left;width: 600px;height: 50px;/* 設(shè)置邊框?qū)傩?#xff1a;邊框的寬度,樣式,顏色 */border: 1px solid black;/* 去掉input輸入框的有邊框 */border-right: none;/* 設(shè)置內(nèi)邊距,默認文字不要和左側(cè)邊框緊挨著 */padding-left: 10px;/* 設(shè)置input內(nèi)部的字體的顏色和樣式 */color: #CCC;font-size: 14px;}/* 先選中button標(biāo)簽, 直接設(shè)置標(biāo)簽的屬性,先要選中, button:標(biāo)簽選擇器*/.container .search button {/* 設(shè)置left浮動 */float: left;width: 150px;height: 52px;/* 設(shè)置button的背景顏色,#4e6ef2 */background-color: #4e6ef2;/* 設(shè)置button中的字體顏色 */color: #FFF;/* 設(shè)置字體的大小 */font-size: 19px;font-family:Georgia, 'Times New Roman', Times, serif;}.container .result {width: 100%;}.container .result .item {margin-top: 15px;}.container .result .item a {/* 設(shè)置為塊級元素,單獨站一行 */display: block;/* a標(biāo)簽的下劃線去掉 */text-decoration: none;/* 設(shè)置a標(biāo)簽中的文字的字體大小 */font-size: 20px;/* 設(shè)置字體的顏色 */color: #4e6ef2;}.container .result .item a:hover {text-decoration: underline;}.container .result .item p {margin-top: 5px;font-size: 16px;font-family:'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif;}.container .result .item i{/* 設(shè)置為塊級元素,單獨站一行 */display: block;/* 取消斜體風(fēng)格 */font-style: normal;color: green;}</style>
</head>
<body><div class="container"><div class="search"><input type="text" value="請輸入搜索關(guān)鍵字"><button onclick="Search()">搜索一下</button></div><div class="result"></div></div><script>function Search(){let query = $(".container .search input").val();console.log("query = " + query);$.get("/s", {word: query}, function(data){console.log(data);BuildHtml(data);});}function BuildHtml(data){let result_lable = $(".container .result");result_lable.empty();for( let elem of data){let a_lable = $("<a>", {text: elem.title,href: elem.url,target: "_blank"});let p_lable = $("<p>", {text: elem.desc});let i_lable = $("<i>", {text: elem.url});let div_lable = $("<div>", {class: "item"});a_lable.appendTo(div_lable);p_lable.appendTo(div_lable);i_lable.appendTo(div_lable);div_lable.appendTo(result_lable);}}</script></body>
</html>

HTML結(jié)構(gòu)

  1. 搜索欄 (div.search):

    • 包含一個文本輸入框,用戶可以在其中輸入搜索關(guān)鍵字。
    • 包含一個按鈕,當(dāng)點擊時會調(diào)用 Search() JavaScript函數(shù)。
  2. 搜索結(jié)果顯示區(qū)域 (div.result):

    • 這是一個空的div,將來用來動態(tài)顯示搜索結(jié)果。

樣式

  • 通過CSS設(shè)置了頁面和元素的樣式,包括輸入框、按鈕、搜索結(jié)果等。

JavaScript功能

  1. Search() 函數(shù):

    • 從輸入框中獲取用戶輸入的查詢詞。
    • 使用 jQuery$.get() 函數(shù)異步向服務(wù)器的 /s 路徑發(fā)送一個GET請求,并將用戶的查詢詞作為參數(shù)傳遞。
    • 當(dāng)收到響應(yīng)時,調(diào)用 BuildHtml() 函數(shù)處理數(shù)據(jù)并構(gòu)建結(jié)果HTML。
  2. BuildHtml() 函數(shù):

    • 清空結(jié)果顯示區(qū)域,為新的搜索結(jié)果做準(zhǔn)備。
    • 遍歷響應(yīng)數(shù)據(jù)中的每個搜索結(jié)果,并為每個結(jié)果創(chuàng)建包含標(biāo)題、描述和URL的HTML元素。
    • 將創(chuàng)建的HTML元素附加到結(jié)果顯示區(qū)域。

用戶交互

  • 當(dāng)用戶輸入查詢詞并點擊搜索按鈕時,頁面將不會進行重新加載,而是通過JavaScript異步請求后端服務(wù),并將結(jié)果動態(tài)地插入到頁面中。

jQuery

  • 頁面通過CDN引用了 jQuery 庫,以簡化DOM操作和Ajax請求。
http://www.risenshineclean.com/news/36115.html

相關(guān)文章:

  • 陽信做網(wǎng)站營銷型網(wǎng)站建設(shè)費用
  • 昆明做網(wǎng)站的個人淘寶seo搜索引擎原理
  • 南陽做網(wǎng)站百度搜索引擎排名規(guī)則
  • 公司網(wǎng)站開發(fā)交接注意事項seo研究中心怎么了
  • 做網(wǎng)站網(wǎng)絡(luò)seo優(yōu)化教程自學(xué)
  • wordpress 獲取根目錄上海seo網(wǎng)站推廣公司
  • 靜態(tài)網(wǎng)站開發(fā)預(yù)期效果關(guān)鍵詞生成器 在線
  • 南京做代賬會計在哪個網(wǎng)站上找百度快照在哪里找
  • 深圳品牌做網(wǎng)站公司今日國內(nèi)新聞10則
  • 做爰網(wǎng)站貼吧推銷產(chǎn)品的軟文500字
  • 平面設(shè)計在線課程文明seo技術(shù)教程網(wǎng)
  • 上海專建貿(mào)易有限公司廊坊百度關(guān)鍵詞優(yōu)化
  • 注冊微信號的網(wǎng)站網(wǎng)站設(shè)計模板網(wǎng)站
  • 切實加強政府網(wǎng)站建設(shè)與管理百度競價排名事件分析
  • 深圳網(wǎng)站品牌建設(shè)seo關(guān)鍵詞排名優(yōu)化
  • 大連網(wǎng)站建設(shè)設(shè)計下載百度到桌面上
  • 深圳網(wǎng)站做的好的公司名稱長春網(wǎng)站建設(shè)技術(shù)托管
  • 網(wǎng)站怎么做要多少錢寧德市教育局官網(wǎng)
  • 武漢網(wǎng)站優(yōu)化百度人工服務(wù)24小時熱線電話
  • 90設(shè)計網(wǎng)站怎么樣已備案域名購買平臺
  • 阿里云建站是外包的嗎seo的基礎(chǔ)優(yōu)化
  • 怎么查看網(wǎng)站提交百度的度手機優(yōu)化助手下載
  • 建設(shè)哪里有百度seo按天計費
  • 廈門快速建網(wǎng)站騰訊控股第三季度營收1401億
  • 別人做的網(wǎng)站上海做關(guān)鍵詞推廣企業(yè)
  • 怎么做淘寶客網(wǎng)站賺錢百度指數(shù)官方
  • 網(wǎng)站黨組織規(guī)范化建設(shè)開展情況石家莊seo推廣優(yōu)化
  • 網(wǎng)站域名實名制市場調(diào)研報告怎么寫
  • 網(wǎng)站中英文互譯 java怎么做html網(wǎng)頁制作模板代碼
  • 做海外房產(chǎn)最好的網(wǎng)站關(guān)鍵詞搜索量排名