setting focus to first cell of table using html/javascript - javascript

i have table with 3X4 cells i navigate among cells using arrow keys(right,left,up, down) but problem is initially i need to press tab key to get focus to first cell and only after that i will be able to use arrow key to navigate. now my question is how can i set focus to first cell of table so that i can directly use arrow keys to navigate instead use tab first and they arrow keys.
here is my code:
function myNav(e,down,left,up,right)
{
if (!e) e=window.event;
var selectArrowKey;
switch(e.keyCode)
{
case 37:
selectArrowKey = left;
break;
case 38:
selectArrowKey = down;
break;
case 39:
selectArrowKey = right;
break;
case 40:
selectArrowKey = up;
break;
}
if (!selectArrowKey) return;
var controls = document.getElementsByName(selectArrowKey);
if (!controls) return;
if (controls.length != 1) return;
controls[0].focus();
}
kindly help.

On page load, retrieve a reference to that cell and call focus on it. You haven't shown your markup, so it's hard to give you a concrete example, but for instance if your table has an id of "foo":
var node = findFirstChild(document.getElementById('foo'), 'TD');
if (node) {
// get the control within the cell
node.focus();
}
function findFirstChild(parent, tag) {
var node, child;
for (node = parent.firstChild; node; node = node.nextSibling) {
if (node.nodeType == 1) { // Element
if (node.tagName === tag) {
return node;
}
child = findFirstChild(node, tag);
if (child) {
return child;
}
}
}
return undefined;
}
In terms of "page load", you can either hook the window.onload event (but that happens very late), or just put a script element at the bottom of the body tag (or anywhere after the table) that does the above. Once the table tag is closed, you can access it from script (ref1, ref2).
Off-topic: If you use a library like jQuery, Prototype, YUI, Closure, or any of several others, the code can get a lot simpler. For instance, with jQuery, the above changes to:
$("#foo td:first").focus();
Update: Responding to your comment below, your jsFiddle code was:
<html>
<head>
<script type="text/javascript" src="jquery-1.4.4.js"></script>
<script type="text/javascript">
$("#mycell td:first").focus();
function myTest(e,down,left,up,right)
{
if (!e) e=window.event;
var selectArrowKey;
switch(e.keyCode)
{
case 37:
// Key links.
selectArrowKey = left;
break;
case 38:
// Key oben.
selectArrowKey = down;
break;
case 39:
// Key rechts.
selectArrowKey = right;
break;
case 40:
// Key unten.
selectArrowKey = up;
break;
}
if (!selectArrowKey) return;
var controls = document.getElementsByName(selectArrowKey);
if (!controls) return;
if (controls.length != 1) return;
controls[0].focus();
}
var node = findFirstChild(document.getElementById('mycell'), 'TD');
if (node) {
// get the control within the cell
node.focus();
}
function findFirstChild(parent, tag) {
var node, child;
for (node = parent.firstChild; node; node = node.nextSibling) {
if (node.nodeType == 1) { // Element
if (node.tagName === tag) {
return node;
}
child = findFirstChild(node, tag);
if (child) {
return child;
}
}
}
return undefined;
}
</script>
</head>
<body>
<table id="mycell" border="1" cellpadding="0" cellspacing="0">
<tr>
<td><button name="obenLinks" onkeydown="myTest(event,undefined,undefined,'mitteLinks','obenMitte')"><img src="C:\Documents and Settings\ing12732\Desktop\html_files\tv-dev\image2.png" ></button></td>
<td><button name="obenMitte" onkeydown="myTest(event,undefined,'obenLinks','mitteMitte','obenRechts')"><img src="C:\Documents and Settings\ing12732\Desktop\html_files\tv-dev\image2.png" ></td>
<td><button name="obenRechts" onkeydown="myTest(event,undefined,'obenMitte','mitteRechts',undefined)"><img src="C:\Documents and Settings\ing12732\Desktop\html_files\tv-dev\image2.png" ></td>
</tr>
</table>
</body>
</html>
Three issues prevented that fiddle from working:
You weren't successfully including jquery. On your system, the path jquery-1.4.4.js may give you jQuery, but jsFiddle is obviously not on your system.
You're trying to access an element before it's been created. Your first line of script code happens right away, but since the script is above the table in the file, it fails because the element isn't there.
Your selector is selecting the table cell; I'm guessing you actually want the button.
Separately:
The second and third button tags weren't closed. The browser probably quietly closes them for you, but one of the first steps in debugging this sort of thign is to make sure your markup is correct and valid. Valid markup make a difference.
The paths "C:\Documents and Settings\ing12732\Desktop\html_files\tv-dev\image2.png" and the like in the images inside the button tags indicate to me that you're trying to do web development without using a web server. Strongly recommend using a web server and proper paths, browsers do various things differently when dealing with local files rather than resources loaded via HTTP.
Strongly recommend using a DOCTYPE. Any DOCTYPE, although my preferred one is HTML5's <!DOCTYPE html> (more).
Here's a corrected fiddle. Hope this helps.

Related

Have image display on mouse over text, delay with hide or hide immediately if mouseover new text

So I have so an image will show when certain text is moused over, it will delay when the mouse is taken off before disappearing and that works just fine. But I have multiple images that can show up depending on the text hovered, I want to have the first image skip it's delay if other text is moused over so it doesn't expand the page and stack the images. Is this possible? Or will I just need to pull the delay off? This is done within JQuery
$("h2").mouseover(function ()
{
let mouseText = $(this).attr("class").split(" ")[0];
switch(mouseText)
{
case "wh-light":
imgID += mouseText;
break;
case "wh-hl-ll":
imgID += mouseText;
break;
case "part-hh-ll":
imgID += mouseText;
break;
}
$(imgID).show();
});
$("h2").mouseout(function ()
{
$(imgID).delay(1000).hide(0);
});
I can supply the HTML but I don't think it is too relevant to this. Thank you in advance for your help!
Without having your template and complete code, I'd have to contrive a full example... but the below snippet should give you a good example of what you'll have to do. You'll need to keep track of the current image and your callback has to know what the current image was when the delay was kicked off and compare it to the current to know whether it should do anything or not.
For this reason I pulled the code into separate javascript functions and used setTimeout instead of the jquery delay(). The documentation on the actual jquery site even mentions that the delay function is limited and has no way to cancel itself and as such should not be treated as a replacement for setTimeout().
Ref https://api.jquery.com/delay/
The .delay() method is best for delaying between queued jQuery effects. Because it is limited—it doesn't, for example, offer a way to cancel the delay—.delay() is not a replacement for JavaScript's native setTimeout function, which may be more appropriate for certain use cases.
Without knowing how you were building the imgID variable or clearing it out... I added the baseImageID and targetImageID variables so that you don't end up just continuously concatenating the new strings onto the end of imgID...
As a last note... I like to make things very modular and verbose when talking through a solution so please dont hate on the extra functions... I think they make the solution easier to understand. The actual implementation can be streamlined...
let baseImageID = 'image-';
let targetImageID = '';
let currentImageID = '';
const hideImageNow = function(imageID) {
$(imageID).hide();
if (currentImageID == imageID) {
currentImageID = '';
}
};
const hideImageLater = function(imageID, delay) {
setTimeout(hideImageNow, delay, imageID);
};
const showImage = function(imageID) {
if (currentImageID != '') {
hideImageNow(currentImageID);
}
currentImageID = imageID;
$(imageID).show();
};
$("h2").mouseover(function() {
targetImageID = baseImageID;
let mouseText = $(this).attr("class").split(" ")[0];
switch (mouseText) {
case "wh-light":
targetImageID += mouseText;
break;
case "wh-hl-ll":
targetImageID += mouseText;
break;
case "part-hh-ll":
targetImageID += mouseText;
break;
}
showImage(targetImageID);
});
$("h2").mouseout(function() {
hideImageLater(currentImageID, 1000);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Search for Text in Loaded HTML document

I have a web page on which my sidebar links will cause an 'external' HTML document to be loaded into a content div.
However after it is successfully loaded and displayed, the loaded HTML content does not appear in the Page Source.
Regardless, I now need to do a client-side Text Search of that 'external' HTML document using a Javascript function.
My webpage looks like the following:
The Search textbox and button are 'outside' of the Content Div (bordered in Red).
And, at the time that one of the link's HTML documents is appearing on-screen the page source looks like:
<!-- Page Content -->
<div id="page-content-wrapper" style="border: thick solid #FF0000; height:660px">
<!--Loaded content goes here-->
</div>
Notice that the 'loaded' HTML document is not showing.
I have found a Javascript function findInPage() which looks promising, but it is not finding the 'loaded' HTML document and its text.
// =====================================
function findInPage() {
var str = document.getElementById("ButtonForm").elements["txtSearch"].value;
var n = 0;
var txt, i, found;
if (str == "")
return false;
// Find next occurance of the given string on the page, wrap around to the
// start of the page if necessary.
if (window.find) {
// Look for match starting at the current point. If not found, rewind
// back to the first match.
if (!window.find(str)) {
while (window.find(str, false, true))
n++;
} else {
n++;
}
// If not found in either direction, give message.
if (n == 0)
alert("Not found.");
} else if (window.document.body.createTextRange) {
txt = window.document.body.createTextRange();
// Find the nth match from the top of the page.
found = true;
i = 0;
while (found === true && i <= n) {
found = txt.findText(str);
if (found) {
txt.moveStart("character", 1);
txt.moveEnd("textedit");
}
i++;
}
// If found, mark it and scroll it into view.
if (found) {
txt.moveStart("character", -1);
txt.findText(str);
txt.select();
txt.scrollIntoView();
n++;
} else {
// Otherwise, start over at the top of the page and find first match.
if (n > 0) {
n = 0;
findInPage(str);
}
// Not found anywhere, give message. else
alert("Not found.");
}
}
return false;
}
Is there some way to modify the function and/or use a different function such that it can find the 'loaded' HTML document and search it for the entered Text?
try selecting the div by id instead of reading the whole window...
document.getElementById('page-content-wrapper').find(str)
This is a duplicate of How to get html elements from an object tag?.
The answer lies in replacing all instances of window.document with document.getElementById('page-content-wrapper').contentDocument, such that the searched document is the page document.
However, the search function you have there is quite broken, it depends on window.find to search the window instead of searching the document text.
You could build a better search function:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Wrapper</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
Body Here
<object id="page-content-wrapper" type="text/html" data="about.html" name="content"></object>
<input id="txtSearch" placeholder="Search..." />
<button onclick="findInPage()">Search</button>
<script>
function findInPage() {
var needle = document.getElementById('txtSearch').value;
var haystack = document.getElementById('page-content-wrapper').contentDocument.body.innerHTML;
var match = haystack.indexOf(needle);
if(match != -1) {
console.log(match);
} else {
console.log('Not Found');
}
}
</script>
</body>
</html>
Fill about.html with anything you want to load and search in.
Note that this just logs the index of the match. It doesn't scroll it into view or select it. With a little more javascript you can do those though. You just have to go through document.getElementById('page-content-wrapper').contentDocument.body
I finally found how to access the HTML content of the Object's innerHTML.
Upon clicking on a specific Sidebar link, using Javascript, I build its Object.
function MenuClick(doc) {
var Tutorial = doc;
var DisplayObj = "<object id='ThisObj' type='text/html' data='" + Tutorial + "' style='min-width:100%; min-height: 101%; overflow: hidden'></object>";
document.getElementById("page-content-wrapper").innerHTML = DisplayObj;
}
But now I have added an ID to the Object ('ThisObj').
With that ID now defined I was able to 'drill-down' into that Object to get to its innerHTML.
var sourceObj = document.querySelector("#ThisObj");
var sourceBody = sourceObj.contentDocument.body
var haystack = sourceBody.innerHTML;
var match = haystack.indexOf(needle);
if (match != -1) {
// --- Text match found ---
} else {
// --- Text match NOT found ---
}
I still need to create the Javascript to highlight the 'found' text and scroll it into view but I'll ask that question in a separate post.
Thanks for your suggestions/advice.

Making Javascript Code Deploy Ready

I need to make this code deploy ready. I can't hard code these URL's in but for some reason any other way of coding this, breaks. Reference this question here: Upon Redirect of Form Submission within iFrame jQuery Not Detecting Updated Src Attribute
I basically need to have the switch check if the location CONTAINS the page name after 'settings/' i.e. iframe-home.php, update.php, or changepassword.php. I think thats how i fix this issue? But i'm not sure how. (Hope that makes sense)
Here is the code:
$(document).ready(function() {
$('iframe#settings-iframe').on('load', function() {
var location = this.contentWindow.location.href;
console.log('location : ', location);
switch (location) {
case "http://localhost/Makoto/profile/settings/iframe-home.php":
console.log(location);
activateHome();
break;
case "http://localhost/Makoto/profile/settings/changepassword.php":
console.log(location);
activatePassword();
break;
case "http://localhost/Makoto/profile/settings/update.php":
console.log(location);
activateName();
break;
}
});
});
Note I assume that you want dynamically check path without host part.
Create new link element, set href to location, compare it to pathname
// replace with this.contentWindow.location.href
var url = "http://localhost/Makoto/profile/settings/iframe-home.php";
/**
* http://localhost/Makoto/profile/settings/iframe-home.php
* will return /Makoto/profile/settings/iframe-home.php
*/
var link = $('<a>', {
href: url
})[0].pathname;
var parts = link.split('/');
var file = parts[parts.length - 1];
console.log(file);
switch (file) {
case "iframe-home.php":
activateHome();
break;
case "changepassword.php":
activatePassword();
break;
case "update.php":
activateName();
break;
}
function activateHome() {console.log('Activating home');}
function activatePassword() {console.log('Activating password');}
function activateName() {console.log('Activating name');}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

How to find out if clicking on an element will lead to a new page?

I have a div which is as follows:
<div id="toGoogle" onclick="window.location='https://www.google.com">Go to google</div>
Clicking on this link takes me to a website (in this case google.com).
(Ofcourse this click method could have been in JS file rather than being inline.)
Now I want to find out all such elements in my webpage which on clicking will lead to another page. I want to find out those page's URLs as well and print them to console.
Is it achievable using JS/Jquery?
On a fully loaded page you can recursively traverse the DOM searching for onClick and href attributes. See the jsfiddle here for an example (and look at the log).
var walkDOM = function(node) {
try {
if (node.getAttribute("onClick") != null) {
console.log(node.getAttribute("onClick"))
}
if (node.getAttribute("href") != null) {
console.log(node.getAttribute("href"))
}
} catch (err) {
console.log("endpoint")
}
node = node.firstChild;
while (node) {
walkDOM(node);
node = node.nextSibling;
}
};
var fb = document.getElementById('facebook')
fb.setAttribute("onclick", "console.log('click')")
var yt = document.getElementById('youtube')
yt.setAttribute("href", "www.youtube.com")
walkDOM(document.documentElement);
https://jsfiddle.net/26wh7zeL/9/
You can then do a regex match for urls if you want.

timing javascript and src changes?

ok so i have this javascript to use the arrow keys to send these javascripts when i press arrowkeys. i have a collaborating script that makes the right('img') command move the image but im trying to change the image as it moves with src changes and delays. Help?
<script type="text/javascript">
document.onkeydown = KeyCheck;
function KeyCheck(event) {
var spacebar=32
var KeyID = event.keyCode;
switch(KeyID) {
case 39:
right('img');
document.getElementById('img').src = 'guyr.png';
setTimeout("right('img');
document.getElementById('img').src = 'runr.png';
setTimeout("right('img');
document.getElementById('img').src = 'guyr.png';",100);",100);
break;
}
}
</script>
Changing the src attribute of an image is going to trigger an asynchronous GET request, and may be slow at first before the browser has cached the images. It looks like you are implementing a game of some sort? Instead of changing the src of a single image, I would keep all of the images hidden initially, and toggle the visibility CSS attribute of images you want to show/hide. That way, you can pre-fetch all of the images that you'll need during load time, and simply show/hide elements as the handlers for your onkeydown events.
If you want to do some sort of a game or animation, try to read a little about it, how to structure your game loop, animations and etc.
But if you are doing just some sort of test try something like this, is not a beautiful code but the idea of an animation should work:
document.onkeydown = KeyCheck;
function KeyCheck(event) {
var spacebar = 32;
var KeyID = event.keyCode;
switch (KeyID) {
case 39:
function guy(fn) {
right('img');
document.getElementById('img').src = 'guyr.png';
setTimeout(function() {
fn(guy);
}, 100);
}
function run(fn) {
right('img');
document.getElementById('img').src = 'runr.png';
setTimeout(function() {
fn(run);
}, 100);
}
guy(run);
break;
}
}
One function calls another, receiving it by parameter, in order to to continue the animation.

Categories