最近做了個項目,其中有項目需求是要實現跑馬燈抽獎效果,實現此功能主要用到js相關知識,廢話不多說,有興趣的朋友可以閱讀下全文。
開始之前先來看上篇文章遺漏的兩個問題和幾個知識點,是自己重構的過程中需要用到的:
1.行動端1px像素線的問題
對於設計師給我的手機端網頁的設計稿都是2倍圖。照道理來說,在寫網頁的時候,所有物件的實際尺寸都是會除2。但是對於1像素的線呢?
先來看兩張圖,設計稿的效果:
在三星 S4下的實際顯示效果:
可以看到這個時候1px的線竟然顯示不出來了。這個問題是跟 S4手機的螢幕像素密度有關。關於螢幕像素密度和1px 線的關係有很多文章介紹,可以自行搜尋了解。我這裡的解決方案是,對1px 的線不做處理。是多少就寫多少。就算我的基礎單位是rem,也不是其它單位。
{ position: absolute; width: 13rem; height: 9.2rem; border:1px solid #000; }
2.pc 端瀏覽器與行動端瀏覽器容錯率的差異
先來看一段程式碼:
$('[node-type=row-a').find('div');
很明顯可以發現,我使用的選擇器是有語法錯誤的。但是在瀏覽器中運行會有什麼結果呢?看下圖:
很明顯可以看出對於屬性選擇器,就算我有語法錯誤,PC 端瀏覽器也是可以正確解析的。但是在手機端,這種寫法是無法正確解析,程式碼不能夠運作。
所以寫程式的時候一定要注意一些小細節哈。 。 。
3.jQuery中選擇器的使用
在使用 jQuery 或是 Zepto 的過程中最常使用的選擇器的寫法就是下面這樣吧,
$('div.testClass')
只是在$() 寫上自己需要的 Dom 節點的 class或 ID 或 者使用屬性選擇器。
在查看 jQuery的文檔,對於$()會有這樣的描述:
jQuery([selector,[context]])
最重要的是看看對 context (它也是我們平時使用中最容易忽略,但是卻非常有用的一個參數)的描述:
預設情況下, 如果沒有指定context參數,$()將在當前的HTML document中查找DOM 元素;如果指定了context 參數,如一個DOM 元素集或jQuery 對象,那就會在這個context 中查找。在jQuery 1.3.2以後,其傳回的元素順序等同於在context中出現的先後順序。
剛開始學習 JavaScript 那會兒,就聽說了操作 DOM 是很損耗瀏覽器效能,遍歷 DOM 也是很影響程式效能的。
如果我們在指定的範圍內尋找需要的 Dom 會不會比從整個document 中尋找快很多。而且在我們寫 web 元件的過程中,一個頁面上元件可能出現很多次,那我們怎麼判斷我們要操作哪個元件呢?這個context參數就會起到決定行的作用。具體請繼續看哇。 。 。
4.jQuery物件到陣列的轉換
剛開始學習 jQuery的時候在一本書上看到一句話:
jQuery物件就是一個 JavaScript 陣列。
而且在使用 jQuery的過程中,都會遇到,js物件轉 jQuery對象,jQuery物件轉 js物件。關於這些基礎不做過多介紹。
但是有時候我們會想在 jQuery物件上運用一些原生Array物件的方法或屬性。來看一個簡單的例子:
由圖中的程式碼執行結果,可以知道在 jQuery物件上是沒有我們要使用reverse方法的。儘管test是一個陣列。
那我們該怎麼辦才可以讓 jQuery物件使用原生的 Array物件的方法呢?
4.1使用原型鏈擴充
例如下面的程式碼:
jQuery.prototype.reverse=function(){ //一些操作 }
使用prototype來擴展方法的時候,大家一直比較認為是缺點的就是可能會污染已經存在的原型鏈上的方法。還有就是存取方法的時候需要找出原型鏈。
4.2將 jQuery物件中的物件加入陣列
看下面的程式碼
var test = $('div.test'); var a=[]; $(test).each(function(){ a.push($(this)); }); a.reverse();
这样就可以将 jQuery对象翻转。
4.3使用 Array对象的 from()方法
这种方法也是自己在编写插件过程中使用的方法。看一下文档描述:
Array.from() 方法可以将一个类数组对象或可迭代对象转换成真实的数组。
个人感觉使用这个代码比较简洁。暂时还不知道有没有性能的影响。继续看下面的代码:
var test = $('div.test'); var a= Array.from(test); a.reverse();
5.setInterval()和setTimeout()对程序性能的影响
因为setTimeout()和setInterval()这两个函数在 JavaScript 中的实现机制完全一样,这里只拿 setTimeout()验证
那么来看两段代码
var a ={ test:function(){ setTimeout(this.bbb,1000); }, bbb:function(){ console.log('----'); } }; a.test()
输出结果如下:
看下面的代码输出是什么
var a ={ test:function(){ setTimeout(function(){ console.log(this); this.bbb(); },1000); }, bbb:function(){ console.log('----'); } }; a.test();
运行这段代码的时候,代码报错
由以上的结果可以知道,当我们在使用setInterval()和setTimeout()的时候,在回掉中使用this的时候,this的作用域已经发生了改变,并且指向了 window。
setTimeout(fn,0)的含义是,指定某个任务在主线程最早可得的空闲时间执行,也就是说,尽可能早得执行。它在”任务队列”的尾部添加一个事件,因此要等到同步任务和”任务队列”现有的事件都处理完,才会得到执行。
意思就是说在我们设置 setTimeout()之后,也可能不是立即等待多少秒之后就立即执行回掉,而是会等待主线程的任务都处理完后再执行,所以存在 “等待”超过自己设置时间的现象。同时也会存在异步队列中已经存在了其它的 setTimeout() 也是会等待之前的都执行完再执行当前的。
看一个 Demo:
setTimeout(function bbb(){},4000); function aaa(){ setTimeout(function ccc(){},1000); } aaa();
如果运行上面的代码,当执行完 aaa() 等待一秒后并不会立即执行 ccc(),而是会等待 bbb() 执行完再执行 ccc() 这个时候离主线程运行结束已经4s 过去了。
以上内容是针对JavaScript实现跑马灯抽奖活动实例代码解析与优化(一),下篇继续给大家分享JavaScript实现跑马灯抽奖活动实例代码解析与优化(二),感兴趣的朋友敬请关注。