<script src="https://lf3-cdn-tos.bytescm.com/obj/cdn-static-resource/tt_player/tt.player.js?v=20160723"></script>
在HTML中,id和class是元素最基本的兩個屬性,一般情況下,id和class都是用來選擇元素,以便進行CSS操作或者JavaScript操作。
一、ID屬性
我們知道id屬性具有唯一性,也就是說同一個id在一個頁面中只能出現一次,如果出現多次相同的id,那么CSS或JavaScript就無法識別id對應的是哪一個元素了。
二、class屬性
class,顧名思義就是“類”,與C++,C#等編程語言中的“類”相似,我們可以為同一個頁面的相同元素或者不同元素設置相同的class,然后使得相同class的元素具有相同的CSS樣式。
三、選擇器
選擇器定義:
用一種方式把你想要的元素選中,只有選中了,才可以為這個元素添加CSS樣式。
選擇器分類:
3.1元素選擇器
3.2id選擇器
3.3class選擇器
3.4后代選擇器
3.5群組選擇器
語法:
選擇器
{
屬性1:取值1;
.........
屬性n:取值n;
}
四、元素選擇器
元素選擇器,就是相同的元素,然后對相同的元素定義同一個CSS樣式。
語法:
div{width:100px;}
div是元素符號,width是屬性 ,100px是屬性值。
舉例:
選中頁面中的div元素,然后把他們的文本顏色定義為紅色
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>12CSS</title>
<style type="text/css">div{color: red;}</style>
</head>
<body>
<div >你好</div>
<p>你好</p>
<span>你好</span>
<div >你好</div>
</body>
</html>
預覽效果
五、id選擇器
語法:
#box{width:100px;}
對于一個id選擇器,id前面必須要加上前綴"#",box是id名稱,width是屬性,100px是屬性值
舉例:
選擇id=abc的元素, color屬性的屬性值是紅色。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>12CSS</title>
<style type="text/css">
#abc{color: #FF0000;}
</style>
</head>
<body>
<div >你好</div>
<p>你好</p>
<span id=abc>你好</span>
<div >你好</div>
</body>
</html>
六:class選擇器
class選擇器可以對相同元素或者不同元素定義相同的class屬性,然后針對同一個class的元素進行css樣式操作。
語法:
.abc{width:100px}
class名前面必須加上前綴的( .) ,否則無法生效,abc是類的名字,width是屬性,100px是屬性值。
舉例:
把選擇的class中的abc的所有元素,定義文本顏色為紅色
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>12CSS</title>
<style type="text/css">
.abc{color: #FF0000;}
</style>
</head>
<body>
<div >你好</div>
<p>你好</p>
<span class=abc>你好</span>
<div class=abc>你好</div>
</body>
</html>
七、后代選擇器
定義:
就是選擇元素內部中所有的某一種元素,包括子元素和其他后代元素。
語法:
h3 p{width:100px}
h3是選擇器1,p是選擇器2,width是屬性,100px是屬性值
舉例:
id為abc的元素,下面所有的idv元素,定義文本顏色為紅色。
id為efg 的元素,下面所有的span元素,定義文本為藍色
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>12CSS</title>
<style type="text/css">
#abc div{color: #FF0000;}
#efg span{color: blue;}
</style>
</head>
<body>
<div id=abc>
<div>你好1</div>
<div>你好2</div>
</div>
<div id="efg">
<p>你好3</p>
<span >你好4</span>
<div>你好5</div>
</div>
</body>
</html>
八、群組選擇器
群組選擇器,指的是同時對幾個選擇器進行操作
語法:
h3,p{width:100px;}
h3選擇器1 中間必須帶(,)隔開,p為選擇器2,width數學,100px屬性值
舉例:
把元素div,p中的元素,文本屬性設置成紅色
022年已接近尾聲,又到了每年發布大版本的時候,Tpflow歷經一個多月的意見征集及版本優化,從底層改進,從UI調整,增強了事件功能。
發布日期:2022年12月23日
發布版號:V7.0.0
更新內容如下:
基于<AntV X6> 圖形引擎再度深化
整合css資源,調整att屬性設置,刪除workflow.css
兼容最新PHP8.1版本
優化<Event>流程事件處理模型
增加流程版本
增加流程圖
計模式(Design pattern) 是解決軟件開發某些特定問題而提出的一些解決方案也可以理解成解決問題的一些思路。通過設計模式可以幫助我們增強代碼的可重用性、可擴充性、 可維護性、靈活性好。我們使用設計模式最終的目的是實現代碼的 高內聚 和 低耦合。通俗一點講的話 打比方面試官經常會問你如何讓代碼有健壯性。其實把代碼中的變與不變分離,確保變化的部分靈活、不變的部分穩定,這樣的封裝變化就是代碼健壯性的關鍵。而設計模式的出現,就是幫我們寫出這樣的代碼。 設計模式就是解決編程里某類問題的通用模板,總結出來的代碼套路就是設計模式。本文章總結下JS在工作中常用的設計模式 ,以幫助大家提高代碼性能,增強工作效率!
圣誕節要到了,許多家庭會買一顆松樹裝上彩燈,一閃一閃亮晶晶然后搖身一變成了圣誕樹。這里 的彩燈就是裝飾器,他不會對松樹原有的功能產生影響。(還是本來的樹)
這種給對象動態地增加職責的方式稱為裝 飾器(decorator)模式。裝飾器模式能夠在不改 變對象自身的基礎上,在程序運行期間給對象 動態地添加職責。
應用
當我們接手老代碼時,需要對它已有的功能做個拓展。
``
var horribleCode = function(){
console.log(’我是一堆你看不懂的老邏輯')
}
// 改成:
var horribleCode = function(){
console.log('我是一堆你看不懂的老邏輯')
console.log('我是新的邏輯')
}
這樣做有很多的問題。直接去修改已有的函數體,違背了我們的“開放封閉原則”;往一個函數體里塞這么多邏輯,違背了我們的“單一職責原則”。
為了不被已有的業務邏輯干擾,將舊邏輯與新邏輯分離,把舊邏輯抽出去:
var horribleCode = function(){
console.log(’我是一堆你看不懂的老邏輯')
}
var _horribleCode = horribleCode
horribleCode = function() {
_horribleCode()
console.log('我是新的邏輯')
}
horribleCode()
這樣就完成了舊代碼的運用 以及新代碼的無傷添加了!!!
先來理解一個概念 —— 構造器模式
你開了家動物園,只有兩只動物,你可能會這樣錄入系統:
const monkey = {
name: '悟空',
age: '1'
}
const tiger = {
name: '泰格伍茲',
age: '3'
}
如果你的動物越來越多,對象字面量也會越來越多,這個時候構造函數可以自動創建動物對象
this.name = name
this.age = age
}
const animal = new Animal(name, age) //Animal 就是一個構造器
像 Animal 這樣當新建對象的內存被分配后,用來初始化該對象的特殊函數,就叫做構造器。在 JavaScript 中,我們使用構造函數去初始化對象,就是應用了構造器模式。
可以看出每個實例化后 對象( animal )屬性的key (name,age) 是不變的,對應的value(空空,泰格伍茲)是變的。所以構造器將賦值過程封裝,確保了每個對象屬性固定,開放了取值確保個性靈活。
簡單工廠模式
動物園要求根據每個動物的食性喜好來分配不同的食物。這樣之前封裝的Animal 就不能直接用了,我們重新封裝的構造器。
this.name = name
this.age = age
this.favorite = 'fruit'
this.food = [apple, banaba]
}
function Carnivore (name,age) {
this.name = name
this.age = age
this.favorite = 'meat'
this.food = [beef, pork]
}
根據喜好可以分配相應的
function Factory(name, age, favorite) {
switch(career) {
case 'fruit':
return new Vegetarian(name, age)
break
case 'meat':
return new Carnivore(name, age)
break
...
}
總結
工廠模式:將創建對象的過程單獨封裝。
應用場景:有構造函數的地方、寫了大量的構造函數、調用了大量的 new的情況下
單例模式
保證僅有一個實例,并提供一個訪問它的全局訪問點,這樣的模式就叫做單例模式。然后性能得到優化!
以下代碼我們做一個彈窗 如果實例已經創建過 就無需再次創建 這就是單例!
<body>
<input type="button" id="btn1" value="成功">
<input type="button" id="btn2" value="失敗">
<input type="button" id="btn3" value="警告">
</body>
<script>
const obj = {
init:function(){
this.ele = document.createElement("dialog"),
document.body.appendChild(this.ele);
},
show:function(c, t){
// 每次顯示之前先判斷是否已經存在彈出框元素,如果不存在就創建,如果已經存在就不用重新創建,只需要修改樣式和顯示即可
if(!this.ele){
this.init();
}
this.ele.style.borderColor = c;
this.ele.style.color = c;
this.ele.innerHTML = t;
this.ele.style.display = "block";
clearTimeout(this.t);
this.t = setTimeout(()=>{
this.hide();
}, 2000);
},
hide:function(){
this.ele.style.display = "none";
}
}
const obtn1 = document.getElementById("btn1")
const obtn2 = document.getElementById("btn2")
const obtn3 = document.getElementById("btn3")
obtn1.onclick = function(){
obj.show("green", "成功");
}
obtn2.onclick = function(){
obj.show("red", "失敗");
}
obtn3.onclick = function(){
obj.show("yellow", "警告");
}
</script>
總結
優點:適用于單一對象,只生成一個對象實例,避免頻繁創建和銷毀實例,減少內存占用。
缺點:不適用動態擴展對象,或需創建多個相似對象的場景。
JavaScript設計模式(四)-適配器模式
當電腦需要外接顯示器的時候,我們都會用到下面這個東西。轉換器幫助我們在不用更改筆記本接口的同時可以適配HDMI。
將轉換器抽象到代碼層面就是今天要介紹的適配器了。
適配器模式的作用是解決兩個軟件實體間的接口不兼容的問題。使用適配器模式之后,原本 由于接口不兼容而不能工作的兩個軟件實體可以一起工作。
應用舉例: 點外賣的時候有美團,餓了么可以選擇,同一家店如果要對比兩個平臺的價格來回切換App十分不方便,作為一個Coder能用代碼解決的堅決不用人力。這個時候我們就想到寫個小應用對比兩家的價格。
在他們openapi里找到了對應的方法,發現請求不一樣,入參不一樣,返回的數據結構也不一樣。翻譯成偽代碼就是如下的狀態
class Eleme() {
getElePice() {
console.log('在餓了么上商品的價格')
return {elePrice:xx}
}
}
class Meituan() {
getMeiPice() {
console.log('在美團上商品的價格')
return {meiPrice:xx}
}
}
試想一下,如果再多增加一些其他平臺,前端渲染的時候要寫多少個if else去判斷來源。這個時候我們可以通過引入適配器
class ElemeAdapter() {
getPrice () {
const e = new Eleme()
return { price:e.elePrice}
}
}
class MeituanAdapter() {
getPrice () {
const m = new Meituan()
return { price:m.meiPrice}
}
}
//通過適配器拿到的數據格式都是統一的 {price:xx}
//同樣,入參也可以在適配器中統一處理
雖然這種模式很簡單,但還有很多場景運用到了適配器模式。如axios抹平了web和node環境下api的調用差異、React的高階組件等。適配器不會去改變實現層,那不屬于它的職責范圍,它干涉了抽象的過程。外部接口的適配能夠讓同一個方法適用于多種系統。
適配器模式主要用來解決兩個已有接口之間不匹配的問題,它不考慮這些接口是怎樣實 現的,也不考慮它們將來可能會如何演化。適配器模式不需要改變已有的接口,就能夠 使它們協同作用。
代理,顧名思義就是幫助別人做事,GoF對代理模式的定義如下:
代理模式(Proxy),為其他對象提供一種代理以控制對這個對象的訪問。
代理模式使得代理對象控制具體對象的引用。代理幾乎可以是任何對象:文件,資源,內存中的對象,或者是一些難以復制的東西。
// 我們來舉一個簡單的例子,假如dudu要送酸奶小妹玫瑰花,卻不知道她的聯系方式或者不好意思,想委托大叔去送這些玫瑰,
// 那大叔就是個代理(其實挺好的,可以扣幾朵給媳婦),那我們如何來做呢?
// 先聲明美女對象
var girl = function (name) {
this.name = name;
};
// 這是dudu
var dudu = function (girl) {
this.girl = girl;
this.sendGift = function (gift) {
alert("Hi " + girl.name + ", dudu送你一個禮物:" + gift);
}
};
// 大叔是代理
var proxyTom = function (girl) {
this.girl = girl;
this.sendGift = function (gift) {
(new dudu(girl)).sendGift(gift); // 替dudu送花咯
}
};
調用
var proxy = new proxyTom(new girl("酸奶小妹"));
proxy.sendGift("999朵玫瑰");
遠程代理,也就是為了一個對象在不同的地址空間提供局部代表,這樣可以隱藏一個對象存在于不同地址空間的事實,就像web service里的代理類一樣。
虛擬代理,根據需要創建開銷很大的對象,通過它來存放實例化需要很長時間的真實對象,比如瀏覽器的渲染的時候先顯示問題,
而圖片可以慢慢顯示(就是通過虛擬代理代替了真實的圖片,此時虛 擬代理保存了真實圖片的路徑和尺寸。
安全代理,用來控制真實對象訪問時的權限,一般用于對象應該有不同的訪問權限。
JavaScript設計模式(五)-發布訂閱模式
今年非常火爆的蘋果13, 非常火爆。我每天都會去亞馬遜上看看貨到沒,可他一直處在無貨狀態,如果他十年不上線,難道我要十年如一日的去看嗎。好在亞馬遜提供了一個 到貨通知 的按鈕,訂閱到貨通知后,只要健身環一到,就會發信息告訴我。
上述就是一個現實中的發布-訂閱者模式。我和其他同樣想買健身環的買家都屬于 訂閱者,我們訂閱了到貨消息,亞馬遜作為發布者,當貨物到達時會給我們發布貨物到貨信息。
發布—訂閱模式定義了一種一對多的依賴關系,讓多個觀察者對象同時監聽某一個目標對象,當這個目標對象的狀態發生變化時,會通知所有觀察者對象,使它們能夠自動更新。
實現了一個最簡單的發布—訂閱模式
例子
//發布者 亞馬遜
class Publisher() {
construct() {
this.observers = []
}
//添加訂閱者
add(oberver) {
this.observers.push(observer)
}
// 通知所有訂閱者
notify() {
this.observers.forEach((observer) => {
//調用訂閱者的函數
observer.update(this)
})
}
}
// 訂閱者類 顧客
class Observer {
constructor() {
}
update() {
console.log('Observer buy buy buy')
}
}
const cunstomer = new CunstomerObserver() //創建訂閱者:顧客
const amazon = new Publisher() / /亞馬遜
amazon.add(cunstomer) //訂閱到貨小修消息
amazon.notify() //貨物到達通知顧客
策略模式定義一族算法類,將每個算法分別封裝起來,讓它們可以互相替換。策略模式可以使算法的變化獨立于使用它們的客戶端(這里的客戶端代指使用算法的代碼)。策略模式用來解耦策略的定義、創建、使用。實際上,一個完整的策略模式就是由這三個部分組成的。
策略類的定義比較簡單,包含一個策略接口和一組實現這個接口的策略類。策略的創建由工廠類來完成,封裝策略創建的細節。策略模式包含一組策略可選,客戶端代碼選擇使用哪個策略,有兩種確定方法:編譯時靜態確定和運行時動態確定。其中,“運行時動態確定”才是策略模式最典型的應用場景。
大家看這段代碼可以看見這里有一堆的if,隨著組件的增多if變得龐大難以維護。通過今天的策略模式我們的代碼可以大瘦身!
調用
function initNewDataList (avaliable = []) {
avaliable.forEach( (item, index) => {
if (item.type === 'singleBanner') {
//加載組件
}
if (item.type === 'groupBanner') {
//加載組件
}
if (item.type === 'tab') {
//加載組件
}
})
}
改造
function singleBannerFunc (item,index) {
//加載組件
}
function groupBannerFunc (item,index) {
// 加載組件
}
function tabFunc (item,index) {
// 加載組件
}
function initNewDataList (avaliable = []) {
avaliable.forEach( (item, index) =>
{
if (item.type === 'singleBanner') {
singleBannerFunc()
}
if (item.type === 'groupBanner') {
groupBannerFunc()
}
if (item.type === 'tab') {
tabFunc()
}
})
}
總結
策略模式利用組合、委托和多態等技術和思想,可以有效地避免多重條件選擇語句。
優點
缺點:
使用策略模式會在程序中增加許多策略類或者策略對象,但實際上這比把它們負責的 邏輯堆砌在 Context 中要好。
為子系統中的一組接口提供一個一致的界面,定義一個高層接口,這個接口使子系統更加容易使用
可以通過請求外觀接口來達到訪問子系統,也可以選擇越過外觀來直接訪問子系統
外觀模式在JS中,可以認為是一組函數的集合
調用
// 三個處理函數
function start() {
console.log('start');
}
function doing() {
console.log('doing');
}
function end() {
console.log('end');
}
// 外觀函數,將一些處理統一起來,方便調用
function execute() {
start();
doing();
end();
}
// 調用init開始執行
function init() {
// 此處直接調用了高層函數,也可以選擇越過它直接調用相關的函數
execute();
}
init(); // start doing end
多態
熟悉java的朋友知道,java三大特征之一就有多態,多態給java帶來了很大的靈活性,很多設計模式也是通過多態來實現,java中的多態涉及到向上轉型和向下轉型,而javascript(以下簡稱js)的"多態"就相對來說容易實現
我們來看一段“多態”的js代碼
多態就是可以讓函數一個函數根據不同的傳參有不同的返回值或者不同的執行過程,讓函數更加靈活!!!
JS中可以根據argumengts的特性進行 同一函數返回不同的值或者不同的執行過程實現多態模式!
示例代碼
<script>
function Person() {
this.test1 = function () {
if (arguments.length == 1) {
this.show1(arguments[0]);
} else if (arguments.length == 2) {
this.show2(arguments[0], arguments[1]);
} else if (arguments.length == 3) {
this.show3(arguments[0], arguments[1], arguments[2]);
}
};
this.show1 = function (a) {
window.alert("show1()被調用" + a);
};
this.show2 = function (a, b) {
window.alert("show2()被調用" + "--" + a + "--" + b);
};
function show3(a, b, c) {
window.alert("show3()被調用");
}
}
var p1 = new Person();
p1.test1("a", "b");
p1.test1("a");
</script>
迭代器模式也叫游標模式,它用來遍歷集合對象。這里說的“集合對象”,我們也可以叫“容器”“聚合對象”,實際上就是包含一組對象的對象,比如,數組、鏈表、樹、圖、跳表。迭代器模式主要作用是解耦容器代碼和遍歷代碼。大部分編程語言都提供了現成的迭代器可以使用,我們不需要從零開始開發。
迭代器模式**:指提供一種方法順序訪問一個聚合對象中的各個元素,而又不需要暴露該對象的內部表示。
// jQuery 中的迭代器模式
$.each([1, 2, 3], function(i, n) {
console.log('當前下標為:' + i)
console.log('當前的值為:' + n)
})
外部迭代器
const Iterator = function(obj) {
let current = 0;
const next = function() {
current += 1
}
const isDone = function() {
return current >= obj.length
}
const getCurrentItem = function() {
return obj[ current ]
}
return {
next,
isDone,
getCurrentItem,
length: obj.length
}
}
// 比較兩個數組的元素是否相等
const compare = function(iterator1, iterator2) {
if (iterator1.length !== iterator2.length) return false
whilte(!iterator1.isDone() && !iterator2.isDone()) {
if (iterator1.getCurrentItem() !== iterator2.getCurrentItem()) return false
// 迭代
iterator1.next()
iterator2.next()
}
// 相等
return true
}
迭代器模式是一種相對簡單的模式,簡單到很多時候我們都不認為它是一種設計模式。大部分語言都內置有迭代器模式。
總結
設計模式是為了可復用、可拓展、高性能軟件,前人給我們總結的寶貴經驗。
設計模式(Design Pattern)是前輩們對代碼開發經驗的總結,是解決特定問題的一系列套路。它不是語法規定,而是一套用來提高代碼可復用性、可維護性、可讀性、穩健性以及安全性的解決方案。
當然,軟件設計模式只是一個引導,在實際的軟件開發中,必須根據具體的需求來選擇
發布—訂閱模式的優點: 時間上的解耦,對象之間的解耦
*請認真填寫需求信息,我們會在24小時內與您取得聯系。