I tried extensive search without luck and I am stuck, So I am hoping someone can assist me in in a code that if a user clicks on a camera feed on a webpage cell it will open that feed in a new window in a larger view.
My friend is a manager of a small data center and the DVR’s are set to view cameras over IP webpage. Problem is over IP webpage you can only see multiple cams at 100px x100px very small and there is no option to view a single cam. He can log in as admin and use the DVR’s control panel to see the single cam but again the view is 100px x 100px. Unless he is at the actual DVR then he can see full screen but not remotely. He has 50 camera’s set up in the server cabinets viewing the lights and temps. Without having the camera feed in larger view it is hard to see the temp indicator on the servers.
As a test I created a webpage with a table 25 rows and 2 columns to make 50 cells. I copied the network feed code form the source code of the webpage and pasted it in a cell. I then added a script to the feed code and gave the “IMG” 600px x 600px. It worked and streamed. Looked good.
Now since one cam worked I copied the code for the other 49 cams, only a few cams will show up under 600px x 600px, but all the cams will show up under 100px x 100px. Scratching my head on this!
The only option that is coming to mind is to have an onclick script in each of the 50 cam feed cells , so that if he clicks on that cam feed it copies the code that in that cell and opens a new window in a larger view.
Any Suggestions?
Here is the script that I put in each cell. The only thing that changes on each cell code is the camera number. I put xxx for the camera ip address for security purposes. It is not my company so I cannot give that information out.
<center>
<img id="jpeg_3" width="600" height="600" class="auto-style5">
<span class="auto-style5">
<script type="text/javascript">
var camera_2 = {
addEvent: function(elem, event, func ){
if (typeof (window.event) != 'undefined')
{elem.attachEvent('on' + event, func);}
else
{elem.addEventListener(event, func, false);}
},
initCamera: function(jpeg, serverUrl, token, id, interval){
this.addEvent(jpeg, 'load', function(){setTimeout(function() {camera_2.showJpegFrame(jpeg, serverUrl, token, id);}, interval);});
this.showJpegFrame(jpeg, serverUrl, token, id);
},
showJpegFrame: function(jpeg, serverUrl, token, id){
jpeg.src = serverUrl+"/Jpeg/"+id+"?authToken="+token+"&"+new Date().getTime();
}
}
camera_2.initCamera(jpeg_2, "http://xxx.xxx.xxx.xxx:8100", "27e4d1dd-058e-47a8-b768-ac8cd6cbe29a", 2, 40);
</script>
Well, as far as I know, what you can do is set an onclick attribute for each of the cells to a window.open() function passing in the cams as parameters for each of the 50 cells. But, that is a "time waster", so you can use the DOM to select all 50 cells by using document.getElementsByTagName() passing in td as a parameter. Then, you can use a for loop to set that like here:
// Locate cells using the DOM:
var cells = document.getElementsByTagName("td");
for(var i = 0; i < cells.length; i++) {
cells[i].onclick = window.open(/* add link to cams */);
}
Hopefully this helps!
Related
I am making a web page reader that needs to inventory the text nodes in the document when it commences reading, because it reads each sentence down the page. So I'm "crawling" the text nodes you could say.
I have a procedure that uses document.createTreeWalker to take that inventory of text nodes.
I haven't figured out the pattern (I think there is one), but at one point when I use document.body, the document that gets pointed to is not the main page, but the document of an iframe. In my current debugging this happens to be a twitter widget, but I suppose it could be anything. This isn't a twitter question, but you can let that inform your answer if you happen to know twitter is doing something extra-ordinary to make document always go to it instead of the top document. In any case, regardless of the source, I need to get the right document.
What do I mean by the right document, you ask me? I'd say the document hosting the selected text, or if no text is selected then the top document.
But my real question is how did this happen, why is this happening? The last time I messed around with the dom was in 2009 when I wrote a web page reader in IE. Times have changed; I'm writing a Chrome extension and web pages seem 1000x more complex these days. Honestly, it's like a circus on the average web page, and most of it you don't see; it's buried beneath and lurking to trip up any robot like my reader.
I don't want to make a hard coded-rule for twitter, or any other widget. There must be a thousand such things that can end up adding / injecting themselves into the page. I literally can't get into the business of custom rules.
this.LoadAllTextNodes = function () {
this.AllTextNodes = textNodesUnder(document.body); // at some point, this document starts referring to something other than the top document. How did the definition of "document" change?
}
function textNodesUnder(root) {
var textNodes = [];
if (root.nodeType == 3)
textNodes.push(root);
else {
var treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, getTextElements, false);
var node;
while (node = treeWalker.nextNode())
textNodes.push(node);
}
return textNodes; // Array
}
function getTextElements(node) {
if (['SCRIPT', 'STYLE'].indexOf(node.parentNode.tagName) !== 0 && node.nodeValue !== '') //filter out script elements and empty elements
return NodeFilter.FILTER_ACCEPT
else
return NodeFilter.FILTER_SKIP
}
The web page I'm testing on happens to be https://code.visualstudio.com/blogs/2016/02/23/introducing-chrome-debugger-for-vs-code. The fact that the topic matter of the page deals with Chrome debugging is just a coincidence. It has no relation to the question. I'm just adding it in the event you'd like to see the source of the page.
<iframe id="twitter-widget-0" scrolling="no" frameborder="0" allowtransparency="true" class="twitter-follow-button twitter-follow-button-rendered" title="Twitter Follow Button" src="https://platform.twitter.com/widgets/follow_button.d59f1863bc12f58215682d9908af95aa.en.html#dnt=false&id=twitter-widget-0&lang=en&screen_name=code&show_count=true&show_screen_name=true&size=m&time=1474137195557" style="position: static; visibility: visible; width: 191px; height: 20px;" data-screen-name="code"></iframe>
In a chrome extension, the content scripts get run for each and every window, including the top window and all iframes. In this way, Chrome extension access trumps cross-site restrictions which a script running in a script tag may have.
This was instantiating a context for each frame which pointed the duplications of my extension code running in that frame to their respective documents, not the top window's document.
It runs the code in parallel. In my case each frame was queuing up content to be read without me knowing it, for the singleton window.speechSynthesis to read.
The fix was simple; just don't run in non-top windows:
if (window != window.top) return; // don't run in frames
I have an HTML issue. This is for a intro web programming class that I have no clue what is going on.
Some web pages are written in a comibination of HTML and JavaScript. In this Application, you will create a video game using HTML and JavaScript. The idea of the game is that an image will move on screen randomly and the player will try to click the image as many times as possible before time runs out. The score will increase each time the player successfully clicks the image.
Perform the following steps:
Create a Web page called “game.html” and place it in the root directory. To that page, add a layer, which will be treated as an object, with an image for its contents. Add another image which will start the game when clicked on. When the game starts, the layer, including the image, will move randomly in any direction but not more than 10 pixels. The layer will not leave the visible screen space. You may assume an 800x600 resolution setting. Be creative when choosing your images, but avoid anything that may be considered explicit or offensive.
Add a timer, or loop, to determine how long the game will run. This should be set to 30 seconds. You will need to experiment to determine how many times a loop must repeat to make it last 30 seconds. One of the ways to accomplish this is by using the command “setTimeout()” which executes a code some time in the future. As an example, the following command will call the function “FlyLogoIE” exactly 50 milliseconds after this line is executed:
setTimeout("FlyLogoIE()",50);
The game should proceed as follows:
The score starts at 0. Each time the user clicks the image, one point is added to the score. This score is constantly displayed either on the status bar or somewhere in the background.
On every click, the layer also moves randomly, by not more than 10 pixels, to another part of the screen.
The game continues until the time runs out. Optionally, a dialog box appears telling the user his or her final score. The user now has the option to restart the game by clicking the “Start” image again.
For an extra challenge, implement levels of difficulty for the game. Add instructions that prompt the user for the level of difficulty at which he or she wants to play. A higher level of difficulty would correspond to either faster motion, a smaller target, or both. Perform this step only if all other requirements are met and you still have time before the due date. No extra points will be given to you for this step.
Add a link from your homepage to this web page.
Test the code thoroughly before publishing it.
Here is what I've done so far, but am lost. Can you help?
<Layer Name="game" LEFT=400 TOP=500>
<a href="#" onClick="return moveGame()";> Start! </a>
<br>
<IMG <span id= "Game" style= "left: 100px; top 100px; position; absolute;" SRC="/pics/drone.jpg" alt="drone" width="100">
<script>
<SCRIPT LANGUAGE="javascript">
function moveGame(){
var x;
x = Math.floor(Math.random()*4+1);
if (x==4 && game.style.pixelLeft>=10) {game.style.pixelLeft-=10;}
if (x==3 && game.style.pixelRight>=5) {game.style.pixelRight-=5;}
if (x==2 && game.style.pixelUp>=10) {game.style.pixelUp-=10;}
if (x==1 && game.style.pixelDown>=5) {game.style.pixelDown-=5;}
setTimeout("moveGame()",50);
}
</script>
</layer>`
Start of with something like this:
JS:
// timer
var gameLength = 30 * 1000; // 30 seconds
function startGame(){
runGame();
setTimeout( endGame, gameLength );
}
function endGame(){
// stop listening for click
}
function runGame(){
// register click listeners
// main game loop
}
var myElement = {
htmlElement: "img",
onClick: function(){ /* do stuff */ },
moveRandomly: function(){ /* do stuff */ },
state: 'listening' // or not
}
var viewPort = {
htmlElement: 'div',
draw: function(){ /* do stuff */ }
}
This is really just to get you started. There is more and it could be written better. You need to Object Orient this stuff so that each component is easy to understand, easy to modify, and then you'll be on your way in programming.
Part of learning programming is the struggle. Most everyone has been there. Don't give up.
For a mockup-webpage used for research on interaction on websites, I created a mockup message-stream using JavaScript. This message stream is loaded in an IFrame and should show images at pre-set intervals and scroll to the bottom of the page after placing a new image at the bottom of the page. Getting the images to appear is working quite well with the provided script. However, both Chrome and IE seem to have trouble scrolling the page to the bottom. I would like to scroll to the bottom of the page as soon as the image is attached, but have for now added a 5 ms delay because that seemed to work sometimes. My questions are:
Is it okay to use document.body.scrollHeight for this purpose?
Can I make the scroll occur directly, or do I need a small interval before scrolling?
How to make the code scroll to the bottom of the IFrame directly after adding an image?
The following functions are used and trypost() is started onLoad:
function scrollToBottom(){
window.scrollBy(0,document.body.scrollHeight);
}
function trypost(){
point = point + 1;
if(point < interval.length){
//create and append a new image
var newImg = document.createElement("IMG");
newImg.src = "images/"+images[point]+".png";
document.getElementById('holder').appendChild(newImg);
//create and append a return
var br = document.createElement("br");
document.getElementById('holder').appendChild(br);
//time scroll to bottom (after an arbitrary 5 seconds)
var stb = window.setTimeout(scrollToBottom, 5);
//time next post
var nextupdate = interval[point]*400;
var tp = window.setTimeout(trypost, nextupdate);
}
}
My script section contains at least the following variables:
var point = -1;
var interval = [10, 10, 15];
var images = ["r1", "a1", "r2"];
This questions is a continuation of the project described in How to proper use setTimeout with IE?
To answer one of your questions, document.body.scrollHeight is appropriate for this purpose, but not if you're actually calling for document. That'll give you the scroll height of the document the iFrame is in, not the iFrame's document. The iFrame's document can be called upon by [insert variable for iFrame here].contentDocument.
Here's how I did it (and by that, I mean I tested it out with my own stuff to make sure it worked):
let i = document.querySelector('iframe')
i.contentWindow.scrollTo(0, i.contentDocument.body.scrollHeight);
That being said, the other answer by Thomas Urban will also work most of the time. The difference is only if your page has a really long scroll height. Most pages won't be longer than 999999 (for all I know that's impossible and that's why they chose that number), but if you have a page longer than that, the method I showed here would scroll to the bottom and the 999999 would scroll to somewhere not yet at the bottom.
Also note, if you have more than one iFrame, you're gonna want to query it in a different way than I did, like by ID.
Scrolling to bottom is always like scrolling to some ridiculously large top offset, e.g. 999999.
iframe.contentWindow.scrollTo( 0, 999999 );
In addition see this post: Scrolling an iframe with javascript?
If scrolling occurs too early it's probably due to images not being loaded yet. Thus, you will have to scroll as soon as added image has been loaded rather than on having placed it. Add
newImg.onload = function() { triggerScrolling(); };
after creating newImg, but before assigning property src.
If several events are required to trigger scrolling you might need to use some "event collector".
function getEventCollector( start, trigger ) {
return function() {
if ( --start == 0 ) { trigger(); )
};
}
You can then use it like this:
var collector = getEventCollector( 2, function() { triggerScrolling(); } );
newImg.onload = collector;
window.setTimeout( collector, 100 );
This way triggerScrolling() is invoked after 100ms at least and after image has been loaded for collector has to be invoked twice for triggerScrolling() being invoked eventually.
I'm making a html-5 based report generator. I created a button to upload a [HTML] page containing multiple paragraphs and tables, which is continuous.
Now my task is to display the whole contents into separated a4-sized pages, just like in Microsoft Word.]
This is the sketch: >>>LINK<<<
Here are part of my codes.
function xx (){
var fi = document.getElementById('fi').files[0];
reader.onload = function (e){
var reader = new FileReader();
var inner ="";
inner += this.result;
inn.innerHTML ="<center><div class='bg' id='0'><div id='testmain'>"+inner+"</div></div></center>";
}
reader.onerror = function (e){
dd.innerHTML = "error<br>";
}
reader.readAsText(fi);
}
After displaying the result of pages, users can click a specific part of the paper, just like a paragraph, then a pagebreak is created and the pages changes, the remaining content are pushed starting from top of next page.
Could you please give me some ideas about how to realize it?
Instead of using comments as chat to present my suggestion, here's my answer:
I once tried to do such a thing, back in html4. Here's the logic I was using. Create a div that has the exact size of your page CONTENT (after margins and all) put all your content in it and cycle through its direct children. If the current child's bottom is lower than his parent, take it and all the following children and put them in a new div CONTENT. Rinse and repeat.
For this, you will need to calculate the height of the container and cross-check it against the offset+height of the elements. My vanillaJS is a bit rusty as for browser specifics and all... So I will display the logic using jQuery but most of it can easily be made in pure JS. The code will assume that we have a div.page that has the right CSS to make it exactly the size of a content page, and that will not resize to content (overflow:hidden) and the document will contain one of those div with all the content of what should be in the pages...
$(document).ready(function(){
var $page = $('div.page');
var newPage = true;//To track if we loop
while(newPage){
newPage = false;
$page.children().each(function(){
if($(this).offset().top+$(this).outerHeight() > $page.offset().top+$page.height()){
$page = $('<div>').addClass('page').appendTo('body');
$(this).nextAll().appendTo($page);
$(this).prependTo($page);//Don't forget the element too.
newPage = true;
}
});
}
});
I have a report generated by Oracle Apex (A UI tool operating against the Oracle database). I have customized it to have a hyperlink on each record, which when clicked opens a detail report in an iframe right under the current record. This, I am doing by using the Javascript insertRow method on the html table element (Condensed Javascript code below. Oracle APEX allows use of JS/Jquery)
var pTable= html_CascadeUpTill(t,'TABLE');
var myNewRow = pTable.insertRow(pTR.rowIndex+1);
var myNewCell = myNewRow.insertCell(0);
myNewCell.innerHTML = '<iframe src="detail report url" height="0"></iframe>';
In order to resize the height of the iFrame that is different for different detail records, I have the following code in the document).ready(function() of the page
$('iframe').load(function()
{
setTimeout(iResize, 1000);
}
function iResize()
{
// Iterate through all iframes in the page.
for (var i = 0, j = iFrames.length; i < j; i++)
{
var y=(iFrames[i].contentWindow || iFrames[i].contentDocument);
if (y.document)y=y.document;
var docHt = getDocHeight(y);
if (docHt) iFrames[i].height = docHt + "px";
}
}
);
Without the setTimeout call to iResize function, the iframe resize is not happening. But this setTimeout is adding a delay in the resized iframe to appear which I want to avoid. Is there a way to do this? All the related posts/articles I have seen online deal with iframes that are built into the page but not generated on-the-fly as in my case.
Let me know if you need more information. Please help. Thank you.
You should consider putting the details in a <div> block, then showing or hiding the <div> with JQuery. You can set dimensions for your block with CSS, or just let the content flow normally inside of the block. Sounds like a much simpler way to achieve the same effect.
The issue is that if you perform the resize too soon it will get the dimensions of the child document before it has been fully rendered, hence the use of a timer.
If your detail reports are other APEX pages that you control, then you could call the iResize function from the "Execute when page loads" section of the detail page:
parent.iResize();
That seems to work for me.
It sounds to me like the iframes don't even exist when the page first loads.
Instead of calling the iResize function on page load and then every second you could place the call to iResize in the code that creates the iframe.