国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

360前端星學習筆記-如何寫‘好’JavaScript

arashicage / 2412人閱讀

摘要:前言如何寫好這門課是由技術專家月影老師講的。控制流設計原則為什么要用到事件機制呢因為要降低結構之間的耦合度,如果不這樣做的話,我們需要做雙向的操控的。

前言

《如何寫‘好’javascript》這門課是由360技術專家月影老師講的。

這堂課的ppt

說實話,我一直在糾結要不要寫關于js的文章,因為對于js來說,我的實際經驗不足,更不要說面向對象編程與函數式編程了,對于過程抽象與行為抽象也沒有深入的理解,但想想還是覺得應該分享出來,并且我盡量原汁原味的闡述這門課的內容,盡量不加入自己主觀理解,因為對于沒有實際經驗的我來說,如果添加自己主觀的理解只能誤導讀者,好了,不費話了~

一、關燈吃面

需求:

點擊紅色按鈕

背景變成黑色

字體color由黑色變成白色

紅色按鈕變成綠色

1.1 版本1
light.onclick = function(evt) {
  if(light.style.backgroundColor !== "green"){
    document.body.style.backgroundColor = "#000";
    document.body.style.color = "#fff";
    light.style.backgroundColor = "green";
  }else{
    document.body.style.backgroundColor = "";
    document.body.style.color = "";
    light.style.backgroundColor = "";    
  }
}

對于我來說,要是讓我完成這個需求,大概應該就寫成這樣吧^_^,

想想這樣寫好不好呢?

答案肯定是不好的。

這樣寫的問題:

用js直接去修改了元素的樣式。

并且代碼只能看出修改了一些元素的樣式,看不出這坨代碼需要完成哪些需求。

假設:如果以后想改需求了,比如開燈時字體變為紅色,或者需要添加一些功能,那我就得去重新看代碼,去改這一坨代碼,這樣的話,維護起來就非常難。

1.2 版本2:
lightButton.onclick = function(evt) {
  if(main.className === "light-on"){
    main.className = "light-off";
  }else{
    main.className = "light-on";
  }
}

這回代碼語義化就比較強了,通過js去修改className而不是用js來直接修改style,這樣寫會比較好一點。

1.3 版本3:其他思路

    今天回到家,
    煮了點面吃,
    一邊吃面一邊哭,
    淚水滴落在碗里,
    沒有開燈。
    

這么寫的思路就是不使用js,而是通過input和label關聯來切換狀態。

二、復雜的UI組件的設計

這是大家最熟悉不過的輪播圖組件了,如果用面向過程的寫法,可能會出現很多bug,那么如何實現才是最好的呢?

2.1 步驟1:整體思路

整體思路

圖片結構是一個列表型結構,所以主體用

  • 使用 css 絕對定位將圖片重疊在同一個位置

    輪播圖切換的狀態使用修飾符(modifier)

    輪播圖的切換動畫使用 css transition

    2.2 步驟2: API設計

    具體實現:

    class Slider{
      constructor(id){
        this.container = document.getElementById(id);
        this.items = this.container.querySelectorAll(".slider-list__item, .slider-list__item--selected");
      }
      // 獲得當前元素
      getSelectedItem(){
        const selected = this.container.querySelector(".slider-list__item--selected");
        return selected
      }
      // 獲得當前元素的索引
      getSelectedItemIndex(){
        return Array.from(this.items).indexOf(this.getSelectedItem());
      }
      // 切換到第index張圖片
      slideTo(idx){
        const selected = this.getSelectedItem();
        if(selected){ 
          selected.className = "slider-list__item";
        }
        const item = this.items[idx];
        if(item){
          item.className = "slider-list__item--selected";
        }
      }
      // 切換到下一張圖片
      slideNext(){
        const currentIdx = this.getSelectedItemIndex();
        const nextIdx = (currentIdx + 1) % this.items.length;
        this.slideTo(nextIdx);
      }
      // 切換到上一張圖片
      slidePrevious(){
        const currentIdx = this.getSelectedItemIndex();
        const previousIdx = (this.items.length + currentIdx - 1) % this.items.length;
        this.slideTo(previousIdx);  
      }
    }
    // 通過new來實例化
    const slider = new Slider("my-slider");
    setInterval(() => {
      slider.slideNext()
    }, 3000)
    2.3 步驟3:控制流設計 (下方小圓點與左右按鈕設計)

    控制結構

    
    
    

    自定義事件

        const detail = {index: idx}
        const event = new CustomEvent("slide", {bubbles:true, detail})
        this.container.dispatchEvent(event)

    因為下方原點與圖片自動切換的下標(index)是一致的,所以可以通過事件機制,在圖片slide時候直接給container派發一個事件,這樣的話呢,通過container去監聽這個事件,去更新控制結構上小圓點的狀態。

    具體實現:

    class Slider{
      constructor(id, cycle = 3000){
        this.container = document.getElementById(id);
        this.items = this.container.querySelectorAll(".slider-list__item, .slider-list__item--selected");
        this.cycle = cycle;
    
        const controller = this.container.querySelector(".slide-list__control");
        if(controller){
          const buttons = controller.querySelectorAll(".slide-list__control-buttons, .slide-list__control-buttons--selected");
          controller.addEventListener("mouseover", evt=>{
            const idx = Array.from(buttons).indexOf(evt.target);
            if(idx >= 0){
              this.slideTo(idx);
              this.stop();
            }
          });
          
          controller.addEventListener("mouseout", evt=>{
            this.start();
          });
          // 監聽slide事件
          this.container.addEventListener("slide", evt => {
            // 拿到slide事件傳來的index
            const idx = evt.detail.index
            const selected = controller.querySelector(".slide-list__control-buttons--selected");
            if(selected) selected.className = "slide-list__control-buttons";
            buttons[idx].className = "slide-list__control-buttons--selected";
          })
        }
        
        const previous = this.container.querySelector(".slide-list__previous");
        if(previous){
          previous.addEventListener("click", evt => {
            this.stop();
            this.slidePrevious();
            this.start();
            evt.preventDefault();
          });
        }
        
        const next = this.container.querySelector(".slide-list__next");
        if(next){
          next.addEventListener("click", evt => {
            this.stop();
            this.slideNext();
            this.start();
            evt.preventDefault();
          });
        }
      }
      getSelectedItem(){
        let selected = this.container.querySelector(".slider-list__item--selected");
        return selected
      }
      getSelectedItemIndex(){
        return Array.from(this.items).indexOf(this.getSelectedItem());
      }
      slideTo(idx){
        let selected = this.getSelectedItem();
        if(selected){ 
          selected.className = "slider-list__item";
        }
        let item = this.items[idx];
        if(item){
          item.className = "slider-list__item--selected";
        }
      
        const detail = {index: idx}
        const event = new CustomEvent("slide", {bubbles:true, detail})
        this.container.dispatchEvent(event)
      }
      slideNext(){
        let currentIdx = this.getSelectedItemIndex();
        let nextIdx = (currentIdx + 1) % this.items.length;
        this.slideTo(nextIdx);
      }
      slidePrevious(){
        let currentIdx = this.getSelectedItemIndex();
        let previousIdx = (this.items.length + currentIdx - 1) % this.items.length;
        this.slideTo(previousIdx);  
      }
      start(){
        this.stop();
        this._timer = setInterval(()=>this.slideNext(), this.cycle);
      }
      stop(){
        clearInterval(this._timer);
      }
    }
    
    const slider = new Slider("my-slider");
    slider.start();

    這個實現的構造函數會復雜一些,但是把timer定時器也封裝進去了,會有輪播的時間默認為3秒鐘,同樣的也是獲得container,items,cycle(時間)通過事件機制將控制流中的小圓點與圖片聯動起來。并且還判斷了controler是否存在,假如以后我們不需要小圓點這個功能了,我們只需要把html中相關的結構去掉,js也不會報錯,但是這里還有一個優化的點就是slider與controler之間有著比較強的耦合度。

    2.4 控制流設計原則

    為什么要用到事件機制呢?因為要降低結構之間的耦合度,如果不這樣做的話,我們需要做雙向的操控的。

    舉個栗子

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/108041.html

相關文章

  • 360前端學習筆記-HTML

    摘要:前端與一枚大三學生,非常感謝前端星計劃,在這里學習了很多,非常幸運獲得的校招實習,非常感謝面試我的王峰老師和盧岳文老師總的來說,這天的學習,讓我堅定了走前端這條路。使用在模式下可以使元素水平居中,但在模式下卻會失效。 前端與HTML 一枚大三學生,非常感謝360前端星計劃,在這里學習了很多,非常幸運獲得360的校招實習offer~,非常感謝面試我的王峰老師和盧岳文老師!總的來說,這7天...

    kuangcaibao 評論0 收藏0
  • 360前端學習筆記-深入CSS

    摘要:深入課程鏈接一的版本規范在之前,把所有標準放在一起去管理,這樣推進起來版本升級比較難,后來在的版本中,將標準分成幾個模塊來管理。 深入CSS 課程ppt鏈接 一、CSS的版本(level) css Level 1 css Level 2(CSS2.2規范) css Level 3 Color Module Level 3 Selectors Level 3 Media Queri...

    xcold 評論0 收藏0
  • 360前端學習筆記-深入css(2)

    摘要:課程一繼承某些元素會自動繼承其父元素的計算值舉例上述代碼,標簽里的就會繼承父元素的,為。顯示繼承給設置顯示繼承根元素下所有元素除獨自設置如的都是。二初始值當向上繼承到頂點還是沒找到值的話,就需要初始值了。 課程ppt 一、css繼承 1.1 某些元素會自動繼承其父元素的計算值 舉例: This is a test of inherit. p { color: #666; ...

    William_Sang 評論0 收藏0
  • 360前端負責人月影:賽跑項目和跳水項目的金牌含量其實一樣

    摘要:不久,傳說中的月影大大進入了視線。目前擔任奇虎副總監技術委員會委員兼前端技術委員會主席,前端最大團隊奇舞團負責人,顧問。圖靈訪談我知道月影大大在前端方面特別有名,圖靈社區的好多留言也都感嘆終于有機會訪談到月影大大了。 本文僅用于學習和交流,不用于商業目的。非商業轉載請注明作譯者、出處,并保留本文的原始鏈接:http://www.ituring.com.cn/Art... 編者語 通往...

    taohonghui 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<