There seems to be some issues when combining MathJax and jQuery Mobile on the same page. Sometimes the MathJax renders correctly and other times it does not - and this can happen to the same page.
The HTML that loads both of them looks like this:
<script type='text/javascript' src='http://code.jquery.com/jquery.min.js'>
</script>
<script type='text/javascript'
src='http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.js'>
</script>
<link rel='stylesheet' type='text/css'
href='http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.css' />
<script src='/beta/mathjax/MathJax.js'>
</script>
You can see an example page here: http://stackmobile.com/beta/math.stackexchange.com/questions/view/?id=47772
Edit: It seems to be a problem with MathJax not recognizing a new page being loaded via AJAX - here is an example that doesn't seem to work: http://stackmobile.com/beta/#/beta/physics.stackexchange.com/questions/view/?id=11678
Well I found a solution... and it goes something like this:
First assign unique numbers to the pages. Since these pages are generated in PHP, this can be accomplished by using uniqid().
Assign the following function the the pageshow event:
$('#page_id').live('pageshow', function(event, ui) {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'path_to_mathjax/MathJax.js';
script.onload = callback;
document.getElementsByTagName('head')[0].appendChild(script);
});
This loads MathJax and inserts it into the DOM - this script should be included within the page element. Also note that we mention a 'callback'. This will be called when the script loads.
This function (the callback) needs to go outside of any pages. This will prevent it from being included twice after a new page is loaded.
var mathjax_loaded = false;
function callback()
{
if(mathjax_loaded)
MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
else
{
MathJax.Hub.Startup.onload();
mathjax_loaded = true;
}
}
There's a lot here. First of all, we keep track of whether this callback has been called once before. If not, we tell MathJax to parse the page as if it were invoked from the window.onload event. If this has already happened (and we're on a new page) then we simply need to have MathJax run through the new page.
I'm probably missing something and there may be a better way of doing this. But I haven't found any other way that works.
Not sure if this is easier/better way to add a script but here is what I found:
http://api.jquery.com/jQuery.getScript/
Can't append <script> element
(Untested) Maybe (using your post: Combining jQuery Mobile and MathJax on a mobile site?)
$('#page_id').live('pageshow', function(event, ui) {
$.getScript('http://path_to_mathjax/MathJax.js', function() {
callback();
});
});
var mathjax_loaded = false;
function callback()
{
if(mathjax_loaded)
MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
else
{
MathJax.Hub.Startup.onload();
mathjax_loaded = true;
}
}
Related
I am working on a Firefox Add, using the newest SDK. The problem I am having, is that when ever I try to run a custom dom function it doesn't work.
Scenario:
The firefox add-on must be able to loop through all tabs, and if the correct one is open based on the title, run a specific function, like: mydom.checkIt();
<!DOCTYPE html>
<html>
<head>
<title>My Web</title>
</head>
<body>
<script>
mydom = {};
mydom.checkIt = function (){
alert('Hi');
};
</script>
</body>
</html>
Then the add-on source code would be something like:
var tabs = require('sdk/tabs');
for (let tab of tabs)
{
if(tab.title=='My Web')
{
tab.activate();
}
}
tabs.on('activate', function(tab) {
tab.attach({
contentScript: "if(typeof(mydom)!=='undefined')mydom.checkIt();else console.log('no defined');"
});
});
But this doesn't work and it says always: "no defined"
Any ideas?
You have to get into the dom js scope with unsafeWindow or wrappedJSObject. So contentWindow.wrappedJSOBject.checkIt() works from bootstrap addon (not sure about sdk)
Warning though, this may not be e10s friendly and we should find a way to support that
I have an Delphi application that uses TWebbrowser component to automate navigation to another web application we have.
My problem is that sometimes IE shows the infamous 'Are you sure you want to leave this page' message and when this happens, my app can't navigate to another pages unless an user clicks on 'Leave this page' button. I can't edit the website code to remove this warning, unfortunately.
This message is plaguing my app for weeks, and I could not reach to a proper solution anymore. What I did is to keep a background process do manually send a keystroke when this window is show, but this is not a good solution because nobody can use the computer while my app is working.
I saw possible solution for C# in the topic below but I need a Delphi code instead.
Supress the "are you sure you want to leave this page" popup in the .NET webbrowser control
Any help is very, very appreciated.
Thanks :)
This message is shown by the underlying MSHTML engine if the web page handles window.onbeforeunload event. Usually, it's there for a reason, to let the user know his/her input hasn't been saved or submitted yet. The prompt suppression script from the answer you linked doesn't work for cases when the page uses addEventListener("beforeonload", handler) or attachEvent("onbeforeunload", handler). I don't think there's a reliable way of doing this, without resorting to low-level Windows hooks.
[UPDATE] The following script (look for "Inject this script") is a hack which aggressively suppresses the page's own handlers for onbeforeunload event, via setInterval. It should work in 99% of cases, but it still leaves a gap for the page to override onbeforeonload right before navigating away.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title></title>
<script type="text/javascript">
window.attachEvent("onbeforeunload", function (ev) {
window.event.returnValue = "onbeforeunload via window.attachEvent()";
});
window.addEventListener("beforeunload", function (ev) {
window.event.returnValue = "onbeforeunload via window.addEventListener()";
});
window.onbeforeunload = function (ev) {
window.event.returnValue = "onbeforeunload via window.onbeforeunload";
};
</script>
<script type="text/javascript">
//
// Inject this script
//
(function () {
var onbeforeunloadHandler = function (ev) {
if (ev) {
if (ev.stopPropagation)
ev.stopPropagation();
if (ev.stopImmediatePropagation)
ev.stopImmediatePropagation();
ev.returnValue = undefined;
}
window.event.returnValue = undefined;
}
var handler = null;
var intervalHandler = function () {
if (handler)
window.detachEvent("onbeforeunload", handler);
// window.attachEvent works best
handler = window.attachEvent("onbeforeunload", onbeforeunloadHandler);
// handler = window.addEventListener("beforeunload", onbeforeunloadHandler);
// handler = window.onload = onbeforeunloadHandler;
};
window.setInterval(intervalHandler, 500);
intervalHandler();
})();
</script>
</head>
<body>
Go away
</body>
</html>
To inject this script with Delphi, you'd probably need to resort to low-level WebBrowser/MSHTML COM interfaces, like IWebBrowser2, IHTMLDocument2, IHTMLScriptElement, in a very similar way it's done in the linked answer. With some more efforts, the same can also be done via late binding, using IDispatch::GetIDsOfNames and IDispatch::Invoke only. If you're asking for exact Delphi code, I don't have one.
The other answer you link to handles the browser's Navigated event. In it, it injects a script element into the page and into each frame on the page. That script assigns a new value to window.alert so that when other code on the page calls it, it does nothing.
This code resets the event handler:
var
WrkIHTMLWindow2: IHTMLWindow2;
WrkIHTMLWindow2Disp: IHTMLWindow2Disp;
begin
WrkIHTMLWindow2 := IHTMLDocument2Disp(WrkIWebBrowser2.Document).parentWindow;
if WrkIHTMLWindow2.QueryInterface(IHTMLWindow2Disp, WrkIHTMLWindow2Disp) = S_OK then
if not VarIsNull(WrkIHTMLWindow2Disp.onbeforeunload) then
WrkIHTMLWindow2Disp.onbeforeunload := NULL;
end;
Note: JS/Jquery noob alert (yes, me)
There seems to be a conflict between the following two plugins:
TableSorter (2.9.1)
bootstrap-popover.js v2.2.1
The plugins work as they should separately, but when together, the popovers don't work. I've tried moving the calls to the popover script (and its initialization) before any other plugins, but no dice. I have a feeling the tablesorter script is somehow removing the titles from the DOM (another subject I know little about) before the popover script can load, but no dice.
In my HTML
<script src="../../js/jquery-1.8.2.min.js"></script>
<script src="../../js/jquery.tablesorter.js"></script>
<script src="../../js/jquery.tablesorter.pager.js"></script>
<script src="../../js/tooltips-popovers.js"></script>
<script>
$(function(){
$("#stats").tablesorter();
});
</script>
<script>
$("a[rel=popover]").popover({html:true,trigger:'hover'});
</script>
<script> /* Initiate pager */
$(function(){
var pagerOptions = {
container: $(".pager"),
};
$("table")
.tablesorterPager(pagerOptions);
});
</script>
Make sure you are initializing the popover script within a document ready event.
$(function(){
$("a[rel=popover]").popover({html:true,trigger:'hover'});
$("#stats")
.tablesorter()
.tablesorterPager({
container: $(".pager")
})
});
If that doesn't work, I can only guess that the popover links are inside the table? If so, they are added and removed dynamically, when sorting the table, so they might need to be added through a delegated event, the code above may not work in that case.
Update: As stated, the popup links are within the th, which I assume are in the thead? If so, try this code:
$(function(){
$("#stats")
.tablesorter({
initialized: function(table){
$("a[rel=popover]").popover({html:true,trigger:'hover'});
}
})
.tablesorterPager({
container: $(".pager")
})
});
I have jQuery UI tabs set up, but a problem that I'm having with links to different pages is that they load all contents of the page into the tab. This includes the footer, header, and other navbars that I don't want in the tab. What if I would only like to load a single ID from that page?
My tabs are set up this way:
<div id="mytabs">
<ul>
<li>Awesome page</li>
<li>Foo</li>
</ul>
</div>
Nothing much going on in the jQuery...
$(function() {
$( "#mytabs" ).tabs();
});
Let's say this is the html of "awesomepage" (that the first link targets):
<html>
<head>
<title>awesome page</title>
</head>
<body>
<div id="header">bla</div>
<div id="awesomeness">awesomeness!</div>
<div id="footer">fdsfd</div>
</body>
</html>
...And I only want the tab to load #awesomeness from the page. How would I go about doing this? I've read into some guides that do that by adding a data-target="#youridhere" attribute to the HTML, but I'm still confused on how to implement the javascript. It seems like this is a convenient solution, as I won't be targeting the same ID in every page. Any clues on how to get the javascript working?
Thanks in advance!
The function that allow to load partial code of the response is the $.load() function.
Unfortunately, the tabs() feature does not use this function but use $.ajax instead.
You can try this solution:
You can try to stop the default processing on the beforeLoad callback and manage your ajax call with the $.load() method.
(base on the 1.9 documentation, you may should adapt)
$('#tabs').tabs({
// Callback run when selecting a tab
beforeLoad: function(event, ui) {
// If the panel is already populated do nothing
if (ui.panel.children().size() > 0)
return false;
// Make your own ajax load (with fragment feature)
ui.panel.load(ui.tab.attr('href') + ' #yourFragment');
// stop the default process (default ajax call should not be launched)
return false;
});
NOTICE: I'm not sure about extracting the URL with ui.tab.attr('href'), check before what object is ui.tab, but it should be easy to retrieve the href parameter.
Good luck
Got the solution :) Using one of the answers as a reference point, the tabs can now load a single element specified in the data-target attribute. Here is the modified version:
$(function() {
$('#tabs').tabs(
{
beforeLoad: function(event, ui) {
if (ui.panel.children().size() > 0)
return false;
ui.panel.load($('a', ui.tab).attr('href') + $('a', ui.tab).attr('data-target'));
return false;
}
});
});
So I was using trigger.io to create a page where there's a custom menu at the bottom and each button loads an external HTML page into main container. I had to hack around to make this work so I was wondering if there's a better way of doing it.
I started using the $('.main').load('pages/test.html') and it doesn't work. Instead I had to do:
forge.file.getLocal('pages/test.html', function (file) {
forge.file.string(file, function (str) {
$('.main').html(str);
});
});
which is kinda messy.
Also if the str HTML content as a img tag, the img doesn't show since the src attribute gets messed up. So I had to do another hack:
forge.file.getLocal('pages/test.html', function (file) {
forge.file.string(file, function (str) {
var $main = $('.main');
$main.html(str);
//Hack to resolve img src
var imgPath;
$main.find('img').each(function () {
var $this = $(this);
// First 8 chars is "file:///"
imgPath = $this.prop('src').substr(8);
forge.file.getLocal(imgPath, function (file) {
$this.prop('src', file.uri);
});
});
});
});
Any better way of purely loading an external HTML page without all the hassle?
Thanks!
Testing with forge platform v1.4 (at the time of writing, v1.4.18) on Android 4.1 and iOS (both the iPhone simulator and an iPad), I seem to be able to use jQuery's load method without any extra effort. Here's the structure for my testcase:
src/
index.html
face.png
pages/
hello.html
Here's the contents of index.html
<!DOCTYPE html>
<html>
<head>
<script src="js/jquery-1.7.1.min.js"></script>
<script type="text/javascript">
$(function () {
$('.content').load('pages/hello.html');
});
</script>
</head>
<body>
<div class="content">
</div>
</body>
</html>
And pages/hello.html:
<b>hello world</b><img src="face.png">
Which resulted in this just after app launch:
One gotcha I can see with this approach is that the src attribute for the img tag had to be relative to index.html. If you're still having problems then a more specific testcase and/or details of forge platform version used as well as what devices/simulators you tested on might be useful.