1. 程式人生 > >快速用JavaScript實現劃詞取詞,可複製百度文庫文字(獲取滑鼠選中區域文字)

快速用JavaScript實現劃詞取詞,可複製百度文庫文字(獲取滑鼠選中區域文字)

完整程式碼可在最後程式碼塊檢視呦!!!
※本貼程式碼,可用用於油猴指令碼,支援瀏覽器F12Console控制檯直接執行
有一段時間呢在百度文庫查詢資料時被限制了複製,說什麼複製次數已達上限,那個
難受鴨!!於是我打開了傳說中的F12,意外的發現了一個功能
在這裡插入圖片描述
就是很意外的發現我所選中的文字會在我的Console檢視中顯示於是我去看了一下他是那個JS段中打印出來的
在這裡插入圖片描述
97行Emmmm,好像和百度文庫沒有什麼關係,地址好像是我瀏覽器的外掛,然後我將這個外掛裝入了其他瀏覽器,發現會報錯,應該是相容問題,之前也想過獲取滑鼠選中的文字,一直也沒有找到程式碼意思明確的文章,於是趁此時機
在這裡插入圖片描述
首先分析一下劃詞取詞的過程

  1. 使用者左擊滑鼠             → 滑鼠按下事件onmousedown
  2. 滑鼠滑過文字             → 文字本身樣式改變
  3. 轉中後擡起滑鼠左鍵  → 滑鼠擡起事件onmouseup,同時返回那些文字有變化

那麼首先進行簡單的程式碼主體:

 document.onmousedown
= function(event) {//監聽當前頁面滑鼠按下事件 var event = event || window.event;//此處考慮相容問題 if (event.button == "0" || event.button == "1") {//判斷按下的按鍵(0) document.onmouseup = function(event) {//監聽頁面中滑鼠擡起事件 var txt = ""; if(window.getSelection){//相容性判斷,各瀏覽器獲取有變化處的文字函式不同 txt = window.getSelection
();//谷歌等核心瀏覽器獲取方式 }else{ txt = document.selection.createRange().text;//IE普通核心 } console.log(txt);//控制檯列印瀏覽 } } }

可以在頁面中新增P標籤隨便寫一些文字,或者放入任意網頁console控制檯均可,然後滑鼠隨便選中文字,觀察控制檯會出現如下內容

在這裡插入圖片描述

恭喜你成功第一步了,那出現了這個當初說好的文字呢???OK其實這個就是文字只是它以一種不同的方式展現了出來,那我們如何得到呢

		txt = txt+"";

將變數txt經過這步處理會變為字串的形式了,這個時候就可以在控制檯看到你所選中的文字了,你以為這就完了???不完善一下舒服嘛???衝鴨!!!
繼續分析,如果使用者點一個按鈕,或者選中的是空格怎麼辦

 	txt = txt.replace(/^\s+|\s+$/g, "");
    if (txt != "") {
        console.log(txt);
    }

OK,首先一個正則判斷,將兩端空格去除(帶著前面一堆空格獲取到的字串很帶勁,試試?滑稽.jpg),之後判斷如果為空就不獲取,普繞飛科特

劃詞部分到此結束
接下來需要在選中文字後追加一個div方便使用者複製百度文庫文字,那麼我們可以將其封成一個方法,只要將上面那一步獲取到的字串傳入即可

function creatDiv(str) {
    var arr = mousePosition();//這是個獲取滑鼠當前位置的一個方法
    var newDiv = document.createElement('div'); //建立一個div元素;
    var newContent = document.createTextNode(str);//建立文字內容
    newDiv.appendChild(newContent);//將內容放入新建立的div
    newDiv.id = "bblock";//新增一個ID方便之後的操作
    //可以用下操作設定自己想要的CSS屬性
    newDiv.style.width = "200px";//設定div寬(視自己需求而定)
    newDiv.style.background = "red";//設定背景顏色
    newDiv.style.zIndex = "1000";//設定層級保證在最上方
    newDiv.style.position = "absolute";//給div新增絕對定位*必有
    //此處要加px否則不生效,+20原因  根據自己需要調整
    newDiv.style.left = arr[0] + 20 + "px";//距左側距離
    newDiv.style.top = arr[1] + 0 + "px";//具右側距離
    var bo = document.body; //獲取body物件.
    bo.insertBefore(newDiv, bo.lastChild); //動態插入到body中
}
function mousePosition(evt) { //當前滑鼠位於頁面位置
	evt = evt || window.event;//相容性判斷,滿足一個即可有值
	//相容寫法,獲取當前滑鼠橫座標
    var xPos = evt.pageX || evt.clientX || evt.offsetX || evt.x;
    //相容寫法,獲取當前滑鼠縱座標
    var yPos = evt.pageY || evt.clientY || evt.offsetY || evt.y;
    return [xPos, yPos];//返回陣列為當前滑鼠橫縱座標
}

你以為這就完了,OK 調GUG階段
分析:

  1. 使用者每次劃詞後都要生成一個新的,那麼舊的怎麼關閉?
  2. 如果使用者在生成的div中進行劃詞操作,是否也要生成新的div?
  3. 如果才能判斷什麼情況下要進行銷燬舊的div呢?

解決:

  1. 最好的關閉體驗為:單擊其他不是新追加的div區域進行關閉
  2. 否,新div的目的就是讓使用者可以在這裡進行選中複製的,要加判斷
  3. 根據第一條,得到銷燬條件

由此可以得到我們還需要兩個判斷(判斷div關閉,判斷div中劃詞),和一個方法(滑鼠是否離開div)

設定兩個全域性變數

var workType = false; //使用者當前是否進行了劃詞
var workTool = false; //使用者劃詞後是否正在取詞

根據之前給的ID監聽滑鼠是否離開視窗,如果在則設定workTool為ture

function bingDiv() {
    document.getElementById("bblock").onmouseover = function() {
        workTool = true;
    }//滑鼠移入事件
    document.getElementById("bblock").onmouseout = function() {
        workTool = false;
    }//滑鼠移除事件
}

在劃詞開始新增判斷

 if (workTool) { //如果使用者在取詞則不進行二次劃詞操作
	return 0;
 }
 //如果div存在且不是在取詞操作 根據ID銷燬該div
 if (document.getElementById("bblock") && !workTool) {
     document.body.removeChild(document.getElementById("bblock"));
 }
 //如果在不是取詞操作程式碼會執行到這裡,那麼將劃詞工作狀態設為true
 workType = true;

新增判斷只有在劃詞操作下,滑鼠擡起才會進行獲取文字,追加div的操作,而此時滑鼠擡起後,劃詞工作狀態結束

 document.onmouseup = function(event) {
     if (workType) {//是劃詞狀態才進行如下操作
         workType = false;//劃詞狀態結束
         var txt = "";
	     if(window.getSelection){
	        txt = window.getSelection();
	     }else{
	        txt = document.selection.createRange().text;
	     }
        txt = txt + "";
        txt = txt.replace(/^\s+|\s+$/g, "");
        if (txt != "") {
            creatDiv(txt);//傳入生成div的函式
        }
    }
}

這裡有一個坑,為什麼要把判斷滑鼠是否在新追加的div中封成一個方法呢?
這個大多數新手會遇到的問題,因為網頁是動態渲染的,如果你直接寫到劃詞的方法中進行判斷,js是獲取不到這個節點的,所以需要在每次建立節點後再去判斷,防止獲取不到

 function creatDiv(str) {
    var arr = mousePosition();
   		   	  ·
  			  ·
  			  ·
     bo.insertBefore(newDiv, bo.lastChild); //動態插入到body中
     bingDiv();//追加完畢後進行判斷
 }

到這裡效果就完全實現了

以下為全部完整程式碼(可直接開啟需要的百度文庫,貼上到console控制檯即可使用):

let workType = false; //當前劃詞狀態
let workTool = false; //當前取詞狀態
document.onmousedown = function(event) {             
  var event = event || window.event;
  if ((event.button == "0" || event.button == "1") && !workTool) {
    if (workTool) { //如果使用者在取詞則不進行二次劃詞操作
        return 0;
    }
    if (document.getElementById("bblock") && !workTool) {
        document.body.removeChild(document.getElementById("bblock"));
    }
    workType = true;
    document.onmouseup = function(event) {
      if (workType) {
        workType = false;
        var txt = window.getSelection ? window.getSelection() : document.selection.createRange().text;
        txt = txt + "";
        txt = txt.replace(/^\s+|\s+$/g, "");
        if (txt != "") {
           creatDiv(txt);
        }
      }
    }
  }
}

function mousePosition(evt) { //當前滑鼠位於頁面位置
    evt = evt || window.event;
    var xPos = evt.pageX || evt.clientX || evt.offsetX || evt.x;
    var yPos = evt.pageY || evt.clientY || evt.offsetY || evt.y;
    return [xPos, yPos];
}

function creatDiv(str) {
    var arr = mousePosition();
    var newDiv = document.createElement('div'); //建立一個div元素;
    var newContent = document.createTextNode(str);
    newDiv.appendChild(newContent);
    newDiv.id = "bblock";
    newDiv.style.width = "200px";
    newDiv.style.background = "red";
    newDiv.style.position = "absolute";
    newDiv.style.left = arr[0] + 20 + "px";
    newDiv.style.top = arr[1]+ 0  + "px";
    newDiv.style.zIndex = "1000";
    var bo = document.body; //獲取body物件
    bo.insertBefore(newDiv, bo.lastChild); //動態插入到body中
    bingDiv();
}

function bingDiv() {
    document.getElementById("bblock").onmouseover = function() {
        workTool = true;
    }
    document.getElementById("bblock").onmouseout = function() {
        workTool = false;
    }
}

效果:
在這裡插入圖片描述

取詞區域的樣式可以根據自己需求更改,我就懶一下啦~~~