ftlabs / fastclick

Polyfill to remove click delays on browsers with touch UIs
MIT License
18.66k stars 3.23k forks source link

Since <Label> and <Button> can contains child elements, those child elements should be `needsclick` #460

Open UncleBill opened 8 years ago

UncleBill commented 8 years ago

Code should show my idea:

-       return (/\bneedsclick\b/).test(target.className);
+       return (/\bneedsclick\b/).test(target.className) || inLabelOrButton(target);
    };

+    function inLabelOrButton(ele) {
+        var e = ele;
+        var p = ele;
+        var tagname;
+        while(p.parentElement) {
+            tagName = p.parentElement.tagName.toLowerCase();
+            if (tagName == 'label' || tagName == 'button') {
+                return true;
+            }
+            p = p.parentElement;
+        }
+        return false;
+    }
+
UncleBill commented 8 years ago

I use Label to wrap radio box, to trigger checking by clicking on Label:

<ul class="cells" id="issueTypeList">
    <li class="cell-row">
        <label class="cell">
            <div class="cell-body ">issue 1</div>
            <div class="cell-foot">
                <input type="radio" class="cell-radio" name='tmpname' />
            </div>
        </label>
    </li>
    <li class="cell-row">
        <label class="cell">
            <div class="cell-body ">
                issue 2
            </div>
            <div class="cell-foot">
                <input type="radio" class="cell-radio" name='tmpname' />
            </div>
        </label>
    </li>
</ul>

But it doesnt' work on iOS (tested on iOS 9 device and Chrome iOS {8,9} Emulation , so far). So I set breakpoint in fastclick's source code: image You can see that the target is not label.cell but div.cell-body. However it's label.cell on Android Emulation. Then I add needsclick class to div.cell-body, it works properly. And I came with an idea: we can check if target is wrapped by Label (Button, too).

UncleBill commented 8 years ago

Just update the patch.

-       return (/\bneedsclick\b/).test(target.className);
+       return (/\bneedsclick\b/).test(target.className) || parentNeedsClick(target);
    };

+    function parentNeedsClick(ele) {
+        if (deviceIsAndroid) {
+            return false;
+        }
+        var p = ele;
+        var tagName;
+        while(p.parentElement) {
+            tagName = p.parentElement.tagName.toLowerCase();
+            if (tagName == 'label' || tagName == 'button') {
+                console.log('yes');
+                return true;
+            }
+            p = p.parentElement;
+        }
+        return false;
+    }
+
UncleBill commented 8 years ago

You can see that the target is not label.cell but div.cell-body (iOS). However it's label.cell on Android Emulation.

Please ignore the patch. I think this is a bug.