【小貼士】zepto find元素以及ios彈出鍵盤可能讓你很頭疼


前言

在此,我不得不說移動端的兼容問題很多,並且很令人頭疼,這不,這個星期又有兩個讓我逮着了,一個是使用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的情況下

但是,彈出鍵盤還是得滿足以上情況,缺一不可

結語

今天沒有用公司的電腦,狀態不好,暫時到此


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM