JavaScript面向對象實現(xiàn)放大鏡案例
本文實例為大家分享了JavaScript面向對象實現(xiàn)放大鏡的具體代碼,供大家參考,具體內容如下
效果圖

實現(xiàn)原理分析
如圖所示

觸發(fā)鼠標的移動事件時,根據(jù)事件對象的 clientX 和 clientY 屬性得到實時的坐標點 x 和 y
值 ,減去 small_box 的 offsetLeft 值 和 cutting_box 的寬度的一半 ,可以得到 cutting_box 的偏移量 left 值,top值同理。當 cutting_box 到達右側和下側時,left 和 top 取得最大值。用 實時變化的left和top值 比上 各自的最大值,可得到一個比例,再根據(jù)這個比例,算出右側 big_img 元素的 left 和 top。具體求法是:先求出 big_img 放大后的寬高,由這個寬高求得big_img的 left和top 最大值。在用這個最大值乘以上述的比例值即得到相應的 big_img 的 left 和 top值。
注意點:big_img 放大后的寬高求法
small_box寬高 / cutting_box = big_img寬高 / big_box寬高。(只有big_img寬高未知)
基本頁面結構
<div class="small"> <img src="images/timg.jpg" alt=""> <span class="grayBox"></span> </div> <div class="big"> <img src="images/timg.jpg" alt=""> </div>
CSS代碼
.small {
width: 400px;
height: 400px;
position: relative;
border:4px solid #ddd;
box-shadow: 0 0 5px rgba(0,0,0,.5);
}
.small img{
width: 100%;
height: 100%;
}
.small .grayBox{
display: none;
width: 100px;
height: 100px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
position: absolute;
left: 0;
top: 0;
}
.big{
width: 400px;
height: 400px;
position: absolute;
left: 700px;
top: 100px;
border:1px solid #f10;
display: none;
overflow: hidden;
}
.big img{
position: absolute;
}
面向對象實現(xiàn)
分析(OOA)
- 元素選擇功能
- 綁定事件驅動
- 元素的顯示與隱藏功能
- 小圖移動,大圖的放大跟隨移動功能
- 鼠標滾輪縮放功能
設計(OOD)
構造函數(shù)
function Magnifier(){}
初始化各個功能模塊
function init(){}
事件綁定功能
function bindEvent(){}
元素的顯示與隱藏功能
function eleToggle(){}
小圖移動,大圖放大跟隨功能
function eleMove(){}
編寫(OOP)
- 首先明確應該把所有功能都放到放大鏡構造函數(shù)的原型上。
- 其次實例化一個對象時應該傳入的是對象類型的參數(shù),如下所示:
new Magnifier({
small_box : ".small",
cutting_box : ".grayBox",
big_box : ".big",
big_img : ".big img"
});
構造函數(shù)此時需要接收實例化時傳入的參數(shù):
function Magnifier( options ) {
// 調用初始化函數(shù),處理接收到的參數(shù)對象
this.init( options );
}
初始化功能完成初始化元素、獲取small_box、cutting_box、big_box的offset系列的值:
Magnifier.prototype.init = function( options ){
// 初始化元素;
for(var attr in options){
this[attr+"_ele"] = this.$(options[attr]);
}
// 為了節(jié)省性能,所以只獲取一次offsetLeft;
this.small_box_offset = {
left : this.small_box_ele.offsetLeft,
top : this.small_box_ele.offsetTop,
width : parseInt( getComputedStyle(this.small_box_ele).width ),
height : parseInt( getComputedStyle(this.small_box_ele).width )
}
this.cutting_box_offset = {
width : parseInt( getComputedStyle(this.cutting_box_ele).width ),
height : parseInt( getComputedStyle(this.cutting_box_ele).height ),
}
this.big_box_offset = {
width : parseInt( getComputedStyle(this.big_box_ele).width ),
height : parseInt( getComputedStyle(this.big_box_ele).height ),
}
// 標志變量 ,鼠標是否移入放大鏡
this.magnifier_start = false;
this.bindEvent();
// 圖片縮放功能
this.scaleBigImg();
}
選擇元素功能:
Magnifier.prototype.$ = function(selector){
return document.querySelector(selector);
}
事件綁定功能:
Magnifier.prototype.bindEvent = function(){
// 鼠標移入左側small_box
this.small_box_ele.addEventListener( "mouseover" , function(){
// cutting_box big_box元素顯示;
this.eleToggle("show");
// 修改標志變量為true
this.magnifier_start = true;
// 修改事件函數(shù)里面的this指向為當前實例對象
}.bind(this));
// 鼠標移出左側small_box
this.small_box_ele.addEventListener( "mouseout" , function(){
// cutting_box big_box元素隱藏;
this.eleToggle("hide");
this.magnifier_start = false;
}.bind(this));
// 鼠標移動,元素運動;
this.small_box_ele.addEventListener("mousemove" , function( evt ){
var e = evt || event;
// 獲取鼠標點距離瀏覽器可視區(qū)的 x y 值
var x = e.clientX ;
var y = e.clientY ;
// 調用factoryPosition處理得到的坐標值
this.res = this.factoryPosition( x , y );
// 把處理好后的坐標值傳入eleMove方法,改變相應的left、top值
this.eleMove( this.res );
}.bind(this));
// 滾輪事件;
document.addEventListener("mousewheel" , function( evt ){
// 如果鼠標未移入放大鏡,則不執(zhí)行滾輪事件函數(shù)
if(!this.magnifier_start){ return false }
var e = evt || event;
// 判定滾輪向上(縮?。┻€是向下(放大);
this.changeCutBoxScale( e.wheelDelta > 0 ? "narrow" : "large" );
}.bind(this));
}
元素顯示隱藏功能:
Magnifier.prototype.eleToggle = function( type ){
// 根據(jù)type類型,判定元素的display的屬性值 block | none
this.cutting_box_ele.style.display = type === "show" ? "block" : "none";
this.big_box_ele.style.display = type === "show" ? "block" : "none";
}
處理鼠標移動時得到的坐標點 x 和 y 值:
Magnifier.prototype.factoryPosition = function( x , y ){
// 根據(jù)接收到的 x 和 y 計算得到 cutting_box 的 left 和 top 偏移量
var _left = x - this.small_box_offset.left - this.cutting_box_offset.width / 2;
var _top = y - this.small_box_offset.top - this.cutting_box_offset.height / 2
// cutting_box 的 left 和 top 的最大值
var _left_max = this.small_box_offset.width - this.cutting_box_offset.width;
var _top_max = this.small_box_offset.height - this.cutting_box_offset.height;
// 最小值邊界監(jiān)測;
_left = _left <= 0 ? 0 : _left;
_top = _top <= 0 ? 0 : _top
// 最大值檢測
_left = _left >= _left_max ? _left_max : _left;
_top = _top >= _top_max ? _top_max : _top;
// 返回處理好的坐標點值 以及 移動的距離與最大值的比例系數(shù)
return {
x : _left,
y : _top,
xp: _left / _left_max,
yp:_top / _top_max
}
}
小圖移動,大圖放大跟隨功能:
Magnifier.prototype.eleMove = function( position_obj ){
// 左側cutting_box移動范圍
this.cutting_box_ele.style.left = position_obj.x + "px";
this.cutting_box_ele.style.top = position_obj.y + "px";
// 大圖big_img的移動范圍。cutting_box和big_img的移動方向時相反的
this.big_img_ele.style.left = -position_obj.xp * this.big_img_boundary.left_max + "px";
this.big_img_ele.style.top = -position_obj.yp * this.big_img_boundary.top_max + "px";
}
放大圖片功能:
Magnifier.prototype.scaleBigImg = function(){
// 放大的比例 ;
var width_p = this.big_box_offset.width / this.cutting_box_offset.width;
var height_p = this.big_box_offset.height / this.cutting_box_offset.height;
// 獲得了big_img放大之后的寬高;
this.big_img_offset = {
width : width_p * this.small_box_offset.width,
height : height_p * this.small_box_offset.height,
}
// 計算出big_img運動的邊界;
this.big_img_boundary = {
left_max : this.big_img_offset.width - this.big_box_offset.width,
top_max : this.big_img_offset.height - this.big_box_offset.height
}
// 給圖片設置等比例寬高;
this.big_img_ele.style.width = this.big_img_offset.width + "px";
this.big_img_ele.style.height = this.big_img_offset.height + "px";
}
鼠標滾輪滾動時同時需要改變左側 cutting_box 的大?。?/p>
Magnifier.prototype.changeCutBoxScale = function( type ){
switch ( type ) {
// 放大
case "large":
this.cutting_box_offset.width += 2;
this.cutting_box_offset.height += 2;
// 讓cutting_box 向左 向上移動 讓鼠標始終保持在中心位置
this.res.x --;
this.res.y --;
break;
// 縮小
case "narrow":
this.cutting_box_offset.width -= 2;
this.cutting_box_offset.height -= 2;
this.res.x ++;
this.res.y ++;
break;
default:
break;
}
this.cutting_box_ele.style.width = this.cutting_box_offset.width + "px";
this.cutting_box_ele.style.height = this.cutting_box_offset.height + "px";
// 位置改變之后,調用相應的比例計算工具;
this.scaleBigImg();
// 重新進行大圖運動的計算;
this.eleMove(this.res);
}
功能補充:多圖片切換,可以放大相應的圖片。
添加標簽:data-src自定義屬性存放不同的圖片路徑
<button class="btn" data-src=""><img src="" alt=""></button> <button class="btn" data-src=""><img src="" alt=""></button>
最后只需在實例化放大鏡對象后,分別給每個按鈕綁定點擊或者移入事件,再替換 small 和 big 容器中的 img 的 src 的屬性值為相應的 data-src 的屬性值即可,如下所示:
// 選中所有代表不同圖片的button按鈕
var btns = document.querySelectorAll(".btn");
// 選中small 和 big 容器中的 img 標簽
var imgs = document.querySelectorAll(".big img,.small img");
for(var i = 0 ; i < btns.length ; i ++){
btns[i].onclick = function(){
// 獲取每個按鈕上的不同的 data-src 屬性
var src = this.getAttribute("data-src");
for(var k = 0 ; k < imgs.length ; k ++){
// 替換相應的 src 屬性的屬性值
imgs[k].src = src;
}
}
}
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
javascript用defineProperty實現(xiàn)簡單的雙向綁定方法
這篇文章主要介紹了javascript用defineProperty實現(xiàn)簡單的雙向綁定方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-04-04

