I want to import files from collection.media that are not sound, image, or video. For example I'd like to import a JSON file.
I put the file _script.jquery-3.3.1.min.js and _data.json in my collection.media folder.
On Anki Desktop (Ubuntu), the following works:
<script src="_script.jquery-3.3.1.min.js"></script>
<script>
$.getJSON('_data.json', function(data) {
// succeeds on Anki Desktop, fails on AnkiDroid
});
</script>
(Note on Anki Desktop 2.0.47 I am using the JS Booster plugin).
On AnkiDroid, the situation is different. JQuery loads just fine in the script tag. However, $.getJSON fails to find the _data.json file.
I'd like to use _data.json on many cards/notes.
How can I import non-media, non-js files from collection.media in javascript, in a way that works both in Anki Desktop and AnkiDroid?
I have found some working answer for this.
To get character data in AnkiDroid card templates. (OFFLINE)
As we can access js and image file using this
<script src="some-js-file.js"></script>
<img src="some-image.png"></img>
To access json
I have tried same steps but getting CORS error so I used next steps.
<!-- It will give CORS error -->
<script src="我.json" type="application/json"></script>
With example,
To access 我.json file
Copy contents of 我.json into a javascript file 我.js, with any variable name,
var char_data = {"strokes":["M 350 571 Q 3....}
Add following tag to access that js file
<!-- Note : file type & name -->
<script src="我.js" type="text/javascript"></script>
Now also change code in _hanzi-writer.min.js
To change code, first beautify code using this https://beautifier.io, then make following change
a) Remove the link to load from internet
b) Change this 200 != r.status and replace/add this
JSON.parse(JSON.stringify(char_data))
( May be more good replacement can be done here )
....
....
// Note : char_data variable come from 我.js file
r.overrideMimeType && r.overrideMimeType("application/json"), r.open("GET", "", !0), r.onerror = function(t) {
....
....
4 === r.readyState && (200 != r.status ? i(JSON.parse(JSON.stringify(char_data))) : 0 !== r.status && n && n(r))
....
....
So final script will be like this
Front side of card
{{Pinyin}}
<div id="character-target-div"></div>
<script src= "我.js" type="text/javascript"></script>
<script>
var data = JSON.stringify(char_data);
console.log(data);
</script>
<script src="_hanzi-writer.min.js"></script>
<script>
var writer = HanziWriter.create('character-target-div', '我', {
width: 150,
height: 150,
showCharacter: false,
padding: 5
});
writer.quiz();
</script>
Above all the steps are for single file 我.js
To access other character repeat the same.
For similar issues view my code
https://github.com/infinyte7/Anki-xiehanzi
https://github.com/infinyte7/hanzi-writer-data-in-javascript
I assume this is related to how AnkiDroid handles collections.media files. If so, this might be a bug. A really hackish workaround could be to rename the file to .svg so that AnkiDroid treats it as an image and lets it through.
I'm using https://github.com/styled-components/styled-components.
I'm trying to work out the best strategy for components that require #font-face. I want to make sure each component is independent of its context, so I'm defining font-family styles on each them. But if I use injectGlobal in multiple components, I get multiple #font-face rules for the same font.
Should I just define the #font-face rules in my ThemeProvider entry-point component and live with the fact that the desired font might not be loaded by the browser?
That's exactly why we made injectGlobal. If you take a look at our docs they say:
We do not encourage the use of this. Use once per app at most, contained in a single file. This is an escape hatch. Only use it for the rare #font-face definition or body styling.
So what I'd do is create a JS file called global-styles.js which contains this code:
// global-styles.js
import { injectGlobal } from 'styled-components';
injectGlobal`
#font-face {
font-family: 'My custom family';
src: url('my-source.ttf');
}
`
As you can see, all we do here is inject some global styling-in this case #font-face. The last thing necessary to make this work is to import this file in your main entry point:
// index.js
import './global-styles.js'
// More stuff here like ReactDOM.render(...)
This will mean your font-face is only injected once, but still all of your components have access to it with font-family: 'My custom family'!
Doing it this way will give you a flash-of-invisible-text (FOIT), but that has nothing to do with styled-components-it'd be the same if you were using vanilla CSS. To get rid of the FOIT requires a more advanced font loading strategy rather than just #font-faceing.
Since this has nothing to do with styled-components, I highly recommend watching these two Front End Center episodes to learn more about how to best do this: "Crafting Web Font Fallbacks" and "The Fastest Webfont Loader in the West"!
And on the other side of the same coin in Chrome:
do not use #font-face inside injectGlobal if using e.g. react-router.
You will get re-paint of all of you app on each newly loaded route.
And this is why:
Same font-files downloaded on each new route.
As soon as you include font-face in a separate .css file - problem solves as stated in the last comment in this github issue.
injectGlobal is deprecated. Use createGlobalStyle
import { createGlobalStyle } from 'styled-components'
export const GlobalStyle = createGlobalStyle`
body {
font-family: 'Muli', sans-serif;
h1 {
font-weight: 800;
font-size: 36px;
p {
font-size: 18px;
}
}
`;
Then you can use it in your App.js:
import { GlobalStyle } from './styles/global'
class App extends Component {
render() {
return (
<ThemeProvider theme={theme}>
<>
<GlobalStyle/>
<Container/>
</>
</ThemeProvider>
)
}
}
I agree
I get reloaded with
import { createGlobalStyle } from 'styled-components';
import { silver } from 'shared-components/themes/colors';
export default createGlobalStyle`
#font-face {
font-family: "Proxima Nova";
font-style: normal;
font-weight: 300;
font-display: swap;
src: url("/static/media/fonts/proxima_nova/ProximaNova_300.otf");
}
and react create app
There is another thread that covers this, but I am not allowed to post to it. Also, the only answer does not seem to solve my problem.
I am getting the Object not a function error when using the #html.extend() method. I have read all of the very limited threads on this topic. They all say the same thing. That I need to ensure the path is correct to the layout.vash file I am extending. My declaration looks like this in the file that I want to want to extend with my layout.vash file.
#html.extend('layout', function (model) {
.... do stuff ...
})
What is odd, is that some pages work fine others don't. The path is correct. I am sure of this because of the fact the files in the same director exhibit different behavior.
Does anyone know what other mistake I could be making to cause this error?
In my case, vash was unable to parse the content within ...
I pulled it out from the layout page and created a separate .css file, and the annoying "object is not a function" error disappeared.
I speculate that vash collides with some css syntax.
For you info, my style statements that caused the trouble were these.
<style type="text/css">
*{padding:0;margin:0;}
html{border-top:10px #1abf89 solid;}
body{width:800px;margin:0 auto;padding:5% 20px 20px;font-family:Palatino, Optima, Georgia, serif;}
#media all and (max-width:1024px){ body, pre a{width:60%;} }
small{color:#999;}
#toolbar{margin-bottom:1em;position:fixed;left:20px;margin-top:5px;}
#toolbar [class^="icon-"]:before, #toolbar [class*=" icon-"]:before{font-family:'pen'}
#mode{color:#1abf89;;cursor:pointer;}
#mode.disabled{color:#666;}
#mode:before{content: '\e813';}
#hinted{color:#1abf89;cursor:pointer;}
#hinted.disabled{color:#666;}
#hinted:before{content: '\e816';}
#fork{position:fixed;right:0;top:0;}
/*
When the webpage is printed
this media query hides extra elements,
and makes the text content fit the page.
*/
#media print {
#fork, #toolbar {
display: none;
}
body {
width: 94%;
padding-top: 1em;
font-size: 12px;
}
html {
border-top: 0;
}
}
</style>
How can I add a phone number to a website that is clickable but hides the link when I'm browsing on a website that doesn't support touch.
I could use Modernizr to set it up although. I don't know how.
<p><img src="assets/images/bt_calltoaction.gif" alt="View Projects" width="306" height="60"></p>
Could you just have the code in twice? i.e...
<div class="desktoptel">0800 000 000</div>
<div class="mobiletel"><a href="tel:0800-000-000">0800-000-000</div>
Then just 'display:none;' on the relevant class depending on your browser sizes?
I was just dealing with this issue, looking up solutions, and I found this thread (and a few others). I have to confess that I couldn't get any of them to work properly. I'm sure I was doing something wrong, BUT I did figure out a cheat.
As others have pointed out, changing the CSS to hide the visible link indication (color, text-decoration, cursor) is the first and easiest step. The cheat is to define a title for the tel link.
<p>Just call us at <a class="cssclassname" href="tel:18005555555"
title="CLICK TO DIAL - Mobile Only">(800) 555-5555</a>.</p>
By doing this, not only is the visible indicator of a link disguised (via CSS - see examples from others), but if someone does hover over the link, the title will pop up and say "CLICK TO DIAL - Mobile Only". That way, not only is there a better user experience, but your client doesn't accuse you of having a broken link!
For me the easiest, yet simplest method without any new classes / setup is via css:
a{
color: #3399ff;
}
a[href^="tel"]:link,
a[href^="tel"]:visited,
a[href^="tel"]:hover {
text-decoration: none;
color: #000;
pointer-events: none;
cursor: default;
}
/* Adjust px here (1024px for tablets maybe) */
#media only screen and (max-device-width: 480px) {
a[href^="tel"]:link,
a[href^="tel"]:visited,
a[href^="tel"]:hover {
text-decoration: underline;
color: #3399ff;
pointer-events: auto;
cursor: pointer;
}
}
Html just goes like this:
(+12)3 456 7
This works for modern browsers & IE 11+. If you need to include 8 < IE < 11 add the following to your javascript, since pointer-events dont work in IE:
var msie = window.navigator.userAgent.indexOf("MSIE ");
if (msie > 0){
var Elems = [], Tags = document.querySelectorAll("a[href^='tel']");
//Nodelist to array, so we're able to manipulate the elements
for (var i = 0; i < Tags.length; i++ ) {
Elems[ i ] = Tags[ i ];
}
for(var i = 0; i < Elems.length; i++){
Elems[ i ].removeAttribute('href');
}
}
EDIT: i found another answer on another thread, that may be useful for you - SO - Answer
I recently had this same problem. This problem is all over stackoverflow and everywhere else. How do you hide 'tel:' prefix and keep it from blowing up in regular browsers. There's no good single answer.
I ended up doing it this way:
first I use metalanguage to filter browser vs mobile (like php/coldfusion/perl) based on useragent string:
regular exp match for "/Android|webOS|iPhone|iPad|BlackBerry/i",CGI.HTTP_USER_AGENT
that gives me an if/else condition for desktop browser vs phone.
Next, my href tag looks like this: <a class="tel" id='tel:8005551212' href=''>800-555-1212</a>
Use CSS to style the .tel class in desktop stylesheet so it doesn't look like a link to desktop browsers. the phone number can still be clicked but its not obvious, and it wont do anything:
/* this is in default stylesheet, styles.css: */
.tel{
text-decoration:none;
color: #000;
cursor:default;
}
/* it should be re-styled in mobile css: */
.tel{
text-decoration: underline;
color: #0000CC;
cursor:auto;
}
Finally, I do a little jquery on the mobile links. The jQuery gets the id from the a.tel class, and inserts it into the href property, which makes it clickable for phone users.
The whole thing looks like this:
<!-- get regular CSS -->
<link rel="stylesheet" href="styles/styles.css" type="text/css" media="Screen" />
<!-- get user agent in meta language. and do if/else on result.
i'm not going to write that part here, other than pseudocode: -->
if( device is mobile ) {
<!-- load mobile CSS -->
<link rel="stylesheet" href="styles/mobile.css" type="text/css" media="handheld" />
<!-- run jQuery manipulation -->
<script>
$(function(){$('a.tel').prop('href',$('a.tel').prop('id'));});
</script>
}
<p> Call us today at <a class="tel" id='tel:8005551212' href=''>800-555-1212</a>!</p>
One caveat to this approach: id's should be unique. If you have duplicate phone numbers on a page that you want to link, change the id to name, then you use jQuery to loop through them.
You could use css media queries to control when its viewed as link and when not.
#media(min-width:768px){
a[href^="tel:"] {
pointer-events: none;
}
}
anything below 768px will work as link, above that, just as text.
if you just wanted to disable the click on the mobile screens:
if(typeof window.orientation !== 'undefined'){
$('a[href^="tel:"]').on('click', function(e){
e.preventDefaults();
});
}
Hope this helps :)
I've had success with this using Modernizr, specifically the touch test. It's not a perfect solution in that it doesn't do anything to help tablets or touch-enabled laptops, but it works in most desktop browsing situations.
HTML:
Call us at: 1-800-BOLOGNA
CSS:
.no-touch a.call-us {
color: black; /* use default text color */
pointer-events: none; /* prevents click event */
cursor: text; /* use text highlight cursor*/
}
The above CSS targets links with class="call-us" on non-touch devices which covers the majority of desktops.
Note that pointer-events is supported in all modern browsers but IE only supports it in versions 11+. See the compatibility chart.
Another solution, still imperfect, would be to use Modernizr.mq along with Modernizr.touch to detect screen width and touch capability and then inject the phone link with jQuery. This solution keeps the phone link out of the source code and then only appears on touch devices smaller than a certain width (say 720px which will probably cover most phones but exclude most tablets).
Ultimately, it's up to the browser vendors to come up with a bulletproof solution here.
I found the best way. I get that this is old, but I found a very easy way of doing this.
Using this code below
888-555-5555
//This is the logic you will add to the media query
.not-active {
pointer-events: none;
cursor: default;
}
In your CSS make use of media queries.
So make a media query for all desktops
#media only screen and (min-width: 64em) {
/* add the code */
.not-active {
pointer-events: none;
cursor: default;
}
}
Now all desktop sized pages wont be able to click on it.
it seems this could be done with a simple media query for most browsers. Something like this is working like a charm for me:
<style type="text/css">
#mobil-tel {
display:none;
}
#media (max-width: 700px) {
#mobil-tel {
display:block;
}
#desktop-tel{
display:none;
}
}
</style>
and on the desktop link, leave out the 'href', on the mobile link, put in the 'href'.
Just thought I would add my two-cents worth to (what is turning out to be a rather lengthy) discussion.
I basically use the onClick event (on the link) to execute Javascript to return a boolean true or false. If the return value is true, i.e. some variable or function that tests if the device is a phone returns a value true, then the href URL is followed by the browser. If the the return value is false, then the href URL becomes, in effect, inactive. (Standard HTML behavior, way before HTML5.)
Here is what I mean:-
<html>
<head>
<title>tel markup example</title>
<script src="http://code.jquery.com/jquery-2.1.0.min.js"></script> <!-- Does not really matter what version of jQuery you use -->
<script>
var probablyPhone = ((/iphone|android|ie|blackberry|fennec/).test(navigator.userAgent.toLowerCase()) && 'ontouchstart' in document.documentElement);
function initialize() {
if ( !probablyPhone ) {
alert ("Your device is probably not a phone");
( function( $ ) {
$( '.call' ).css ( "text-decoration", "none" );
$( '.call' ).css ( "color", "black" );
$( '.call' ).css ( "cursor", "default" );
} )( jQuery );
}
}
</script>
</head>
<body onLoad="initialize();">
Please ring (some fictitious number in Australia): +61 3 9111 2222
</body>
</html>
Note that I also added some re-formatting of the link to make it appear to the user as if it's just ordinary text.
Here is a gist I created.
Just to finish this post/ answer, credit for writing succinct JavaScipt code for detecting a phone (based on the user agent and the ontouchstart event) goes to a fellow Melbournian rgb in this stackoverflow post
Here is a simple jquery-based solution which I developed to solve this problem. See code comments for explanation.
https://jsfiddle.net/az96o8Ly/
// Use event delegation, to catch clicks on links that may be added by javascript at any time.
jQuery(document.documentElement).on('click', '[href^="tel:"]', function(e){
try{
// These user-agents probably support making calls natively.
if( /Android|webOS|iPhone|iPad|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
// Do nothing; This device probably supports making phone calls natively...
} else {
// Extract the phone number.
var phoneNumber = jQuery(this).attr('href').replace('tel:', '').trim();
// Tell the user to call it.
alert("Please call "+phoneNumber);
// Prevent the browser popup about unknown protocol tel:
e.preventDefault();
e.stopPropagation();
}
} catch(e){
console.log("Exception when catching telephone call click!", e);
}
});
My approach is similar to another approach above; there are a few considerations I take into account:
As we know, there is no good programmatic way to detect support. This is a rare case where we are forced to parse the UserAgent string.
This should be client side; there is no need for server side detection.
There are now desktop browsers that can handle tel: links; Chrome's behavior on the desktop is, at worst, to do nothing when clicked. At best, you can make a call with Google Voice.
Because doing nothing when clicked is Chrome's fallback behavior, we should use that behavior as a fallback on all browsers.
If your page takes responsibility for creating tel: links, it should take responsibility for all tel: links and disable autodetection in the browser.
With all of this in mind, I suggest first adding a meta tag to your <head>:
<meta name="format-detection" content="telephone=no"/>
Then, define a JavaScript function that parses the UserAgent and returns true if and only if we think the browser will not bring us to an error page when the link is clicked:
function hasTelSupport()
{
return /Chrome\/|Mobile( Safari)?\/|Opera M(in|ob)i\/|w(eb)?OSBrowser\/|Mobile\;|Tablet\;/.test(navigator.userAgent);
}
Then, call that function from the onclick attribute in your link:
Call Me
This will allow tel: links to be clicked on Chrome, Edge, iOS Safari, Android Browser, Blackberry, Dorothy, Firefox Mobile, IE Mobile, Opera Mini, Opera Mobile, and webOS. The links will do nothing when clicked on other devices or browsers.
Please use international format for your tel: links. In other words, the first characters should be a + and a country code.
Thanks to TattyFromMelbourne's post I am now using a pretty simple bit:
My button id="call" will make the phone call based on his "probablyphone" test function but also will scroll down to the contact info section either way giving the button a working use no matter what.
I aslo replaced the alert with an empty function, to remove the pop-up.
<a id="call" href="#contact">PHONE US</a>
$("#call").on('click', function() {
var probablyPhone = ((/iphone|android|ie|blackberry|fennec/).test(navigator.userAgent.toLowerCase()) && 'ontouchstart' in document.documentElement);
var link = "callto:15555555555";
if ( !probablyPhone ) {
window.alert = function() {};}
else{window.location.href = link;}
});
</script>
You can use css3 media queries to detect a mobile window and hide the link accordingly.
#media(max-width:640px){
.your-calling-link{
display:none;
}
}
Alternately, if you want to show the link and just disable click functionality, use jquery function:
screen.width
or
screen.innerWidth
and disable the click functionality on the link using
$('.your-link').off(click);
One way of handling this is to create two separate divs and use display:hidden.
Example:
<div class="mobile-desktop"><p>123-456-7890</p></div>
<div class="mobile-mobile">123-456-7890</div>
In your css set your mobile break points. This part is really up to you. Let's say
#media only screen (min-width: 768px){
.mobile-mobile {
display:none;
}
}
#media only screen (max-width: 767px){
.mobile-desktop{
display:none;
}
}
This should let you hide one div based on screen size. Granted 789 is just a number I picked, so pick a size you believe is mobile. You can find them online at like this site I found on Google or others like it. Lastly, this is just a quick css markup, you might have to tinker but the idea is there.
This way works without adding any more CSS.
Try replacing the a tag with something else like a span tag, but only for mobile browsers of course. Benefits are that you are not cloaking this a with CSS preventing default action while keeping it still as a link. It won't be a anymore, so you won't have to worry.
I've created an example to here. Bold phone there works this way, see code below.
I took piece of code from one of the respondent to define if browser is mobile. And you have to mark these links with class="tel" or find a way to determine if the href has "tel:" in it. JQuery is also required.
// define if browser is mobile, usually I use Anthony's Hand mobile detection library, but here is simple detection for clarity
var probablyPhone = ((/iphone|android|ie|blackberry|fennec/).test(navigator.userAgent.toLowerCase()) && 'ontouchstart' in document.documentElement);
if ( !probablyPhone ) {
// find all the A with "tel:" in it, by class name
$('a.tel').each(function(){
var span = document.createElement('span');
// SPAN inherits properties of A, you can also add STYLE or TITLE or whatever
span.innerHTML = this.innerHTML;
span.className = this.className;
// replace A with SPAN
this.parentNode.insertBefore(span, this);
this.parentNode.removeChild(this);
});
}
Input this into custom css and call it a day:
a.tel { color: #FFFFFF; cursor: default; /* no hand pointer */ }
Change your color as needed.
Cheers!
I am adding the following css through javascript when mobile device is detected.
pointer-events:none
The js code is:
var a = document.getElementById("phone-number");
if (Platform.isMobile()) // my own mobile detection function
a.href = "tel:+1.212.555.1212";
else
$(a).css( "pointer-events", "none" );
In my target site, all phone link markups are in this pattern:
111-222-3333. My solution is such simple:
function setPhoneLink() {
if (screen.width > 640) {
$("a[href^='tel:']").each(function(){
$(this).replaceWith($(this).text());
});
}
}
Device-width: mobile<640; tablet >=768 and <1024; desk >=1024.
Source: http://javascriptkit.com/dhtmltutors/cssmediaqueries2.shtml
Don't use the screen size as a requirement for that.
You can use CSS media query like this:
#media (pointer: fine) { /* this is for devices using a mouse, maybe a pen */
a[href^="tel:"] { /* select only "tel:" links */
pointer-events: none; /* avoid clicks on this element */
}
}
#media (pointer: coarse) { /* this works for mobile phones */
}
More info: https://developer.mozilla.org/en-US/docs/Web/CSS/#media/pointer
#media screen {.telephone {pointer-events: none;}}