首頁 web前端 js教程 JavaScript物件導向分層思維全面解析

JavaScript物件導向分層思維全面解析

Dec 05, 2016 pm 04:17 PM
javascript

js本身不是面向對象語言,在我們實際開發中其實很少用到面向對象思想,以前一直以為當要復用的時候才封裝成對象,然而隨著現在做的項目都後期測試階段發現面向對象的作用不隻隻是複用,可能你們會說面向對象還有繼承,多態的概念,但在javascript裡面多態的概念是不存在,而繼承由於web頁面的必須先下載js在運行導致js的繼承不能像後台那麼靈活而且js沒有重載以及重寫不方便(而且js中重寫的意義不是很大),所以在js中很少用到面向對象,可能在一些插件中會看到對象的寫法,寫js的都會有同樣的感覺在寫一個插件的時候一般是先用面相過程把插件功能寫出來,然後在重構改成對象的方法.但在實際專案開發中要求時間進度和開發成本很少會有那麼寬鬆的時間讓你先用面向過程實現功能在重構.實際開發中我們基本都是用面相過程寫完就直接提交了.

這種寫法發現一個問題就是,當你把這個頁面的寫完了之後過一段時間突然這個頁面的功能需求或是頁面佈局要調整,你在看這個頁面的代碼,一下很難快速的把整個頁面的代碼邏輯步驟梳理清楚,我相信很多寫前端都要同感吧! 舉個例子:我幾年前寫的放大鏡插件,現在我在放出來發現我寫的這個插件在谷歌瀏覽器第一次渲染的時候沒有效果,代碼如下:

/// <reference path="../jquery11.js" />
(function ($) {
$.fn.extend({
jqoom: function (potions) {
var settings = {
width: 350,
height: 350,
position: "right"
}
if (potions) {
$.extend(settings, potions);
}
var ImgUrl = $("img", this).attr("src");
var ImgMinWidth = $("img", this).width();
var ImgMinHeigth = $("img", this).height();
var ImgWidth = 0;
var ImgHeight = 0;
var de = true;
$(this).hover(function (e) {
}, function () {
$("#jqoomz").remove();
$(document).unbind("mousemove");
$("#jqoomy").remove();
de = true;
});
$("img", this).hover(function (e) {
var pagex = e.x || e.pageX;
var pagey = e.y || e.pageY;
var pagex1 = 0;
var pagey1 = 0;
var leftcha = 0;
var topcha = 0;
_this = $(this).parents("div");
if ($("#jqoomz").length == 0) {
_this.after("<div id=&#39;jqoomz&#39;></div>");
var obj = new Image();
obj.src = ImgUrl;
obj.onload = function () {
if (de && obj.height > 0) {
de = false;
ImgWidth = obj.width;
ImgHeight = obj.height;
finder.call(_this.find("img")[0]);
}
};
$("#jqoomz").width(settings.width).height(settings.height).offset({
left: $(_this).outerWidth() + $(_this).offset().left,
top: $(_this)[0].offsetTop
}).append($("<img  src="/static/imghw/default1.png"  data-src="jquery11.js"  class="lazy"  alt="JavaScript物件導向分層思維全面解析" ></img>").attr("src", ImgUrl));
if (de && obj.height > 0) {
de = false;
ImgWidth = obj.width;
ImgHeight = obj.height;
finder.call(this);
}
}
function mover(event) {
var pagex2 = event.x || event.pageX;
var pagey2 = event.y || event.pageY;
if (parseInt(pagex2 + leftcha) <= parseInt($(_this).width() + $(_this).offset().left) && pagex2 >= leftcha + $(_this).offset().left) {
$(this).offset({left: pagex2 - leftcha});
} else {
if (parseInt(pagex2 + leftcha) > parseInt($(_this).width() + $(_this).offset().left) && pagex2)
$(this).offset({left: $(_this).width() + $(_this).offset().left - leftcha * 2});
else
$(this).offset({left: $(_this).offset().left});
}
if (parseInt(pagey2 + topcha) <= parseInt($(_this).height() + $(_this).offset().top) && pagey2 >= topcha + $(_this).offset().top) {
$(this).offset({top: (pagey2 - topcha)});
//document.getElementById("move").style.top = (pagey2 - (this.pagey - this.divtop)).toString() + "px";
} else {
if (parseInt(pagey2 + topcha) > parseInt($(_this).height() + $(_this).offset().top))
$(this).offset({top: ($(_this).height() + $(_this).offset().top - topcha * 2)});
//document.getElementById("move").style.top = (this.height - this.divHeight).toString() + "px";
else
$(this).offset({top: $(_this).offset().top});
//document.getElementById("move").style.top = "0px"
}
var bilx = ($(this).offset().left - $(_this).offset().left) / (ImgMinWidth / ImgWidth);
var bily = ($(this).offset().top - $(_this).offset().top) / (ImgMinHeigth / ImgHeight);
$("#jqoomz img").css({"margin-left": -bilx, "margin-top": -bily});
}
function finder() {
if (parseFloat($(this).offset().top + $(this).height() - (ImgMinHeigth / ImgHeight * ImgMinHeigth)) >=
parseFloat(pagey - ImgMinHeigth / ImgHeight * ImgMinHeigth / 2) && parseFloat(pagey - ImgMinHeigth / ImgHeight * ImgMinHeigth / 2) >=
parseFloat($(this).offset().top)) {
pagey1 = (pagey - ImgMinHeigth / ImgHeight * ImgMinHeigth / 2);
} else {
if ((pagey - ImgMinHeigth / ImgHeight * ImgMinHeigth / 2) < $(this).offset().top) {
pagey1 = $(this).offset().top;
} else {
pagey1 = ($(this).offset().top + $(this).height() - (ImgMinHeigth / ImgHeight * ImgMinHeigth));
}
}
if (($(this).offset().left + $(this).width() - ImgMinWidth / ImgWidth * ImgMinWidth) >=
(pagex - ImgMinWidth / ImgWidth * ImgMinWidth / 2) && (pagex - ImgMinWidth / ImgWidth * ImgMinWidth / 2) >=
$(this).offset().left) {
pagex1 = (pagex - ImgMinWidth / ImgWidth * ImgMinWidth / 2);
} else {
if ((pagex - ImgMinWidth / ImgWidth * ImgMinWidth / 2) < $(this).offset().left) {
pagex1 = $(this).offset().left;
} else {
pagex1 = ($(this).offset().left + $(this).width() - ImgMinWidth / ImgWidth * ImgMinWidth);
}
}
leftcha = ImgMinWidth / ImgWidth * ImgMinWidth / 2;
topcha = ImgMinHeigth / ImgHeight * ImgMinHeigth / 2;
if ($("#jqoomy").length == 0) {
$(this).after("<div id=&#39;jqoomy&#39;></div>")
.siblings("#jqoomy")
.addClass("jqoomy").show()
.width((ImgMinWidth / ImgWidth * ImgMinWidth))
.height((ImgMinHeigth / ImgHeight * ImgMinHeigth)).offset({
top: pagey1,
left: pagex1
});
}
$(document).on("mousemove", $.proxy(mover, $("#jqoomy")));
}
}, function () {
});
}
});
})(jQuery);
登入後複製

   html:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<script ></script>
<script src="OppJqoom.js"></script>
<style type="text/css">
.jqoom
{
width: 350px;
height: 350px;
border: solid 1px #DFDFDF;
z-index: 10;
}
.jqoom img
{
cursor: pointer;
z-index: 10;
max-height: 350px;
max-width: 350px;
}
.jqoomy
{
background-color: white;
position: relative;
z-index: 999;
opacity: 0.5;
cursor: pointer;
border: solid 1px #DFDFDF;
}
#jqoomz
{
border: solid 1px #DFDFDF;
position: absolute;
overflow: hidden;
}
.lef
{
border: 1px solid #DFDFDF;
display: block;
height: 72px;
line-height: 72px;
text-align: center;
text-decoration: none;
width: 10px;
background-color:#EBEBEB;
float:left;
}
.lef:hover
{
color:red;
}
.jqooz
{
float:left;
width:352px;
margin-top:20px;
}
.jqooz ul
{
float: left;
margin: 0;
padding: 0;
width:328px;
height:72px;
}
.jqooz ul li
{
display: inline;
list-style: none outside none;
margin: 0 10px;
}
.jqooz ul li img
{
border: 1px solid #DFDFDF;
max-height: 72px;
max-width: 120px;
}
.jqooz ul li img:hover
{
border: 1px solid #ff6600;
}
</style>
<script type="text/javascript">
$(function () {
$(".jqoom").jqoom();
});
</script>
</head>
<body>
<div class="jqoom">
<img  src="/static/imghw/default1.png"  data-src="b3.jpg"  class="lazy"   / alt="JavaScript物件導向分層思維全面解析" >
</div>
<div class="jqooz">
<a href="javascript:void(0)" class="lef"><</a>
<ul>
<li><a>
<img  src="/static/imghw/default1.png"  data-src="b3.jpg"  class="lazy"   / alt="JavaScript物件導向分層思維全面解析" ></a></li>
</ul>
<a href="javascript:void(0)" class="lef">></a>
</div>
</body>
</html>
登入後複製

   

效果:

JavaScript物件導向分層思維全面解析

現在我要修改這個插件為什麼在谷歌瀏覽器第一次加載的時候沒有效果,那我要重新跟著代碼來放大的整個程式碼來放大這個過程放大鏡的功能還不是很複雜,在實際項目中各種函數回調嵌套,取數,數據處理,顯示,頁面的動態效果都交織在onload或是ready裡面你要花幾個小時甚至一整天來梳理你要修改頁面的程式碼邏輯,而且還未必能梳理的全面,所以經常會有前端同事在隔了一段時間給之前寫的頁面添加註釋的時候說我自己寫代碼都開始看不懂了.

本身javascript特點之一是事件監聽函數回調,這是它優點,nodejs作者之所以選擇js其中一個原因就是javascript的事件監聽函數回調帶來的優點,但函數回調同時也帶來一個缺點就是經常出現return不出資料,典型的例子就是ajax,jQuery傳統的ajax成功之後回調success方法,當你要把這個ajax的輸出作為另一個ajax的輸入的時候你就不得不要嵌套ajax,一旦嵌套多了這個程式碼的可讀性和複雜度就增加了很多!後期的維護也自然增加了難度,Promise出來之後,jQuery、angular也都紛紛加了Promise。為什麼javascript在後期維護要花這麼大的時間去梳理邏輯?

我們在看看後台java或c#的語言是怎麼做,典型的javaweb幾乎都是springMVC框架,C#做web毋庸置疑是.net MVC,他們都有共同的特點是c層提供給前台頁面ajax調用的方法都是按照所需要的數據一個一個拆分的,還有相對於的m層,mvc其實是兩個維度的分層這是我個人觀點,一個維度是單個細小的功能分為view,control ,model,另一個維度是整個頁面分成多個小的功能.所以你發現後台程式碼要修改其實很容易就把邏輯梳理,那前台javascript也能不能按照整個思路來取分層呢?

這個插件沒有涉及到動態取數,所以分層的標準也不一樣,在這裡我分了兩層,第一層是對滑鼠移動後圖片的一系列演算法,第二層是事件綁定分的一系列dom的操作,程式碼如下:

/**
* Created by on 2016/11/2.
*/
(function ($) {
//构造函数逻辑主线路
var OppJqoom = function (_this, potions) {
this._this = _this;
this.ImgUrl = $("img", this._this).attr("src");
this.ImgMinWidth = $("img", this._this).width();
this.ImgMinHeigth = $("img", this._this).height();
this.ImgWidth ,this.ImgHeight ,this.leftcha,this.topcha;
var settings = {
width: 350,
height: 350,
position: "right"
}
$.extend(this,settings);
if (potions) {
$.extend(this, potions);
}
this.domOperation.Jqoomhover.call(this);
this.domOperation.imghover.call(this);
};
OppJqoom.prototype = {
// 第一层 算法层
basicOperation: {
/* 获取遮罩层的top和left*/
finder: function (that) {
var pagey1, pagex1;
if (parseFloat($(this).offset().top + $(this).height() - (that.ImgMinHeigth / that.ImgHeight * that.ImgMinHeigth)) >=
parseFloat(this.pagey - that.ImgMinHeigth / that.ImgHeight * that.ImgMinHeigth / 2) && parseFloat(this.pagey - that.ImgMinHeigth / that.ImgHeight * that.ImgMinHeigth / 2) >=
parseFloat($(this).offset().top)) {
pagey1 = (this.pagey - that.ImgMinHeigth / that.ImgHeight * that.ImgMinHeigth / 2);
} else {
if ((this.pagey - that.ImgMinHeigth / that.ImgHeight * that.ImgMinHeigth / 2) < $(this).offset().top) {
pagey1 = $(this).offset().top;
} else {
pagey1 = ($(this).offset().top + $(this).height() - (that.ImgMinHeigth / that.ImgHeight * that.ImgMinHeigth));
}
}
if (($(this).offset().left + $(this).width() - that.ImgMinWidth / that.ImgWidth * that.ImgMinWidth) >=
(this.pagex - that.ImgMinWidth / that.ImgWidth * that.ImgMinWidth / 2) && (this.pagex - that.ImgMinWidth / that.ImgWidth * that.ImgMinWidth / 2) >=
$(this).offset().left) {
pagex1 = (this.pagex - that.ImgMinWidth / that.ImgWidth * that.ImgMinWidth / 2);
} else {
if ((this.pagex - that.ImgMinWidth / that.ImgWidth * that.ImgMinWidth / 2) < $(this).offset().left) {
pagex1 = $(this).offset().left;
} else {
pagex1 = ($(this).offset().left + $(this).width() - that.ImgMinWidth / that.ImgWidth * that.ImgMinWidth);
}
}
that.leftcha = that.ImgMinWidth / that.ImgWidth * that.ImgMinWidth / 2;
that.topcha = that.ImgMinHeigth / that.ImgHeight * that.ImgMinHeigth / 2;
that.domOperation.docMousemove.call(that);
return {top: pagey1, left: pagex1};
},
// 放大镜的图片的top和left
mover: function (that) {
if (parseInt(that.pagex2 + that.leftcha) <= parseInt(that._this.width() + that._this.offset().left) && that.pagex2 >= that.leftcha + that._this.offset().left) {
$(this).offset({left: that.pagex2 - that.leftcha});
} else {
if (parseInt(that.pagex2 + that.leftcha) > parseInt(that._this.width() + that._this.offset().left) && that.pagex2)
$(this).offset({left: that._this.width() + that._this.offset().left - that.leftcha * 2});
else
$(this).offset({left: that._this.offset().left});
}
if (parseInt(that.pagey2 + that.topcha) <= parseInt(that._this.height() + that._this.offset().top) && that.pagey2 >= that.topcha + that._this.offset().top) {
$(this).offset({top: (that.pagey2 - that.topcha)});
//document.getElementById("move").style.top = (pagey2 - (this.pagey - this.divtop)).toString() + "px";
} else {
if (parseInt(that.pagey2 + that.topcha) > parseInt(that._this.height() + that._this.offset().top))
$(this).offset({top: (that._this.height() + that._this.offset().top - that.topcha * 2)});
//document.getElementById("move").style.top = (this.height - this.divHeight).toString() + "px";
else
$(this).offset({top: that._this.offset().top});
//document.getElementById("move").style.top = "0px"
}
var bilx = ($(this).offset().left - that._this.offset().left) / (that.ImgMinWidth / that.ImgWidth);
var bily = ($(this).offset().top - that._this.offset().top) / (that.ImgMinHeigth / that.ImgHeight);
return{left:bilx,top:bily};
}
},
// 第二层 事件绑定层
domOperation: {
// 鼠标移动到图片的一系列dom的操作
imghover: function () {
var that = this;
$("img", this._this).hover(function (e) {
this.pagex = e.x || e.pageX;
this.pagey = e.y || e.pageY;
var offset;
var obj = new Image();
obj.src = that.ImgUrl;
obj.onload = function () {
if (obj.height > 0) {
that.ImgWidth = obj.width;
that.ImgHeight = obj.height;
if ($("#jqoomz").length == 0) {
that._this.after("<div id=&#39;jqoomz&#39;></div>");
}
offset = that.basicOperation.finder.call(that._this.find("img")[0],that);
}
};
if ($("#jqoomz").length == 0) {
that.ImgWidth = obj.width;
that.ImgHeight = obj.height;
that._this.after("<div id=&#39;jqoomz&#39;></div>");
}
offset = that.basicOperation.finder.call(this,that);
if ($("#jqoomy").length == 0) {
$(this).after("<div id=&#39;jqoomy&#39;></div>")
.siblings("#jqoomy")
.addClass("jqoomy")
.show()
.width((that.ImgMinWidth / that.ImgWidth * that.ImgMinWidth))
.height((that.ImgMinHeigth / that.ImgHeight * that.ImgMinHeigth))
.offset({
top: offset.top,
left: offset.left
});
}
$("#jqoomz").width(that.width).height(that.height).offset({
left: that._this.outerWidth() + that._this.offset().left,
top: that._this[0].offsetTop
}).append($("<img  alt="JavaScript物件導向分層思維全面解析" ></img>").attr("src", that.ImgUrl));
},function () {});
},
//鼠标在图片上滑动的一系列dom操作
docMousemove: function () {
var that=this;
$(document).on("mousemove", function (event) {
that.pagex2 = event.x || event.pageX;
that.pagey2 = event.y || event.pageY;
var offset=that.basicOperation.mover.call($("#jqoomy"),that);
$("#jqoomz img").css({"margin-left": -offset.left, "margin-top": -offset.top});
});
},
//鼠标移除图片的一系列dom操作
Jqoomhover:function () {
this._this.hover(function (e) {
}, function () {
console.log(111);
$("#jqoomz").remove();
$(document).unbind("mousemove");
$("#jqoomy").remove();
});
}
}
};
$.fn.extend({
jqoom: function (potions) {
return new OppJqoom(this, potions);
}
})
})(jQuery);
登入後複製

然後加上簡單的註釋感覺頁面的邏輯步驟就很清晰了,當然這種寫法一種比較麻煩的就是this的用法,對像中嵌套對象調用裡面的方法this是指向自己的物件.

在實際開發中我們可以分為資料讀取層,資料處理層,以及dom動態效果層,如果業務比較繁雜也可以在分個資料展現層.


本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何使用WebSocket和JavaScript實現線上語音辨識系統 如何使用WebSocket和JavaScript實現線上語音辨識系統 Dec 17, 2023 pm 02:54 PM

如何使用WebSocket和JavaScript實現線上語音辨識系統引言:隨著科技的不斷發展,語音辨識技術已成為了人工智慧領域的重要組成部分。而基於WebSocket和JavaScript實現的線上語音辨識系統,具備了低延遲、即時性和跨平台的特點,成為了廣泛應用的解決方案。本文將介紹如何使用WebSocket和JavaScript來實現線上語音辨識系

WebSocket與JavaScript:實現即時監控系統的關鍵技術 WebSocket與JavaScript:實現即時監控系統的關鍵技術 Dec 17, 2023 pm 05:30 PM

WebSocket與JavaScript:實現即時監控系統的關鍵技術引言:隨著互聯網技術的快速發展,即時監控系統在各個領域中得到了廣泛的應用。而實現即時監控的關鍵技術之一就是WebSocket與JavaScript的結合使用。本文將介紹WebSocket與JavaScript在即時監控系統中的應用,並給出程式碼範例,詳細解釋其實作原理。一、WebSocket技

如何利用JavaScript和WebSocket實現即時線上點餐系統 如何利用JavaScript和WebSocket實現即時線上點餐系統 Dec 17, 2023 pm 12:09 PM

如何利用JavaScript和WebSocket實現即時線上點餐系統介紹:隨著網路的普及和技術的進步,越來越多的餐廳開始提供線上點餐服務。為了實現即時線上點餐系統,我們可以利用JavaScript和WebSocket技術。 WebSocket是一種基於TCP協定的全雙工通訊協議,可實現客戶端與伺服器的即時雙向通訊。在即時線上點餐系統中,當使用者選擇菜餚並下訂單

如何使用WebSocket和JavaScript實現線上預約系統 如何使用WebSocket和JavaScript實現線上預約系統 Dec 17, 2023 am 09:39 AM

如何使用WebSocket和JavaScript實現線上預約系統在當今數位化的時代,越來越多的業務和服務都需要提供線上預約功能。而實現一個高效、即時的線上預約系統是至關重要的。本文將介紹如何使用WebSocket和JavaScript來實作一個線上預約系統,並提供具體的程式碼範例。一、什麼是WebSocketWebSocket是一種在單一TCP連線上進行全雙工

JavaScript與WebSocket:打造高效率的即時天氣預報系統 JavaScript與WebSocket:打造高效率的即時天氣預報系統 Dec 17, 2023 pm 05:13 PM

JavaScript和WebSocket:打造高效的即時天氣預報系統引言:如今,天氣預報的準確性對於日常生活以及決策制定具有重要意義。隨著技術的發展,我們可以透過即時獲取天氣數據來提供更準確可靠的天氣預報。在本文中,我們將學習如何使用JavaScript和WebSocket技術,來建立一個高效的即時天氣預報系統。本文將透過具體的程式碼範例來展示實現的過程。 We

簡易JavaScript教學:取得HTTP狀態碼的方法 簡易JavaScript教學:取得HTTP狀態碼的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

javascript如何使用insertBefore javascript如何使用insertBefore Nov 24, 2023 am 11:56 AM

用法:在JavaScript中,insertBefore()方法用於在DOM樹中插入一個新的節點。這個方法需要兩個參數:要插入的新節點和參考節點(即新節點將要插入的位置的節點)。

JavaScript與WebSocket:打造高效率的即時影像處理系統 JavaScript與WebSocket:打造高效率的即時影像處理系統 Dec 17, 2023 am 08:41 AM

JavaScript是一種廣泛應用於Web開發的程式語言,而WebSocket則是一種用於即時通訊的網路協定。結合二者的強大功能,我們可以打造一個高效率的即時影像處理系統。本文將介紹如何利用JavaScript和WebSocket來實作這個系統,並提供具體的程式碼範例。首先,我們需要明確指出即時影像處理系統的需求和目標。假設我們有一個攝影機設備,可以擷取即時的影像數

See all articles