Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
<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都是用來選擇元素,以便進(jìn)行CSS操作或者JavaScript操作。
一、ID屬性
我們知道id屬性具有唯一性,也就是說同一個id在一個頁面中只能出現(xiàn)一次,如果出現(xiàn)多次相同的id,那么CSS或JavaScript就無法識別id對應(yīng)的是哪一個元素了。
二、class屬性
class,顧名思義就是“類”,與C++,C#等編程語言中的“類”相似,我們可以為同一個頁面的相同元素或者不同元素設(shè)置相同的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>
預(yù)覽效果
五、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的元素進(jìn)行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>
七、后代選擇器
定義:
就是選擇元素內(nèi)部中所有的某一種元素,包括子元素和其他后代元素。
語法:
h3 p{width:100px}
h3是選擇器1,p是選擇器2,width是屬性,100px是屬性值
舉例:
id為abc的元素,下面所有的idv元素,定義文本顏色為紅色。
id為efg 的元素,下面所有的span元素,定義文本為藍(lán)色
<!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>
八、群組選擇器
群組選擇器,指的是同時對幾個選擇器進(jìn)行操作
語法:
h3,p{width:100px;}
h3選擇器1 中間必須帶(,)隔開,p為選擇器2,width數(shù)學(xué),100px屬性值
舉例:
把元素div,p中的元素,文本屬性設(shè)置成紅色
022年已接近尾聲,又到了每年發(fā)布大版本的時候,Tpflow歷經(jīng)一個多月的意見征集及版本優(yōu)化,從底層改進(jìn),從UI調(diào)整,增強(qiáng)了事件功能。
發(fā)布日期:2022年12月23日
發(fā)布版號:V7.0.0
更新內(nèi)容如下:
基于<AntV X6> 圖形引擎再度深化
整合css資源,調(diào)整att屬性設(shè)置,刪除workflow.css
兼容最新PHP8.1版本
優(yōu)化<Event>流程事件處理模型
增加流程版本
增加流程圖
計模式(Design pattern) 是解決軟件開發(fā)某些特定問題而提出的一些解決方案也可以理解成解決問題的一些思路。通過設(shè)計模式可以幫助我們增強(qiáng)代碼的可重用性、可擴(kuò)充性、 可維護(hù)性、靈活性好。我們使用設(shè)計模式最終的目的是實(shí)現(xiàn)代碼的 高內(nèi)聚 和 低耦合。通俗一點(diǎn)講的話 打比方面試官經(jīng)常會問你如何讓代碼有健壯性。其實(shí)把代碼中的變與不變分離,確保變化的部分靈活、不變的部分穩(wěn)定,這樣的封裝變化就是代碼健壯性的關(guān)鍵。而設(shè)計模式的出現(xiàn),就是幫我們寫出這樣的代碼。 設(shè)計模式就是解決編程里某類問題的通用模板,總結(jié)出來的代碼套路就是設(shè)計模式。本文章總結(jié)下JS在工作中常用的設(shè)計模式 ,以幫助大家提高代碼性能,增強(qiáng)工作效率!
圣誕節(jié)要到了,許多家庭會買一顆松樹裝上彩燈,一閃一閃亮晶晶然后搖身一變成了圣誕樹。這里 的彩燈就是裝飾器,他不會對松樹原有的功能產(chǎn)生影響。(還是本來的樹)
這種給對象動態(tài)地增加職責(zé)的方式稱為裝 飾器(decorator)模式。裝飾器模式能夠在不改 變對象自身的基礎(chǔ)上,在程序運(yùn)行期間給對象 動態(tài)地添加職責(zé)。
應(yīng)用
當(dāng)我們接手老代碼時,需要對它已有的功能做個拓展。
``
var horribleCode = function(){
console.log(’我是一堆你看不懂的老邏輯')
}
// 改成:
var horribleCode = function(){
console.log('我是一堆你看不懂的老邏輯')
console.log('我是新的邏輯')
}
這樣做有很多的問題。直接去修改已有的函數(shù)體,違背了我們的“開放封閉原則”;往一個函數(shù)體里塞這么多邏輯,違背了我們的“單一職責(zé)原則”。
為了不被已有的業(yè)務(wù)邏輯干擾,將舊邏輯與新邏輯分離,把舊邏輯抽出去:
var horribleCode = function(){
console.log(’我是一堆你看不懂的老邏輯')
}
var _horribleCode = horribleCode
horribleCode = function() {
_horribleCode()
console.log('我是新的邏輯')
}
horribleCode()
這樣就完成了舊代碼的運(yùn)用 以及新代碼的無傷添加了!!!
先來理解一個概念 —— 構(gòu)造器模式
你開了家動物園,只有兩只動物,你可能會這樣錄入系統(tǒng):
const monkey = {
name: '悟空',
age: '1'
}
const tiger = {
name: '泰格伍茲',
age: '3'
}
如果你的動物越來越多,對象字面量也會越來越多,這個時候構(gòu)造函數(shù)可以自動創(chuàng)建動物對象
this.name = name
this.age = age
}
const animal = new Animal(name, age) //Animal 就是一個構(gòu)造器
像 Animal 這樣當(dāng)新建對象的內(nèi)存被分配后,用來初始化該對象的特殊函數(shù),就叫做構(gòu)造器。在 JavaScript 中,我們使用構(gòu)造函數(shù)去初始化對象,就是應(yīng)用了構(gòu)造器模式。
可以看出每個實(shí)例化后 對象( animal )屬性的key (name,age) 是不變的,對應(yīng)的value(空空,泰格伍茲)是變的。所以構(gòu)造器將賦值過程封裝,確保了每個對象屬性固定,開放了取值確保個性靈活。
簡單工廠模式
動物園要求根據(jù)每個動物的食性喜好來分配不同的食物。這樣之前封裝的Animal 就不能直接用了,我們重新封裝的構(gòu)造器。
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]
}
根據(jù)喜好可以分配相應(yīng)的
function Factory(name, age, favorite) {
switch(career) {
case 'fruit':
return new Vegetarian(name, age)
break
case 'meat':
return new Carnivore(name, age)
break
...
}
總結(jié)
工廠模式:將創(chuàng)建對象的過程單獨(dú)封裝。
應(yīng)用場景:有構(gòu)造函數(shù)的地方、寫了大量的構(gòu)造函數(shù)、調(diào)用了大量的 new的情況下
單例模式
保證僅有一個實(shí)例,并提供一個訪問它的全局訪問點(diǎn),這樣的模式就叫做單例模式。然后性能得到優(yōu)化!
以下代碼我們做一個彈窗 如果實(shí)例已經(jīng)創(chuàng)建過 就無需再次創(chuàng)建 這就是單例!
<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){
// 每次顯示之前先判斷是否已經(jīng)存在彈出框元素,如果不存在就創(chuàng)建,如果已經(jīng)存在就不用重新創(chuàng)建,只需要修改樣式和顯示即可
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>
總結(jié)
優(yōu)點(diǎn):適用于單一對象,只生成一個對象實(shí)例,避免頻繁創(chuàng)建和銷毀實(shí)例,減少內(nèi)存占用。
缺點(diǎn):不適用動態(tài)擴(kuò)展對象,或需創(chuàng)建多個相似對象的場景。
JavaScript設(shè)計模式(四)-適配器模式
當(dāng)電腦需要外接顯示器的時候,我們都會用到下面這個東西。轉(zhuǎn)換器幫助我們在不用更改筆記本接口的同時可以適配HDMI。
將轉(zhuǎn)換器抽象到代碼層面就是今天要介紹的適配器了。
適配器模式的作用是解決兩個軟件實(shí)體間的接口不兼容的問題。使用適配器模式之后,原本 由于接口不兼容而不能工作的兩個軟件實(shí)體可以一起工作。
應(yīng)用舉例: 點(diǎn)外賣的時候有美團(tuán),餓了么可以選擇,同一家店如果要對比兩個平臺的價格來回切換App十分不方便,作為一個Coder能用代碼解決的堅決不用人力。這個時候我們就想到寫個小應(yīng)用對比兩家的價格。
在他們openapi里找到了對應(yīng)的方法,發(fā)現(xiàn)請求不一樣,入?yún)⒉灰粯樱祷氐臄?shù)據(jù)結(jié)構(gòu)也不一樣。翻譯成偽代碼就是如下的狀態(tài)
class Eleme() {
getElePice() {
console.log('在餓了么上商品的價格')
return {elePrice:xx}
}
}
class Meituan() {
getMeiPice() {
console.log('在美團(tuán)上商品的價格')
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}
}
}
//通過適配器拿到的數(shù)據(jù)格式都是統(tǒng)一的 {price:xx}
//同樣,入?yún)⒁部梢栽谶m配器中統(tǒng)一處理
雖然這種模式很簡單,但還有很多場景運(yùn)用到了適配器模式。如axios抹平了web和node環(huán)境下api的調(diào)用差異、React的高階組件等。適配器不會去改變實(shí)現(xiàn)層,那不屬于它的職責(zé)范圍,它干涉了抽象的過程。外部接口的適配能夠讓同一個方法適用于多種系統(tǒng)。
適配器模式主要用來解決兩個已有接口之間不匹配的問題,它不考慮這些接口是怎樣實(shí) 現(xiàn)的,也不考慮它們將來可能會如何演化。適配器模式不需要改變已有的接口,就能夠 使它們協(xié)同作用。
代理,顧名思義就是幫助別人做事,GoF對代理模式的定義如下:
代理模式(Proxy),為其他對象提供一種代理以控制對這個對象的訪問。
代理模式使得代理對象控制具體對象的引用。代理幾乎可以是任何對象:文件,資源,內(nèi)存中的對象,或者是一些難以復(fù)制的東西。
// 我們來舉一個簡單的例子,假如dudu要送酸奶小妹玫瑰花,卻不知道她的聯(lián)系方式或者不好意思,想委托大叔去送這些玫瑰,
// 那大叔就是個代理(其實(shí)挺好的,可以扣幾朵給媳婦),那我們?nèi)绾蝸碜瞿兀?
// 先聲明美女對象
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送花咯
}
};
調(diào)用
var proxy = new proxyTom(new girl("酸奶小妹"));
proxy.sendGift("999朵玫瑰");
遠(yuǎn)程代理,也就是為了一個對象在不同的地址空間提供局部代表,這樣可以隱藏一個對象存在于不同地址空間的事實(shí),就像web service里的代理類一樣。
虛擬代理,根據(jù)需要創(chuàng)建開銷很大的對象,通過它來存放實(shí)例化需要很長時間的真實(shí)對象,比如瀏覽器的渲染的時候先顯示問題,
而圖片可以慢慢顯示(就是通過虛擬代理代替了真實(shí)的圖片,此時虛 擬代理保存了真實(shí)圖片的路徑和尺寸。
安全代理,用來控制真實(shí)對象訪問時的權(quán)限,一般用于對象應(yīng)該有不同的訪問權(quán)限。
JavaScript設(shè)計模式(五)-發(fā)布訂閱模式
今年非常火爆的蘋果13, 非常火爆。我每天都會去亞馬遜上看看貨到?jīng)],可他一直處在無貨狀態(tài),如果他十年不上線,難道我要十年如一日的去看嗎。好在亞馬遜提供了一個 到貨通知 的按鈕,訂閱到貨通知后,只要健身環(huán)一到,就會發(fā)信息告訴我。
上述就是一個現(xiàn)實(shí)中的發(fā)布-訂閱者模式。我和其他同樣想買健身環(huán)的買家都屬于 訂閱者,我們訂閱了到貨消息,亞馬遜作為發(fā)布者,當(dāng)貨物到達(dá)時會給我們發(fā)布貨物到貨信息。
發(fā)布—訂閱模式定義了一種一對多的依賴關(guān)系,讓多個觀察者對象同時監(jiān)聽某一個目標(biāo)對象,當(dāng)這個目標(biāo)對象的狀態(tài)發(fā)生變化時,會通知所有觀察者對象,使它們能夠自動更新。
實(shí)現(xiàn)了一個最簡單的發(fā)布—訂閱模式
例子
//發(fā)布者 亞馬遜
class Publisher() {
construct() {
this.observers = []
}
//添加訂閱者
add(oberver) {
this.observers.push(observer)
}
// 通知所有訂閱者
notify() {
this.observers.forEach((observer) => {
//調(diào)用訂閱者的函數(shù)
observer.update(this)
})
}
}
// 訂閱者類 顧客
class Observer {
constructor() {
}
update() {
console.log('Observer buy buy buy')
}
}
const cunstomer = new CunstomerObserver() //創(chuàng)建訂閱者:顧客
const amazon = new Publisher() / /亞馬遜
amazon.add(cunstomer) //訂閱到貨小修消息
amazon.notify() //貨物到達(dá)通知顧客
策略模式定義一族算法類,將每個算法分別封裝起來,讓它們可以互相替換。策略模式可以使算法的變化獨(dú)立于使用它們的客戶端(這里的客戶端代指使用算法的代碼)。策略模式用來解耦策略的定義、創(chuàng)建、使用。實(shí)際上,一個完整的策略模式就是由這三個部分組成的。
策略類的定義比較簡單,包含一個策略接口和一組實(shí)現(xiàn)這個接口的策略類。策略的創(chuàng)建由工廠類來完成,封裝策略創(chuàng)建的細(xì)節(jié)。策略模式包含一組策略可選,客戶端代碼選擇使用哪個策略,有兩種確定方法:編譯時靜態(tài)確定和運(yùn)行時動態(tài)確定。其中,“運(yùn)行時動態(tài)確定”才是策略模式最典型的應(yīng)用場景。
大家看這段代碼可以看見這里有一堆的if,隨著組件的增多if變得龐大難以維護(hù)。通過今天的策略模式我們的代碼可以大瘦身!
調(diào)用
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()
}
})
}
總結(jié)
策略模式利用組合、委托和多態(tài)等技術(shù)和思想,可以有效地避免多重條件選擇語句。
優(yōu)點(diǎn)
缺點(diǎn):
使用策略模式會在程序中增加許多策略類或者策略對象,但實(shí)際上這比把它們負(fù)責(zé)的 邏輯堆砌在 Context 中要好。
為子系統(tǒng)中的一組接口提供一個一致的界面,定義一個高層接口,這個接口使子系統(tǒng)更加容易使用
可以通過請求外觀接口來達(dá)到訪問子系統(tǒng),也可以選擇越過外觀來直接訪問子系統(tǒng)
外觀模式在JS中,可以認(rèn)為是一組函數(shù)的集合
調(diào)用
// 三個處理函數(shù)
function start() {
console.log('start');
}
function doing() {
console.log('doing');
}
function end() {
console.log('end');
}
// 外觀函數(shù),將一些處理統(tǒng)一起來,方便調(diào)用
function execute() {
start();
doing();
end();
}
// 調(diào)用init開始執(zhí)行
function init() {
// 此處直接調(diào)用了高層函數(shù),也可以選擇越過它直接調(diào)用相關(guān)的函數(shù)
execute();
}
init(); // start doing end
多態(tài)
熟悉java的朋友知道,java三大特征之一就有多態(tài),多態(tài)給java帶來了很大的靈活性,很多設(shè)計模式也是通過多態(tài)來實(shí)現(xiàn),java中的多態(tài)涉及到向上轉(zhuǎn)型和向下轉(zhuǎn)型,而javascript(以下簡稱js)的"多態(tài)"就相對來說容易實(shí)現(xiàn)
我們來看一段“多態(tài)”的js代碼
多態(tài)就是可以讓函數(shù)一個函數(shù)根據(jù)不同的傳參有不同的返回值或者不同的執(zhí)行過程,讓函數(shù)更加靈活!!!
JS中可以根據(jù)argumengts的特性進(jìn)行 同一函數(shù)返回不同的值或者不同的執(zhí)行過程實(shí)現(xiàn)多態(tài)模式!
示例代碼
<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()被調(diào)用" + a);
};
this.show2 = function (a, b) {
window.alert("show2()被調(diào)用" + "--" + a + "--" + b);
};
function show3(a, b, c) {
window.alert("show3()被調(diào)用");
}
}
var p1 = new Person();
p1.test1("a", "b");
p1.test1("a");
</script>
迭代器模式也叫游標(biāo)模式,它用來遍歷集合對象。這里說的“集合對象”,我們也可以叫“容器”“聚合對象”,實(shí)際上就是包含一組對象的對象,比如,數(shù)組、鏈表、樹、圖、跳表。迭代器模式主要作用是解耦容器代碼和遍歷代碼。大部分編程語言都提供了現(xiàn)成的迭代器可以使用,我們不需要從零開始開發(fā)。
迭代器模式**:指提供一種方法順序訪問一個聚合對象中的各個元素,而又不需要暴露該對象的內(nèi)部表示。
// jQuery 中的迭代器模式
$.each([1, 2, 3], function(i, n) {
console.log('當(dāng)前下標(biāo)為:' + i)
console.log('當(dāng)前的值為:' + 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
}
}
// 比較兩個數(shù)組的元素是否相等
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
}
迭代器模式是一種相對簡單的模式,簡單到很多時候我們都不認(rèn)為它是一種設(shè)計模式。大部分語言都內(nèi)置有迭代器模式。
總結(jié)
設(shè)計模式是為了可復(fù)用、可拓展、高性能軟件,前人給我們總結(jié)的寶貴經(jīng)驗(yàn)。
設(shè)計模式(Design Pattern)是前輩們對代碼開發(fā)經(jīng)驗(yàn)的總結(jié),是解決特定問題的一系列套路。它不是語法規(guī)定,而是一套用來提高代碼可復(fù)用性、可維護(hù)性、可讀性、穩(wěn)健性以及安全性的解決方案。
當(dāng)然,軟件設(shè)計模式只是一個引導(dǎo),在實(shí)際的軟件開發(fā)中,必須根據(jù)具體的需求來選擇
發(fā)布—訂閱模式的優(yōu)點(diǎn): 時間上的解耦,對象之間的解耦
*請認(rèn)真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。