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

前言

在此,我不得不說移動端的兼容問題不少,而且很使人頭疼,這不,這個星期又有兩個讓我逮着了,一個是使用zepto過程當中出現的問題,一個是ios虛擬鍵盤的問題html

我這裏作一次記錄,以避免之後忘了,同時但願對後面作移動開發的朋友有必定幫助,首先,咱們調一個簡單的來講node

zepto與querySelectorAll

首先,W3C提供了新的查詢接口,querySelector與querySelectorAllios

其中querySelector返回的是一個對象選擇第一個對象,querySelectorAll返回的一個集合(NodeList)web

以百度首頁來講,會出現這樣的現象:ajax

其餘地方可能還會說道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實現是有問題的,可是咱們暫時不關注他app

由於,咱們的項目是單頁應用,因此不可避免的,view與view之間可能出現id重複,這個時候使用zepto的選擇器會不會遇到問題呢?dom

var el = $('#el')//獲取元素
var node = el.find('......')

答案固然是會的,而且是在IOS7下面會遇到問題,不得不說喬幫主一死,丐幫墮落了......測試

前段時間Arron作過一個研究this

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的狀況下

可是,彈出鍵盤仍是得知足以上狀況,缺一不可

結語

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

相關文章
相關標籤/搜索