Android WebView: how to scroll to an <a name=here> position - javascript

I'm loading a self-created HTML page into a WebView in an Android app.
The HTML page contains a tag like <a name="here"></a> somewhere in the middle.
After loading that page, I'd like to be able to programmatically scroll to that position, as if I had clicked on a here link.
I tried with loadURL and with loadDataWithBaseURL, with every possible parameter combinations that I could think of, without success.
Note 1: I want to be able to scroll to that position after the page has been already displayed.
Note 2: I cannot use scrollTo(x,y) because I don't know the y position of that <a name="here"> anchor within the page. If I could figure out the y position in the page of that <a name> tag, that would also solve the problem, but I don't know how to find that y value either.
(P.S. I'm loading the self-created HTML page by calling loadDataWithBaseURL(null, _html, null, null, null); where _html is the string with my HTML page)

1) Inside <script></script> part of your HTML page, create a Javascript function to programmatically click a link on the same page:
function myFunction(){
document.getElementById('myLink').click();
}
2) Instruct your HTML to run your Javascript function once the page is 100% loaded adding an onload event handler to your body HTML tag, this way:
<body onload="myFunction();">
3) Inside the body area of your HTML, anywhere, create an empty link just to have the functionality of a click to the anchor you want (as you suggested, the reference to your anchor is #here:
4) Finally create an anchor at the desired position inside HTML:
<a name="here">HERE</a>
That's it. When the page is loaded it will go to the desired position.
If you want to try this before use... https://jsfiddle.net/vapx8rzk

Answering my own question, thanks to the above suggestions I found that calling "scrollIntoView()" works for me, like this:
Instead of <a name="here"></a>, I use an "id" attribute, like e.g.: <span id="here">
I call webView.loadURL("javascript:document.getElementById(\"here\").scrollIntoView()");

Related

JavaScript DIV Editing Destroys Functionality of Other Elements

So my website is built using a company's software called Inksoft which leaves me very little to work in the way of customization. So I have to do many workarounds.
Here is my site's homepage.
The header on top of the page only has two links right now. "Products" and "Design Studio". My goal is to add an "About Us" link and "Buyers Guide" to the header as well.
I cannot add new content to the header using Inksoft's backend. So I coded a workaround to replace the content of existing DIV's within the header to say and link to where I want them to go.
The only issue is, the responsive mobile-nav loses functionality when this is implemented. As seen here on this test page.
The test page has the About Us in the top header, added by the use of this code:
<script>
$("#header-nav-designs").html('<document.write="<li id="header-nav-studio"><font color="#000000">About Us</font></li>');
</script>
So, the simplified question is: how do I implement this code without losing the responsive functionality of the nav bar?
The jQuery .html function will replace the HTML inside the target element. If you want to just append the one value, you likely want to .append to the element.
In addition, you aren't setting the HTML to a valid html string. You probably just want to get rid of the <document.write=" at the beginning of the string. The rest of it looks fine with just a cursory glance.
So:
<script>
$("#header-nav-designs").append('<li id="header-nav-studio"><font color="#000000">About Us</font></li>');
</script>
Edit:
After looking at it a little more, it appears as though the $('#header-nav-designs') that you are selecting is already an <li> which means you need to either select the parent <ul> list or you can use the jquery .after function instead.
<script>
$("#header-nav-designs").after('<li id="header-nav-studio"><font color="#000000">About Us</font></li>');
</script>
And as someone else commented above, you are getting an error on the page. It appears as though you are trying to get an element with the id divID and the appending some html to it, but there is no element with the id divID and so you are getting an error saying that you can't read the property innerHTML of null as the call to document.getElementById is returning null (element not found).
Element id header-nav-designs witch your code is referring have CSS style on line 170:
#header-nav-designs {display:none;}
The element will be hidden, and the page will be displayed as if the element is not there. With display:none;
If I understand you correctly your code selector points to wrong element id. It should point $(".header-nav > ul"). Document.write is not needed inside jQuery you need to give only an valid html string as argument.
jQuery html function erase html that is all ready inside element and replace it with html string given as argument. You have to use append if you want to add more html but not remove what is allready in element.
$(".header-nav > ul").append('<li><font color="#000000">About Us</font></li>');
$(".header-nav > ul").append('<li><font color="#000000">Buyers Guide</font></li>');

Hash url and AngularJS

I am using angularjs for part of my page say single component, which is used in many pages.Now my problem is hash url does not work now.
Example: I have a div#hello in my page and URL is given as Url#hello.but it does not go to that particular div just the top of the page is diaplayed.
So could you guys help me here please?
NOTE:The url#hello is changing to url/#hello.The page cannot be changed to angular and only that single component use angular.
EDIT: Thank you Stephen:) yes, of course, we need to use routing.The thing is, after page load, if we change the url back to URL#hello it works.So is it possible to do it in other way apart from Routing and $angularscroll ?(i.e) just from the JS or jQuery perspective ?
Ok, thanks. I've misunderstood you. I think I have a better understanding now. Please correct me if I am wrong:
So, you're essentially trying to make a hello link that points to a section within the same page. When you change the url to pageUrl#hello the page should jump down to the section with the id called hello.
But the problem is that since your section has an AngularJS component that uses the ngRoute module, this routing functionality is making your page redirect to pageUrl/#hello instead of jumping to the HTML section with the id='hello'.
Is this correct?
Solution
If I understand your problem correctly, the solution is to check if your ng-app='appName' attribute is on the body tag. If it is, then move it down to your component's parent element.
If a hash link is a child of the ng-app element, then when you click it AngularJS thinks you want to redirect to another view. This is what causes the Home link to redirect to pageUrl#/home.
<body ng-app="demoApp">
Hello <!-- redirects to #/hello -->
<div id="hello"></div>
<!-- ... -->
So if you put the hash link outside of the ng-app element then it will behave as expected when you click it.
<body>
Hello <!-- jumps to the 'hello' div -->
<div id="hello" ng-app="demoApp"></div>
<!-- ... -->
On Page Load
If you want the page to jump to the hello div on page load, then set window.location = '#hello' inside your controller. Then, when you visit pageUrl#hello, the hello div should appear instead of the top of the page.
If you don't have a controller, or don't want to use one, then after your document loads, check the hash url and change it programmatically.
$(document).ready(function(){
if(window.location.hash == '#hello'){
window.location = '#hello';
}
})

HTML Anchor tag issue

I have a piece of code like below
<div>
<ul>
<li>Test1</li>
-------
-------
-------
<li>Test46</li>
</div>
It displays the html page with 46 links. The issue is when i scroll down and select the 46th or the ones just above this the page is going back to the top again. why is it happening so and is there any way to prevent it ?
href is blank thats why its going at top. You can use this instead of keeping blank:
Test46
href="" contains the URL "" which is a relative URL that resolves to "the URL of the current page".
When you click on the link, the browser follows it and goes to the current page.
As is normal (absent of any specific directive otherwise), when it goes to a page, it starts at the top.
If you don't want to link to the page: Why are you using a link in the first place?
If you just want something to dangle JavaScript from, use a button instead.
<button type="button">Test46</button>
You can style it to remove the default background colour and border, and set the colour scheme to match that of a link if you want it to look like a link.
An empty string in the href attribute <a href=""> means in modern browsers to go to the current page. This will basically just reload the current page, and as such it will go to the top.
One way to prevent from going to the top is to use href="javascript:void(0)", as mentioned by #Manwal or you can simply remove the href attribute completely (note in that case it will not show up as a clickable hyper-link).

Static content in website

I've got a website and I'd like to make a part of it static. What happens is that the header, the menu bar and the footer are consistent in every page. I'd like to have them always loaded and when I click the menu button, it will only reload what is the body of the site.
Is there a simple chunck of code that can early achieve this? Something in js or ajax? I'm sorry but I don't have enough experience in these languages to accomplish something on my own. I've already tried to check jQuery library but it's still pretty confusing to me.
Thank you.
I think you don't even need Ajax or css!! Just use iFrames!! They are awesome, what happens is that u only design one page as the holder of your static content (Header-Menu ...) and put one iFrame in there as a place holder for any page you want to load in it, u should use proper css code to place the iFrame where you want, now, for every link in your menu, just set the "target" attribute equal to your iFrame's name and all the links will be loaded in that iFrame and your page won't be reloaded with every link click... I'll be back with some code...
Just add in every page a div container with ID for header, menubar and footer and just load it with this:
$(document).ready(function(){
$('#header').load('header.html');
$('#menubar').load('menubar.html');
$('#footer').load('footer.html');
});
Just make sure that the html files don't have html, head or body tags within, only the HTML-Code you would write inside the div. It's just like the include function in PHP.
EDIT:
For easy and simple implementation store the code above inside a .js file (e.g. include.js) and add this inside every head just below the include of all other scripts of your html files:
<script type="text/javascript" src="include.js"></script>
EDIT2:
Another solution ist to load the content of the page instead of the header, menubar, footer.
Here you take the same specifications (no html, body, etc. tags inside your content html files)
Name your content div e.g. <div id="content"></div>
Your navbar for example:
<div id="navbar">
Content1
Content2
</div>
JavaScript Code:
$(document).ready(function() {
//Click on a link that's child of the navbar
$('#navbar > a').click(function() {
//Get the html file (e.g. content1.html)
var file = $(this).attr('href');
//Load this file into the #content
$('#content').load(file);
return false;
});
});
You should consider the use of Server Side Included : http://httpd.apache.org/docs/current/howto/ssi.html
It's not quite easy to understand (as it refer to apache configuration), but this is a really great solution.
In a nutshell, you include parts of html code in you main page :
<!--#include virtual="/footer.html" -->
You won't have to use or understand all JQuery Framewol, user agent won't have to parse (if they are able to !) Javascript.
This is a pretty good replacement of PHP / ASP / Java for this kind of purpose.
You could use ajax to request the body of each page. But this is only one possibility - there are many. An other approach could be to create you page content using a script language (php, perl) serverside and employ a function there which adds footer, header and anything else to each page.
If you have an idea of Jquery then use click event on menu links to load the page in a div like the following syntax may help you.
$(document).ready(function(){
$("a.menu").click(function(){
$("#bodyContent").load("http://abc.com/your-linked-page.html");
});
});
To load the url dynamically use the following code:
In your menu bar the link looks like:
Home
In your Jquery code:
$(document).ready(function(){
$("a.menu").click(function(){
url = $(this).attr("title"); // here url is just a variable
$("#bodyContent").load(url);
});
});
Step 1: Add Jquery file into your html page.
Step 2: Use the above jquery code and change your menu link to the new what i said here.
Step 3: If you done it correctly, It will work for you.
How about a traditional iframe?
In your menu:
<a target="body" href="URL_to_your_Menu1_page">Menu1</a>
and then further in the document:
<iframe name="body" src="URL_to_homepage"></iframe>
You may use frameset and frames and organize you pages accordingly. So, frames containing menus can always be at display and while displaying contents on click of menu u may set target to frame in which you would like to load the contents.

Javascript Embedding Scripts onclick

What I would like to do is change the content of a div based on the different links clicked on the same page. Can anyone point me in the correct direction? AFAIK it could be dangerous to insert scripts directly into a page, changing text works okay but it seems I'm not sure about scripts. The content of the scripts are embed codes for video streaming. I realise this may not be the right way to go about it. My attempt won't work because of escaping the '<,>' characters and passing the parameter only seems to accept text with no spaces.
The way I've attempted it is as follows (in pseudocode);
function changeVideo(script){ div.innerhtml=script;}
then links that change the content of the div;
<a href='#' onclick=changeVideo('<iframe src=justin.tv etc..></iframe>')>
<a href='#' onclick=changeVideo('<iframe src=ustream.tv etc..></iframe>')>
You could drop the use of JavaScript and create an iFrame with a specified name to host the content; while giving the links a target tag. Thus making any links with the target tag specified appear within the named iFrame.
However if you insist upon using JavaScript you could consider the use of AJAX.
I suggest you to locate your a elements with unobstrusive Javascript, with getElementById() for example.
Once you have got them in variables like, lets say, a1 and a2, and the iFrame is in variable iframe do a code like this.
// ...a1 and a2 are anchors and iframe is the frame.
var srcSwitch = function(e)
{
e.preventDefault(); // this will prevent the anchor from redirecting you
iframe.src = this.src; // this changes the iFrameā€˜s source
};
a1.addEventListener('click', srcSwitch, 1);
a2.addEventListener('click', srcSwitch, 1); // and we register event listeners.
With this code, there is no need to insert Javascript within HTML attributes and you must only put the script URL in the anchors SRC attributes.
Tell me how it goes, greetings.
I may have generalised the question too much.
So I want to embed a stream on clicking a link. If the link is something like a proper URL
http://Jimey.tv/mystream
the iframe works, but loads the whole page. But I want to use the stream embed code to get just the player
The embed code looks similar to;
<script type = text/javascript> channel='mychannel' w='620' h='400'</script><script type=text/javascript> src="jimmy.tv/embed.js></script>
My original JavaScript method doesn't work because of escaping the < characters, and passing the embedcode seems to be problamatic. Hopefully I've made this a bit clearer?
<script>
iframe1 = '<iframe frameborder="0" scrolling="no" id="chat_embed" src="http://twitch.tv/chat/embed?channel=xenema&popout_chat=true" height="301" width="221"></iframe>'
</script>
link 1
link 2
<div id="videos">diiiiv</div>

Categories