I'm using a hidden
<input id="mfile" type="file" accept="image/*">
and triggering it with a paper-fab from google's element catalog. It works everywhere except for safari on iOS, the click fires but it doesn't get redirected to the input.
By redirect i mean a on-tap listener on the fab that triggers this.$.mfile.click();
Any suggestion or workaround?
Thanks to #marx_tseng from polymer slack, here is the solution:
https://polymer.slack.com/archives/general/p1478229319019481
<paper-fab id="fileFab" label="File" on-tap="_pickFile"></paper-fab>
<input type="file" id="filePicker" hidden />
...
_pickFile: function(e) {
e.preventDefault();
this.$.fileFab.blur();
// cancelable is true, not work on ios simulator
// this.$.filePicker.click();
// default cancelable is false, work on ios simulator
try {
// fixes mobile safari
var evt = new MouseEvent("click");
this.$.filePicker.dispatchEvent(evt);
} catch (e) {
// fallback for IE11
this.$.filePicker.click();
}
}
Related
I'm using a commonly used ionic directive to set focus to a textarea on page load which shows the ionic keyboard, and it works fine on every device I've tested with except on an iPhone 4s.
HTML
<textarea focus-me></textarea>
JS
.directive('focusMe', function($timeout) {
return {
link: function(scope, element, attrs) {
$timeout(function() {
element[0].focus();
}),350;
}
};
});
On an iPhone 4s, when the textarea loses focus the keyboard disappears and then pops right back up. This doesn't happen on any other device.
How can I set focus to the textarea on page load (and subsequent page loads) and prevent the ionic keyboard from popping back up when the textarea loses focus?
There is an error in your code calling the $timeout directive. It should be:
.directive('focusMe', function($timeout) {
return {
link: function(scope, element, attrs) {
$timeout(function() {
element[0].focus();
}, 350); // correct this
}
};
});
I am using jquery mobile to close and open a menu in an app like this:
$('body').on('swipeleft', function(event){
if(menuOpen == true){
home.showMenu();
}
});
$('body').on('swiperight', function(event){
if(menuOpen == false){
home.showMenu();
}
});
And I have a input range (slider) in my menu like this:
<input id="changeRadiusRange" type="range" min="5" max="100" step="5" oninput="handleInputVal(value)" onchange="handleChangeVal(this.value)">
Now if I use my slider it stops after some time (I think the 30pixel for swipeleft/right to get fired and menu is closing if it is a swipeleft)
I already tried a few things regarding to this question, that results in this but didn't changed the behavior:
$('#changeRadiusRange').on('swipeleft swiperight', function(e){
e.stopPropagation();
e.preventDefault();
});
How can I force input behavior as normal not to be influenced by swipe-events?
I had the same problem today and found a less hacky solution.
var handleSwipe = function (event) {
// my swipe stuff
}
// regular event listening
$(document).on("swipeleft swiperight", handleSwipe);
// additional workaround
$(".slider").on("mousedown touchstart", function (event) {
// when starting to interact with a .slider, stop listening the event
$(document).off("swipeleft swiperight");
}).on("mouseup touchend", function (event) {
// when interaction stops, re-listen to swipe events
$(document).on("swipeleft swiperight", handleSwipe);
});
It seems that sliders never ever work properly, as long as the swipe events are used anywhere in the document. This is even the case, when there is nothing done in the event handler. Also preventDefault() and/or stopPropagation() doesn't change anything.
With this solution, I kill the previously enabled swipe events while the user interacts with a slider. When interaction is done, I re-enable swipe events. Works great for me.
This worked for me with jqm 1.4.5:
$(document).on('mousedown touchstart', 'input[type=range]',
function(e){
e.stopPropagation();
});
Currently solved it like this:
$('body').on('swipeleft', function(event){
if(event.target.id != "changeRadiusRange"){
if(menuOpen == true){
home.showMenu();
}
}
});
But then slider is stopping after the swipeleft event is called from body. does not move more to the left so I have to release the slider and slide again to the left if I need to till the swipeleft is called etc. Just workaround hope got it fixed soon
On my site, I want to have users watch an embedded YouTube video without leaving the page, but I don't want to have the not so stylistic YouTube embed visible prior to clicking.
This is entirely doable on desktop, as you can use the YouTube JavaScript API to trigger the embed to play, but on iOS, programmatic triggering of the player to play is blocked. So how can I do this on iOS?
When thinking about this problem, I thought that one alternative route would be to have a layer that's opaque and styled, but you could click through it. This would mean the user thinks they're clicking a pretty button, when actually they're just clicking the embed to play.
Turns out there's a way of doing this, using the fancy (unofficial) CSS pointer-events property! Setting this to none means that clicks don't register, and instead punch straight through the element to whatever is behind it. In this case, the YouTube embed iframe. Support is iOS 6+.
Here's a JSFiddle of it working.
Note this is for iOS (and maybe Android) - it utilises the behaviour in which the video will automatically go full screen when it starts playing. If you watch this on desktop, the overlay remains.. overlaid.
There's some more polishing to be done with this to get it schmick:
Handling the initial click and altering the UI so they know immediately the video is kicking off. Perhaps hide the overlay, fade it, or change it to simply signify "Loading... "
On finish, resetting the video by recreating the iframe
You could do some tricky stuff with this technique, e.g. having a small player iframe overlaid by a small button. Still going to go fullscreen, so it'll work fine.
But regardless, there you go - proof of concept of playing a YouTube video on iOS without the user knowing they clicked on an embed.
iOS allows to call HTMLMediaElement.play function only from dispatched (triggered) by an user event (for example, from a "click" event handler).
Thus the code like this will work in iOS (because the player.playVideo is called from the dispatched by an user "click" event):
<div class="video">
Play
<iframe width="560" height="315" src="https://www.youtube.com/embed/pqLVAeoRavo?enablejsapi=1" frameborder="0" allowfullscreen allow="autoplay"></iframe>
</div>
<script>
(function() {
var player;
window.onYouTubeIframeAPIReady = function() {
new YT.Player(document.querySelector('.video iframe'), {
events: {
onReady: function(e) {
player = e.target
}
}
})
}
document.querySelector('.video .play').addEventListener('click', function(e) {
e.preventDefault()
player.playVideo()
})
})()
</script>
<script src="https://www.youtube.com/iframe_api"></script>
And the code like this will work in iOS too (because the initial call (the playMyVideo()) is still in the "click" event):
<div class="video">
Play
<iframe width="560" height="315" src="https://www.youtube.com/embed/pqLVAeoRavo?enablejsapi=1" frameborder="0" allowfullscreen allow="autoplay"></iframe>
</div>
<script>
(function() {
var playMyVideo;
window.onYouTubeIframeAPIReady = function() {
new YT.Player(document.querySelector('.video iframe'), {
events: {
onReady: function(e) {
playMyVideo = function() {
var player = e.target
player.playVideo()
}
}
}
})
}
document.querySelector('.video .play').addEventListener('click', function(e) {
e.preventDefault()
playMyVideo()
})
})()
</script>
<script src="https://www.youtube.com/iframe_api"></script>
But the code like this will not work in iOS (because the player.playVideo is called from the https://www.youtube.com/iframe_api script and not from the "click" event; i.e. only the window.onYouTubeIframeAPIReady function declaration is presented in the "click" event and window.onYouTubeIframeAPIReady is called from the https://www.youtube.com/iframe_api script):
<div class="video">
Play
<iframe width="560" height="315" src="https://www.youtube.com/embed/pqLVAeoRavo?enablejsapi=1" frameborder="0" allowfullscreen allow="autoplay"></iframe>
</div>
<script>
(function() {
document.querySelector('.video .play').addEventListener('click', function(e) {
e.preventDefault()
window.onYouTubeIframeAPIReady = function() {
new YT.Player(document.querySelector('.video iframe'), {
events: {
onReady: function(e) {
var player = e.target
player.playVideo()
}
}
})
}
var tag = document.createElement('script')
tag.src = 'https://www.youtube.com/iframe_api'
var firstScriptTag = document.getElementsByTagName('script')[0]
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag)
})
})()
</script>
I have a website that uses jquery mobile to detect touch interaction.
It works fine when I test it on the desktop, but when I try to use it embedded in a Windows Phone 8.1 WebView App, no touch events are triggered.
What am I missing here?
-edit-
ok here is some code I am using:
<script>
$(function () {
jQuery(window).on("swipe", function (event) { NotifyApp("Test"); });
});
</script>
The called NotifyApp function looks like this:
function NotifyApp(message) {
if ((typeof (window.external) !== "undefined") && (typeof (window.external.notify) !== "undefined")) {
window.external.notify(message);
}
}
NotifApp() works as expected, the app is notified by this function when I call the it manually by a button.
I am developing a Android app using Jquery Mobile/Phonegap. I have the following code to control the phone's back button:
document.addEventListener("backbutton", backKeyDown, true);
function backKeyDown() {
// Call my back key code here.
$.mobile.changePage("#homepage", "slideup");
}
This all works fine, but I would like the app to close when pressing the back button on the homepage only, is this possible?
Update: this has stopped working with a latest Phonegap update (supposedly). Feel free to offer a working solution if you know it.
Here's how I do it:
document.addEventListener("backbutton", function(e){
if($.mobile.activePage.is('#homepage')){
/*
Event preventDefault/stopPropagation not required as adding backbutton
listener itself override the default behaviour. Refer below PhoneGap link.
*/
//e.preventDefault();
navigator.app.exitApp();
}
else {
navigator.app.backHistory()
}
}, false);
For further information, here you can find the related documentation with a full example: http://docs.phonegap.com/en/2.0.0/cordova_events_events.md.html#backbutton
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
document.addEventListener("backbutton", onBackKeyDown, false);
}
function onBackKeyDown()
{
navigator.app.exitApp();
}
Thank you spader.
You would need to keep track of when the homepage is being displayed. When you know you are on the homepage call:
navigator.app.exitApp();
If you don't want to use jQuery Mobile, change $.mobile.activePage.is('#homepage') to document.getElementById('#homepage') on #Spadar Shut answer, as on following code:
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady(){
document.addEventListener("backbutton", function(e){
if(document.getElementById('#homepage')){
e.preventDefault();
navigator.app.exitApp();
}
else {
navigator.app.backHistory()
}
}, false);
}
Through this way, don't need to download Jquery Mobile gibberish only for this purpose. Also, activePage is deprecated as of JQuery mobile 1.4.0 and will be removed from 1.5.0. (Use the getActivePage() method from the pagecontainer widget instead)