整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          JS|鼠標事件交替顯示不同的圖片

          想在同一位置顯示交替顯示圖片時,可以利用鼠標單擊事件,也可以利用鼠標移動事件來改變圖片的src。

          1 鼠標單擊事件

          <script type="text/javascript">
          function ClickImg(indexedNum, name)  {
            // indexedNum可以是圖片在網頁中的序號,也可以是圖片的name屬性。
              var n1 = name + ".jpg"
              var n2 = name + "_2.jpg"
              if (document.images[indexedNum].src.search(n1) != -1) {
                  document.images[indexedNum].src = n2
              }
              else {
                  if (document.images[indexedNum].src.search(n2) != -1) {
                      document.images[indexedNum].src = n1
                  }
              }
          } // 貌似不支持 document.getElementById(id)方法
          
          </script>
          

          2 鼠標移動事件

          <SCRIPT language="JavaScript">
          function movepic(img_name,img_src) {
              document[img_name].src=img_src;
          }
          </SCRIPT>
          <A HREF="http://www.javascript.com" 
              onmouseover="movepic('button','tu01.jpg')" 
              onmouseout="movepic('button','tu02.jpg')">
          <IMG NAME="button" SRC="tu03.jpg" ALT="Image"></A>

          3 單擊超鏈接在同一區域加載不同圖片和文本

          load()
          function load ( )
           {
            xImage=new Array (2)
            xImage[0] = "pic01.gif"
            xImage[1] = "pic02.gif"
            xImage[2] = "pic03.gif"
            xText=new Array (2) 
            xText[0] = "text 1"
            xText[1] = "text 2"
            xText[2] = "text 3"
            
           }
          function loadimage (x)
           {
              obr.src=xImage[x];
          	popis.innerText=xText[x]
           }

          html:

          <a href="javascript: loadimage('0')">pic1</a>
          <a href="javascript: loadimage('1')">pic2</a>
          <a href="javascript: loadimage('2')">pic3</a>
          <img src="pic01.gif"  border="0" name="obr">
          <div id="popis"></div>

          4 下拉菜單圖形預覽

          image1= new Image();
          image1.src = "pic01.gif";
          image2= new Image();
          image2.src = "pic02.gif";
          image3= new Image();
          image3.src = "pic03.gif";
          
          function imgchange(){
          	var imageNum =  document.form.selImage.selectedIndex + 1;
          	fname = eval("image" + imageNum + ".src")
          	document.img.src = fname
          }

          html:

          <form name="form">
            <select name="selImage" size=1>
              <option selected>圖形 1 
              <option>圖形 2 
              <option>圖形 3 
            </select>
            <input type="button" value="View" onClick="imgchange()" name="button">
          </form>
          <img src="pic01.gif" name="img" > </td>

          5 多張圖片通過單擊“上一張”,下一張“交替顯示

          <html>
          <head>
          <script language="JavaScript">
             num_of_slides = 5;    // 圖片數目
             slide_num = 1;        // 哪個圖片首先顯示
             // 圖片說明
             desc1 = "我喜歡的007男主角";
             desc2 = "我喜歡的007男主角";
             desc3 = "我喜歡的007男主角";
             desc4 = "我喜歡的007男主角";
             desc5 = "我喜歡的007男主角";
             
             function firstslide(){
               slide_num = 1;
               changeslide();
             }
             function prevslide(){
               slide_num = slide_num - 1;
               if(slide_num < 1){
                 slide_num = num_of_slides;
               }
               changeslide();
             }
             function nextslide(){
               slide_num = slide_num + 1;
               if(slide_num > num_of_slides){
                 slide_num = 1
               }
               changeslide();
             }
             function lastslide(){
               slide_num = 5;
               changeslide();
             }
          
             // 改變循環顯示圖片和相應的說明。
             function changeslide(){        
               // 圖片文件名pic1.jpg,pic2.jpg...
               eval('document.picbox.src = "pic' + slide_num + '.jpg"');
               eval('document.descform.descbox.value = "圖片' + slide_num + '說明: '  
          	       + eval('desc' + slide_num) + '"');
             }
          
          </script>
          <title>Image Slideshow with description</title>
          
          </head>
          <!--不要忘記body里面的onload-->
          <body onLoad="changeslide()" >
          <br>
          <div align="center"><br>
            <br>
          </div>
          <div align="center"> 
          <img src="pic1.jpg" name="picbox" width="120" height="155"> 
          
          <form name="descform">
            <p> 
          	<textarea name="descbox" rows="3" cols="25" wrap="virtual" onFocus="this.blur()">
          </textarea>
          	<br>
          	<a href="javascript:firstslide()">最前面</a> 
          	<a href="javascript:prevslide()">上一幅</a> 
          	<a href="javascript:nextslide()">下一幅</a> 
          	<a href="javascript:lastslide()">最后面</a> 
            </p>
          </form>
          </div>
          
          </body>
          </html>

          -End-

          之前閑時,花了幾個下班時間使用VUE+Spring Boot前后端分離做了一個博客,博客文章編輯采用vue-quill-editor插件,做了一些簡單的配置后,就直接可用了,可惜在編輯文章時,默認的圖片上傳為Base64存放在文章內容中,這使得原本存儲在數據庫中的5這個大字段會因一篇文章的圖片上傳多而變得沉重。因為我使得的是云服務當服務器,有用過云服務的都知道,網絡帶寬很貴。在帶寬只有3M的情況下,讀取一篇幾兆的文章會有幾秒的延遲。一開始我以為是數據庫讀取問題,所以我把文章內容這個字段做了中間緩存,把常變字段(如閱讀數)依然從數據庫中讀取,在邏輯上進行兩者拼接返回給前端,但依然速度很慢。如下圖,文章內容中的圖片是BASE64存儲,存儲大小782KB,如果一篇文章的上傳圖片越多,也就會導致這個文章內容字段越大。

          在不考慮提高帶寬成本的情況下,準備把富文本圖片默認存儲為Base64的方案改成圖片存儲服務器,用URL引用,這樣可以減少文章內容的讀寫IO。以下我將從引用富本文到圖片改造再到后端接收上傳的圖片來介紹。

          一、下載富文本依賴

          npm install vue-quill-editor --save 
          

          下載完依賴后,在package.json中,將可以找到對應的版本。

          二、在main.js中引用富文本,可以按Ctrl鍵+鼠標點擊vue-quill-editor,看下是否可以看到源碼,這樣可以再次確認是否下載成功(我用的編譯器是JetBrains WebStorm 2018.3.5 x64)

          import VueQuillEditor from 'vue-quill-editor'
          

          三、富文本的使用

          1、HTML部分代碼

          <template>
          //中間省去其他內容,只顯示富文本HTML
          <div class="edit_container">
           <quill-editor
           v-model="blogsContent"
           ref="myQuillEditor"
           :options="editorOption"
           @blur="onEditorBlur($event)" @focus="onEditorFocus($event)"
           @change="onEditorChange($event)">
           </quill-editor>
          </div>
          </template>
          

          2、JS部分代碼

          <script>
           import {quillEditor} from "vue-quill-editor"; //調用編輯器
           import quillConfig from '../../api/quill-config.js'//重寫富文本,使得圖片走自定義上傳
           import 'quill/dist/quill.core.css';
           import 'quill/dist/quill.snow.css';
           import 'quill/dist/quill.bubble.css';
          export default {
           name: 'editor',
           components: {
           quillEditor
           },
           data() {
           return {
           editorOption: quillConfig,//重寫
           }
           }
          }
          

          3、重寫自定義圖片上傳quill-config.js代碼

          以下代碼可以直接復制,然后改一下接口地址和你所要的參數即可

          /*富文本編輯圖片上傳配置*/
          const uploadConfig = {
           // 必填參數 圖片上傳地址
           action: '/api/file/up/img', // 必填參數 圖片上傳接口地址
           methods: 'POST', // 必填參數 圖片上傳方式
           token: '', // 可選參數 如果需要token驗證,假設你的token有存放在sessionStorage
           name: 'img', // 必填參數 文件的參數名
           size: 500, // 可選參數 圖片大小,單位為Kb, 1M = 1024Kb
           accept: 'image/png, image/gif, image/jpeg, image/bmp, image/x-icon' // 可選 可上傳的圖片格式
          };
          
          // toolbar工具欄的工具選項(默認展示全部)
          const toolOptions = [
           ['bold', 'italic', 'underline', 'strike'],
           ['blockquote', 'code-block'],
           [{'header': 1}, {'header': 2}],
           [{'list': 'ordered'}, {'list': 'bullet'}],
           [{'script': 'sub'}, {'script': 'super'}],
           [{'indent': '-1'}, {'indent': '+1'}],
           [{'direction': 'rtl'}],
           [{'size': ['small', false, 'large', 'huge']}],
           [{'header': [1, 2, 3, 4, 5, 6, false]}],
           [{'color': []}, {'background': []}],
           [{'font': []}],
           [{'align': []}],
           ['clean'],
           ['link', 'image', 'video']
          ];
          const handlers = {
           image: function image() {
           var self = this;
          
           var fileInput = this.container.querySelector('input.ql-image[type=file]');
           if (fileInput === null) {
           fileInput = document.createElement('input');
           fileInput.setAttribute('type', 'file');
           // 設置圖片參數名
           if (uploadConfig.name) {
           fileInput.setAttribute('name', uploadConfig.name);
           }
           // 可設置上傳圖片的格式
           fileInput.setAttribute('accept', uploadConfig.accept);
           fileInput.classList.add('ql-image');
           // 監聽選擇文件
           fileInput.addEventListener('change', function () {
           // 創建formData,append這個方法是添加參數的方法,如果你的接口需要添加其他參數,比如用戶ID,也可以在后面加進去。
           var formData = new FormData();
           formData.append(uploadConfig.name, fileInput.files[0]);
           formData.append('object','product');
           // 如果需要token且存在token
           if (uploadConfig.token) {
           formData.append('token', uploadConfig.token)
           }
           // 圖片上傳
           var xhr = new XMLHttpRequest();
           xhr.open(uploadConfig.methods, uploadConfig.action, true);
           // 上傳數據成功,會觸發
           xhr.onload = function (e) {
           if (xhr.status === 200) {
           // var res = JSON.parse(xhr.responseText);//如果你圖片上傳接口返回的是一個Json對象,就需要這個轉,然后在下面獲取圖片URL
           let length = self.quill.getSelection(true).index;
           //這里很重要,你圖片上傳成功后,img的src需要在這里添加,res.path就是你服務器返回的圖片鏈接。
           //如果只是圖片地址,在前端是顯示不了的,需要添加前綴,你可以使用接口全路徑,也可以使用我下面的VUE路由解決跨域問題
           self.quill.insertEmbed(length, 'image','/api/file/get/img?url='+xhr.responseText);
           self.quill.setSelection(length + 1)
           }
           fileInput.value = ''
           };
           // 開始上傳數據
           xhr.upload.onloadstart = function (e) {
           fileInput.value = ''
           };
           // 當發生網絡異常的時候會觸發,如果上傳數據的過程還未結束
           xhr.upload.onerror = function (e) {
           };
           // 上傳數據完成(成功或者失敗)時會觸發
           xhr.upload.onloadend = function (e) {
           // console.log('上傳結束')
           };
           xhr.send(formData)
           });
           this.container.appendChild(fileInput);
           }
           fileInput.click();
           }
          };
          
          export default {
           placeholder: '',
           theme: 'snow', // 主題
           modules: {
           toolbar: {
           container: toolOptions, // 工具欄選項
           handlers: handlers // 事件重寫
           }
           }
          };
          

          4、JAVA圖片上傳接口

          @PostMapping("/up/img")
          @ApiOperation(value = "上傳")
          public String upImg(HttpServletRequest request,
           @ApiParam(name = "userId", value = "id") String userId,
           MultipartFile img){
           String fileName = ServiceCommon.ymdhmsdfStr.format(new Date())+"_"+img.getOriginalFilename();//防止圖片重名覆蓋,生成一個當前時間+圖片名
           String path = filePath;//配置文件中的圖片存儲前綴,如d://img/
           String nameTypePath = "/" +userId+ "/blog_img" ;//中間路徑
           return upFileImgService.upFileService("/" + fileName, path + nameTypePath, nameTypePath, img);//接口看后面Service層
          }
          

          4.1、Service層

          public Result upFileService(String fileName, String filePath, String nameTypePath, MultipartFile file) {
           try {
           File file1 = new File(filePath);//按路徑生成文件對象
           if(!file1.exists()){//如果文件不存在,將創建一個文件
           file1.mkdirs();
           }
           byte [] bytes = file.getBytes();//獲取文件二進制字節數組
           String url = filePath+fileName;//存儲路徑+文件名,產生一個文件存儲地址
           Path path = Paths.get(url);
           Files.write(path,bytes);//文件寫入
           return nameTypePath+fileName;//返回URL(我這個URL返回的前綴地址是截取掉的,不會顯示IP等信息,只返回給前端后半地址,前端在調用圖片獲取時,將在接口中帶入前綴,防止全路徑暴露給前端)
           } catch (IOException e) {
           e.printStackTrace();
           return "";
           }
          }
          

          5、圖片獲取接口

          @GetMapping("/get/img")
          @ApiOperation(value = "獲取圖片")
          public void getImg(HttpServletResponse response,
           @ApiParam(name = "url", value = "文件路徑") @RequestParam(required = true) String url,
           @ApiParam(name = "resType", value = "文件以什么類型輸出(pdf,jpg)") @RequestParam(required = false) String resType) {
           String path = filePath + url;
           upFileImgService.download(path, response, "get", resType);
          }
          

          5.1、圖片獲取接口Service層

          public void download(String filePath, HttpServletResponse response,String type,String resType) {
           File file = new File(filePath); 
           response.setContentLength((int)file.length());
           try (
           FileInputStream fis = new FileInputStream(file);
           OutputStream os = response.getOutputStream())
           {
           byte[] buf = new byte[1024 * 256];
           int i;
           while ((i = fis.read(buf)) != -1) {
           os.write(buf, 0, i);
           }
           os.flush();
           } catch (IOException e) {
           System.out.println(e.getMessage());
           }
          }
          

          到此VUE富文本編輯器+Spring Boot接口就完成了。代碼基本復制改改就可以使用。最后看下效果如何,如下圖上,從原來的Base64內容變成URL地址,整個文章字段就縮小幾十倍,這在IO讀取時也加快了幾十倍。

          小白,昨天我們了解了input為file類型時選擇圖片的功能,我們暫且稱它為inputfile吧,今天我們說一下javascript對inputfile的一些操作,為我們做圖片上傳做個準備。”

          小白:“好啊!真想知道js是怎么讀取文件信息的!”

          老朱:“這是一個圖片上傳簡單布局。”

          “主容器main里面包含了inputfile、縮略圖容器和上傳按鈕。現在我們要做的第一步功能就是,如何選擇圖片以后把圖片放到縮略圖容器中進行預覽!”

          老朱繼續說道:“首選我們需要在用戶選擇文件以后,通過javascript拿到圖片的信息!這就需要用到onchange事件和javascript的file對象知識。”

          “這里用jQuery的change方法來檢查inpufile內容是否發生了改變,一旦改變就從控制臺輸出當前選擇的文件信息。從輸出的結果你大概能理解file對象的構造,file對象包含了最后修改時間(lastModifiedDate)、文件名(name)、文件大小(size)、文件類型(type)等信息。至于輸出的時候為什么要用this而不是$(this),這是因為file對象是js原生對象,跟jquery沒關系,所以直接用this。”

          小白:“我看這幾個屬性沒有包含文件內容的屬性啊!”

          老朱:“恩,file對象只能拿到文件的信息,但是取不到文件的內容,我們還需要用一個H5新增的文件讀取類FileReader,通過它去讀file就能拿到文件的內容了!”

          “實例化一個fileReader對象fr,通過fr的readAsDataURL方法去讀file對象就能拿到圖片的base64編碼。”

          小白:“圖片的base64編碼是什么呢?”

          老朱:“簡單理解就是把圖片內容用一個特殊的文本編碼呈現出來,圖片進行base64編碼以后我們就可以通過字符串來表示一個圖片了。你可以自己去網上查查相關的介紹。”

          老朱繼續說道:“我們要拿到圖片的base64編碼需要等待讀取完成以后才能獲取,所以這是一個異步操作,因此需要用到onload事件。”

          “輸出fr對象的信息,我們可以看到result屬性里面包含了圖片的base64編碼,所以現在只需將fr的result屬性值賦值給一個img標簽的src屬性就可以看到這張圖片。”

          “注意這里呈現圖片的時候并不是用的圖片地址,而是用的圖片的base64編碼。通過這種方式我們就可以實時預覽當前選擇的圖片了。”

          小白:“為什么不直接使用圖片的本地路徑呢?”

          老朱:“有時由于安全沙箱限制,本地圖片是不能直接在網頁上顯示的!”

          小白:“哦!我完了也去了解一下這方面的介紹。”

          老朱:“通過上面的方法我們拿到了圖片的base64編碼,現在只需要一個能夠接收base64編碼的PHP頁面就可以把圖片存到服務器上了,這塊功能我們明天再討論,你先把今天說的東西練習練習。”

          小白:“好的,我還有一個不明白的地方!選擇文件的時候除了圖片還有其他文件格式吧!這個怎么做區分呢?”

          老朱:“我們剛開始不是輸出了file對象的type和size屬性了么?通過type屬性可以判斷當前文件是不是圖片,通過size屬性可以判斷圖片大小是不是超標。這是我們在實際開發的時候非常重要的兩個屬性,你一定要記住。好了你去練習吧,注意用好這兩個屬性(假如用戶選擇了非圖片格式或者特別大的圖片你應該怎么處理)。”


          想學H5的朋友可以關注老爐,您的關注是我持續更新《小白HTML5成長之路》的動力!


          主站蜘蛛池模板: 中文字幕不卡一区| 在线一区二区三区| 精品成人一区二区三区四区| 久久免费视频一区| 在线精品一区二区三区| 久久综合一区二区无码| 日本一区二区视频| 中文字幕亚洲一区二区va在线| 亚洲一区动漫卡通在线播放| 日韩精品一区二区三区中文字幕| 福利一区二区三区视频在线观看 | 亚洲福利一区二区| 精品免费久久久久国产一区| 无码人妻精品一区二区三区蜜桃| 国产成人久久精品麻豆一区| 亚洲av无码一区二区三区天堂| 在线视频一区二区三区三区不卡| 另类国产精品一区二区| 国产高清不卡一区二区| 一区二区手机视频| 精品国产一区二区三区香蕉事| 无码一区二区三区| 中文字幕在线无码一区| 国产乱码精品一区三上 | 亚洲AV无码一区二区三区在线| 国产激情一区二区三区| 在线免费观看一区二区三区| 91一区二区三区四区五区| 日韩人妻无码一区二区三区综合部 | 亚洲一区二区三区91| 国产福利电影一区二区三区,日韩伦理电影在线福 | 亚洲av午夜福利精品一区| 乱色熟女综合一区二区三区| 性盈盈影院免费视频观看在线一区| 日本午夜精品一区二区三区电影| 久久无码一区二区三区少妇 | 亚洲av高清在线观看一区二区 | 一区免费在线观看| 国产精品一区二区AV麻豆| 91久久精品国产免费一区 | 亚洲乱码一区二区三区国产精品|