前言
在此,我不得不說移動端的兼容問題很多,並且很令人頭疼,這不,這個星期又有兩個讓我逮着了,一個是使用zepto過程中出現的問題,一個是ios虛擬鍵盤的問題
我這里做一次記錄,以免以后忘了,同時希望對后面做移動開發的朋友有一定幫助,首先,我們調一個簡單的來說
zepto與querySelectorAll
首先,W3C提供了新的查詢接口,querySelector與querySelectorAll
其中querySelector返回的是一個對象選擇第一個對象,querySelectorAll返回的一個集合(NodeList)
以百度首頁來說,會出現這樣的現象:

其他地方可能還會說道queryselectorAll的BUG,那些我暫且不關注,這簡單拷貝下別人的就說下我遇到的問題
1 <div id="test1"><a href="http://www.hujuntao.com/">設計蜂巢</a></div> 2 <p id="bar">111</p> 3 <script> 4 var d1 = document.getElementById('test1'), 5 obj1 = d1.querySelector('div a'), 6 obj2 = d1.querySelectorAll('div a'); 7 obj3 = $(d1).find('div a'); 8 console.log(obj1) //<a href="http://www.hujuntao.com/">設計蜂巢</a> 9 console.log(obj2.length) //1 10 console.log(obj3) //null 11 </script>
從這個例子來說,querySelectorAll實現是有問題的,但是我們暫時不關注他
因為,我們的項目是單頁應用,所以不可避免的,view與view之間可能出現id重復,這個時候使用zepto的選擇器會不會遇到問題呢?
var el = $('#el')//獲取元素 var node = el.find('......')
答案當然是會的,並且是在IOS7下面會遇到問題,不得不說喬幫主一死,丐幫墮落了......
前段時間Arron做過一個研究
var element = $('<div id = "aaron">...填充大量結構...</div>'); $(root).html(element) $('#aaron') //為空
這個是很簡單的一段代碼,按照常規的認識,JS主線程與GUI的渲染線程是互斥的,所以在執行JS的時候,GUI應該就是掛起的, 同理執行GUI的時候亦然, 因為JS可以動態操作節點,所以如果我們在GUI繪制的時候做操作明顯就會打亂了,所以互斥的解釋也合理
但是實際上這樣並不能直接獲取到$('#aaron'),PC上基本不會出現,常規的辦法都是加setTimeout
這個例子旨在說明在移動端獲取元素會出問題,這不這個星期我馬上遇到了一個問題,並且和上面的情況還不一樣呢:
在IOS7下面,View之間的切換后,如果此時操作了DOM,並且view之間有一個重復id元素,並且我們還會用到
則此時this.$el.find('#id')這個會選取到兩個元素......
PS:其中$el為backbone render時候返回的html元素,
這是一個什么問題呢?簡單來說如下:
<div id="foo"> <p id="t">This is a sample error</p> </div> <div id="foo1"> <p id="t">This is a sample error</p> </div>
var el = document.getElementById('#foo') el.querySelectorAll('#t')
這個在IOS7下有一定幾率會返回一個數組,並且里面裝的是兩個元素(意思是兩個id為t的元素都被選出來的了......)
這個就是我們遇到的一個問題,應該說這個問題很隱蔽,於是我就看了下zepto里面的實現:
1 zepto.qsa = function(element, selector){ 2 var found, 3 maybeID = selector[0] == '#', 4 maybeClass = !maybeID && selector[0] == '.', 5 nameOnly = maybeID || maybeClass ? selector.slice(1) : selector, // Ensure that a 1 char tag name still gets checked 6 isSimple = simpleSelectorRE.test(nameOnly) 7 return (isDocument(element) && isSimple && maybeID) ? 8 ( (found = element.getElementById(nameOnly)) ? [found] : [] ) : 9 (element.nodeType !== 1 && element.nodeType !== 9) ? [] : 10 slice.call( 11 isSimple && !maybeID ? 12 maybeClass ? element.getElementsByClassName(nameOnly) : // If it's simple, it could be a class 13 element.getElementsByTagName(selector) : // Or a tag 14 element.querySelectorAll(selector) // Or it's not simple, and we need to query all 15 ) 16 }
element存在的情況最后使用querySelectAll選取元素,我們這里不是dom不存在而是多選了一個dom,所以這里需要針對ios7做一個適配
1 zepto.qsa = function(element, selector){ 2 var found, 3 maybeID = selector[0] == '#', 4 maybeClass = !maybeID && selector[0] == '.', 5 nameOnly = maybeID || maybeClass ? selector.slice(1) : selector, // Ensure that a 1 char tag name still gets checked 6 isSimple = simpleSelectorRE.test(nameOnly) 7 var doms = (isDocument(element) && isSimple && maybeID) ? 8 ( (found = element.getElementById(nameOnly)) ? [found] : [] ) : 9 (element.nodeType !== 1 && element.nodeType !== 9) ? [] : 10 slice.call( 11 isSimple && !maybeID ? 12 maybeClass ? element.getElementsByClassName(nameOnly) : // If it's simple, it could be a class 13 element.getElementsByTagName(selector) : // Or a tag 14 element.querySelectorAll(selector) // Or it's not simple, and we need to query all 15 ) 16 //這里需要做判斷.......判斷邏輯自己去搞 17 var _tmp = []; 18 if(ios7 && element){ 19 for(var i = 0, len < doms.length; i < len; i++) { 20 if(element.contains(doms[i])) _tmp.push(doms[i]) 21 } 22 return _tmp; 23 } else { return doms } 24 }
這里代碼做一下處理,針對IOS7應該就沒問題了.......於是進入今天第二個話題
這里給出測試地址:http://sandbox.runjs.cn/show/w5q7inp1
手機彈出虛擬鍵盤
之前憂患深第一次出劍時候,他說了一句:你見過吾之六凡滅劍么?然后出劍
於是,在此我想問一句:你見過IOS彈不出來鍵盤么......尼瑪真的彈不出來啊!!!碰上fastclick的話更有不一樣的感覺
我們在手機上想彈出鍵盤,需要的就是讓文本框獲取焦點,文本框獲取焦點便會彈出鍵盤,但是我這里提出一個問題
彈出鍵盤==文本框獲取焦點
文本框獲取焦點!=彈出鍵盤
經過我的研究一定要這種情況下才會彈出鍵盤:
① 文本框獲取焦點
② 手指觸屏(網頁區域,混合開發觸屏app頭不能讓webview彈出鍵盤)
③ 沒有延遲(不會ajax回調,不會延遲)
我這里舉一個例子,並且此例子與fastclick還有一定關系,如果沒有關系這里就沒有意義了:
http://sandbox.runjs.cn/show/0bmobuyy
如果你使用ios訪問這個鏈接,你會發現,其中的input已經獲取了焦點,這個時候你快速的點擊文本框就不會彈出鍵盤
這個情況導致的原因就是文本框已經獲取焦點了,再去點擊就不會彈出鍵盤,當然這個情況只是在使用fastclick的情況下
但是,彈出鍵盤還是得滿足以上情況,缺一不可
結語
今天沒有用公司的電腦,狀態不好,暫時到此
