On iOS 7, <select>
menus in Mobile Safari do not fire a change event until after the user clicks "Done". Are there any other events I can listen for to know when the user's selection has changed?
<select onchange="alert('This will not fire until the user clicks Done')">
<option>1</option>
<option>2</option>
</select>
On iOS 7, <select>
menus in Mobile Safari do not fire a change event until after the user clicks "Done". Are there any other events I can listen for to know when the user's selection has changed?
<select onchange="alert('This will not fire until the user clicks Done')">
<option>1</option>
<option>2</option>
</select>
Share
Improve this question
asked May 28, 2014 at 3:40
Luke DennisLuke Dennis
14.6k17 gold badges59 silver badges69 bronze badges
2 Answers
Reset to default 13 +250There is no way to determine the new selection value before the user touches "Done".
When the user first touches the <select>
control, iOS opens a native UI for the select options. This is not DOM. And when the user touches "Done" it sends the new value/index and fires the corresponding event back on DOM.
You can test this. Just setup two events: onfocus
will setup a timer and continuously poll for selectedIndex
until onblur
destroys the timer when "Done" is touched.
<select id="my-select" onfocus="checkSelectedIndex()" onblur="selectDone()">
<option>1</option>
<option>2</option>
</select>
var timer;
// timer setup on focus
function checkSelectedIndex() {
timer = window.setInterval(function () {
console.log('selected index:', document.getElementById('my-select').selectedIndex);
}, 500); // 2 polls per second
}
// timer cleared on blur
function selectDone() {
console.log('Selection changed!');
if (!timer) { return; }
window.clearInterval(timer);
}
With this test, you'll see that even though you change the selected item on the UI; the logged index will not change until after you touch "Done" (which is when the final message is sent to DOM).
So, what you can do is; (with some UX trade off); instead of a <select>
element, create a custom control which pops up a list of options in a <div>
or <ul>
. This way, you'll NOT be triggering the native UI and the user will not leave the DOM. And you'll be able to listen to the events of the menu and clicked items.
Just make sure your control feels mobile-friendly.
Enabling Safari Web Inspector for iOS Devices:
- On iOS device, go to: Setings » Safari » Advanced and enable Web Inspector.
- On desktop Safari, go to: Preferences » Advanced and check "Show Developer menu in menu bar". A new menu item named "Develop" will be added to you Safari menu.
- Connect your iOS device to your puter via USB.
- Open the page you want to debug (an external or localhost URL).
- From the desktop Safari Develop menu, select the name of your device and then click the application name in the submenu.
Mobile Safari on iOS does not fire the change
event .
Workaround:
using both blur
and change
, you can attach a single event handler that unbinds when fired once: jQuery has $().one()
$("input[type='select']").one("blur change", function(){
//will only execute once
alert('This will fire sure and only once');
});
Note: If you need to have the function execute more than once per DOM element ever, you could re-apply it with a setTimeout
, to avoid the dual firing.