styling hover state of a javascript variable - javascript

I am attempting to style a hover state of a variable I have created. I'm pretty new to javascript, so hopefully one of you can help me out.
here is the script:
controlDiv.style.padding = '5px';
var controlUI = document.createElement('DIV');
controlUI.style.height = '19px';
controlUI.style.backgroundColor = '#F9F9F9';
controlUI.style.background = 'linear-gradient(top, #ffffff 0%,#f3f3f3 50%,#ededed 51%,#ffffff 100%)';
controlUI.style.boxShadow = '2px 2px 2px 1px #999';
controlUI.style.borderRadius = '2px';
controlUI.style.borderStyle = 'solid';
controlUI.style.borderWidth = '1px';
controlUI.style.borderColor = '#9BADCF';
controlUI.style.cursor = 'pointer';
controlUI.style.textAlign = 'center';
controlUI.title = 'Click Me';
controlDiv.appendChild(controlUI);
what I am wanting to do is to write script to set different style properties for the div created by the variable controlUI, when the mouse hovers over said div.

Since you are working purely with JavaScript, instead of with CSS, you will need to do this the hard way, namely with events. With jQuery, it would be:
$(controlUI).hover(
function onMouseEnter() {
this.style.backgroundColor = "blue";
},
function onMouseLeave() {
this.style.backgroundColor = "#F9F9F9";
}
);
Without jQuery, you would need to use DOM events, which is a pain because they are not cross-browser compatible with IE less than 9, as discussed extensively in this MDC article. The code ends up looking something like:
var crossBrowserAEL = controlUI.addEventListener ? "addEventListener" : "attachEvent";
controlUI[crossBrowserAEL]("mouseover", function () {
controlUI.style.backgroundColor = "blue";
});
controlUI[crossBrowserAEL]("mouseout", function () {
controlUI.style.backgroundColor = "#F9F9F9";
});

Try to avoid setting inline styles
Setting inline styles is very bad practice because it's hard to maintain while you have to look inside code to decipher where certain styles are set. I'm not even trying to touch browser differences that may become a real pain if you'll be using pure DOM+Javascript.
A better approach: use CSS classes
Instead of setting particular individual styles on your created element (and writing several lines of code) it's much simpler and better to just apply a CSS class to your element:
controlDiv.className = "some-class";
and then define everything about this class in the CSS file that defines all styles. This will also make it very simple to define related styles (like hover, visited, ::before etc.)

Related

How to display html as firefox panel without using sdk

I need to display html elements as contents of a popup panel using javascript in my firefox addon.
Displaying popup using SDK is what I'm looking for but I don't want to use SDK.
panel:
<popupset id="mainPopupSet">
<panel id="htmlPanel" type="arrow">
i want to use html elements like p,div,span, etc here.
</panel>
</popupset>
javascript to open panel:
document.getElementById('htmlPanel').innerHTML = 'my custom contents';
document.getElementById('htmlPanel').openPopup(null, "before_start", 0, 0, false, false);
it seems some elements are allowed but with different behavior! i also need to set CSS for elements inside panel.
I figure it out how to do it using an iframe
changed the XUL as follow:
<popupset id="mainPopupSet">
<panel id="htmlPanel" type="arrow">
<html:iframe id="htmlContainer"/>
</panel>
</popupset>
and create a javascript function to set html contents:
function setupPanel(contents, width, height)
{
var iframe = document.getElementById("htmlContainer");
iframe.setAttribute("src","data:text/html;charset=utf-8," + escape(contents));
iframe.width = width || 300; //default width=300
iframe.height = height || 300; //default height=300
}
and usage:
setupPanel("<p>this is raw HTML.</p>");
document.getElementById('htmlPanel').openPopup(null, "before_start", 0, 0, false, false);
thanks for your hints.
With animation can copy paste to scratchpad to run it.
var win = Services.wm.getMostRecentWindow('navigator:browser');
var panel = win.document.createElement('panel');
var props = {
type: 'arrow',
style: 'width:300px;height:100px;'
}
for (var p in props) {
panel.setAttribute(p, props[p]);
}
win.document.querySelector('#mainPopupSet').appendChild(panel);
panel.addEventListener('popuphiding', function (e) {
e.preventDefault();
e.stopPropagation();
//panel.removeEventListener('popuphiding', arguments.callee, false); //if dont have this then cant do hidepopup after animation as hiding will be prevented
panel.addEventListener('transitionend', function () {
//panel.hidePopup(); //just hide it, if want this then comment out line 19 also uncomment line 16
panel.parentNode.removeChild(panel); //remove it from dom //if want this then comment out line 18
}, false);
panel.ownerDocument.getAnonymousNodes(panel)[0].setAttribute('style', 'transform:translate(0,-50px);opacity:0.9;transition: transform 0.2s ease-in, opacity 0.15s ease-in');
}, false);
panel.openPopup(null, 'overlap', 100, 100);
to display html in it, do createElementNS('html namespace i cant recall right now','iframe') then set the src of this to the html you want it to display
the type:'arrow' here is important
Since this appears to be an overlay of browser.xul, if your panel will display static content or a simple template, you can take advantage of the fact that the XHTML namespace is already declared.
<popupset id="mainPopupSet">
<panel id="htmlPanel" type="arrow">
<html:div id="htmlplaceholder">
<html:p>Lorem ipsum</html:p>
<html:p>foo <html:strong>bar</html:strong></html:p>
</html:div>
</panel>
</popupset>
The Add-on SDK hosts the html content inside an iframe, perhaps you should consider this for more complex cases.

Javascript Extensibility

I've a script, which manipulates with canvas. I call it like this:
namespace.module.do(canvas, paramString);
I'd like to move the call to the canvas itself, so it'll somewhat similar to:
<canvas namespace.module.dobehavior=paramString />
Can I do it with JS and if not how close can I get to it?
The canvas is a DOM object, so you could attach functions to it. In your example:
document.getElementsByTagName("canvas")[0].namespace.module.dobehavior = function(paramString) { ... code ... };
(obviously, document.getElementsByTagName("canvas")[0].namespace and document.getElementsByTagName("canvas")[0].namespace.module would need to be an object, so you might need to do
document.getElementsByTagName("canvas")[0].namespace = { module : { dobehavior : function(paramString) { ... } } };
And then if you had the canvas element somewhere (possibly also through var canvas = document.getElementsByTagName("canvas")[0];) you could do
canvas.namespace.module.dobehavior("someString");
Is that what you mean?
In JQuery
$(function() {
$("canvas[ns.mod.colorBehavior]") {
var color = $(this).attr("ns.mod.colorBehavior");
if (color == "red") {
var context = this.getContext('2d');
context.fillStyle = "#ff0000";
context.fillRect(0,0,width,height);
}
}
}
Where width and heigh are the width and height of your canvas element (or a higher value like 10000).

converting Div to Canvas options [duplicate]

It would be incredibly useful to be able to temporarily convert a regular element into a canvas. For example, say I have a styled div that I want to flip. I want to dynamically create a canvas, "render" the HTMLElement into the canvas, hide the original element and animate the canvas.
Can it be done?
There is a library that try to do what you say.
See this examples and get the code
http://hertzen.com/experiments/jsfeedback/
http://html2canvas.hertzen.com/
Reads the DOM, from the html and render it to a canvas, fail on some, but in general works.
Take a look at this tutorial on MDN: https://developer.mozilla.org/en/HTML/Canvas/Drawing_DOM_objects_into_a_canvas (archived)
Its key trick was:
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var data = '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">' +
'<foreignObject width="100%" height="100%">' +
'<div xmlns="http://www.w3.org/1999/xhtml" style="font-size:40px">' +
'<em>I</em> like ' +
'<span style="color:white; text-shadow:0 0 2px blue;">' +
'cheese</span>' +
'</div>' +
'</foreignObject>' +
'</svg>';
var DOMURL = window.URL || window.webkitURL || window;
var img = new Image();
var svg = new Blob([data], {type: 'image/svg+xml;charset=utf-8'});
var url = DOMURL.createObjectURL(svg);
img.onload = function () {
ctx.drawImage(img, 0, 0);
DOMURL.revokeObjectURL(url);
}
img.src = url;
That is, it used a temporary SVG image to include the HTML content as a "foreign element", then renders said SVG image into a canvas element. There are significant restrictions on what you can include in an SVG image in this way, however. (See the "Security" section for details — basically it's a lot more limited than an iframe or AJAX due to privacy and cross-domain concerns.)
Sorry, the browser won't render HTML into a canvas.
It would be a potential security risk if you could, as HTML can include content (in particular images and iframes) from third-party sites. If canvas could turn HTML content into an image and then you read the image data, you could potentially extract privileged content from other sites.
To get a canvas from HTML, you'd have to basically write your own HTML renderer from scratch using drawImage and fillText, which is a potentially huge task. There's one such attempt here but it's a bit dodgy and a long way from complete. (It even attempts to parse the HTML/CSS from scratch, which I think is crazy! It'd be easier to start from a real DOM node with styles applied, and read the styling using getComputedStyle and relative positions of parts of it using offsetTop et al.)
You can use dom-to-image library (I'm the maintainer).
Here's how you could approach your problem:
var parent = document.getElementById('my-node-parent');
var node = document.getElementById('my-node');
var canvas = document.createElement('canvas');
canvas.width = node.scrollWidth;
canvas.height = node.scrollHeight;
domtoimage.toPng(node).then(function (pngDataUrl) {
var img = new Image();
img.onload = function () {
var context = canvas.getContext('2d');
context.translate(canvas.width, 0);
context.scale(-1, 1);
context.drawImage(img, 0, 0);
parent.removeChild(node);
parent.appendChild(canvas);
};
img.src = pngDataUrl;
});
And here is jsfiddle
Building on top of the Mozdev post that natevw references I've started a small project to render HTML to canvas in Firefox, Chrome & Safari. So for example you can simply do:
rasterizeHTML.drawHTML('<span class="color: green">This is HTML</span>'
+ '<img src="local_img.png"/>', canvas);
Source code and a more extensive example is here.
No such thing, sorry.
Though the spec states:
A future version of the 2D context API may provide a way to render fragments of documents, rendered using CSS, straight to the canvas.
Which may be as close as you'll get.
A lot of people want a ctx.drawArbitraryHTML/Element kind of deal but there's nothing built in like that.
The only exception is Mozilla's exclusive drawWindow, which draws a snapshot of the contents of a DOM window into the canvas. This feature is only available for code running with Chrome ("local only") privileges. It is not allowed in normal HTML pages. So you can use it for writing FireFox extensions like this one does but that's it.
You could spare yourself the transformations, you could use CSS3 Transitions to flip <div>'s and <ol>'s and any HTML tag you want. Here are some demos with source code explain to see and learn: http://www.webdesignerwall.com/trends/47-amazing-css3-animation-demos/
the next code can be used in 2 modes, mode 1 save the html code to a image, mode 2 save the html code to a canvas.
this code work with the library: https://github.com/tsayen/dom-to-image
*the "id_div" is the id of the element html that you want to transform.
**the "canvas_out" is the id of the div that will contain the canvas
so try this code.
:
function Guardardiv(id_div){
var mode = 2 // default 1 (save to image), mode 2 = save to canvas
console.log("Process start");
var node = document.getElementById(id_div);
// get the div that will contain the canvas
var canvas_out = document.getElementById('canvas_out');
var canvas = document.createElement('canvas');
canvas.width = node.scrollWidth;
canvas.height = node.scrollHeight;
domtoimage.toPng(node).then(function (pngDataUrl) {
var img = new Image();
img.onload = function () {
var context = canvas.getContext('2d');
context.drawImage(img, 0, 0);
};
if (mode == 1){ // save to image
downloadURI(pngDataUrl, "salida.png");
}else if (mode == 2){ // save to canvas
img.src = pngDataUrl;
canvas_out.appendChild(img);
}
console.log("Process finish");
});
}
so, if you want to save to image just add this function:
function downloadURI(uri, name) {
var link = document.createElement("a");
link.download = name;
link.href = uri;
document.body.appendChild(link);
link.click();
}
Example of use:
<html>
<head>
</script src="/dom-to-image.js"></script>
</head>
<body>
<div id="container">
All content that want to transform
</div>
<button onclick="Guardardiv('container');">Convert<button>
<!-- if use mode 2 -->
<div id="canvas_out"></div>
</html>
Comment if that work.
Comenten si les sirvio :)
The easiest solution to animate the DOM elements is using CSS transitions/animations but I think you already know that and you try to use canvas to do stuff CSS doesn't let you to do. What about CSS custom filters? you can transform your elements in any imaginable way if you know how to write shaders. Some other link and don't forget to check the CSS filter lab.
Note: As you can probably imagine browser support is bad.
function convert() {
dom = document.getElementById('divname');
var script,
$this = this,
options = this.options,
runH2c = function(){
try {
var canvas = window.html2canvas([ document.getElementById('divname') ], {
onrendered: function( canvas ) {
window.open(canvas.toDataURL());
}
});
} catch( e ) {
$this.h2cDone = true;
log("Error in html2canvas: " + e.message);
}
};
if ( window.html2canvas === undefined && script === undefined ) {
} else {.
// html2canvas already loaded, just run it then
runH2c();
}
}

Inserting a Div Into another Div?

Im creating a web app and would like to know why the following code is not working. It first creates a element which is then added to the body. I then create another Div element which i would like to place inside the first div element that i created.
Im using MooTools classes to create and initialize objects and it works fine but i just cant seem to get the following code to work. The code is inside aninitialize: function() of a class:
this.mainAppDiv = document.createElement("div");
this.mainAppDiv.id = "mainBody";
this.mainAppDiv.style.width = "100%";
this.mainAppDiv.style.height = "80%";
this.mainAppDiv.style.border = "thin red dashed";
document.body.appendChild(this.mainAppDiv); //Inserted the div into <body>
//----------------------------------------------------//
this.mainCanvasDiv = document.createElement("div");
this.mainCanvasDiv.id = "mainCanvas";
this.mainCanvasDiv.style.width = "600px";
this.mainCanvasDiv.style.height = "400px";
this.mainCanvasDiv.style.border = "thin black solid";
document.getElementById(this.mainAppDiv.id).appendChild(this.mainCanvasDiv.id);
As you can see it first creates a div called "mainBody" and then appends it the document.body, This part of the code works fine. The problem comes from then creating the second div and trying to insert that usingdocument.getElementById(this.mainAppDiv.id).i(this.mainCanvasDiv.id);
Can anyone think of a reason the above code does not work?
Instead of:
document.getElementById(this.mainAppDiv.id).appendChild(this.mainCanvasDiv.id);
Just do:
this.mainAppDiv.appendChild(this.mainCanvasDiv);
This way you are appending the mainCanvesDiv directly to the mainAppDiv. There is no need to getElementById if you already have a reference to an element.
Do like this:
this.mainAppDiv.appendChild(this.mainCanvasDiv);
why do you use mootools yet revert to vanilla js?
this.mainAppDiv = new Element("div", {
id: "mainBody",
styles: {
width: "100%",
height: "80%",
border: "thin red dashed"
}
});
this.mainCanvasDiv = new Element("div", {
id: "mainCanvas",
styles: {
width: 600,
height: 400,
border: "thin black solid"
}
}).inject(this.mainAppDiv);
this.mainAppDiv.inject(document.body);

javascript font size not working

why this don´t work:
function rp_insertTable() {
FM_log(3,"rp_insertTable() called");
var farmTable = dom.cn("table");
var ftableBody = dom.cn("tbody");
var i;
var maximize = GM_getValue("Maximize_" + suffixGlobal, 0);
farmTable.className = "FMtbg";
farmTable.id = "farmMachineTable";
farmTable.setAttribute('cellpadding', 2);
farmTable.setAttribute('cellspacing', 1);
farmTable.style.marginBotton = "12px";
farmTable.style.font = "bold 12px arial,serif";
the font does change in format, but the font size is not working, I can put 100px and it deosn´t change anything, why is that?
Why don't you try doing:
farmTable.style.fontSize = "12px"; ?
Accordingly XHTML.com your syntax is off:
Edit, more descriptive: You missed the font-style property in the list, you only had font-weight.
http://xhtml.com/en/css/reference/font/
Also, font is a shorthand, if you just want to set one indeed use the fontSize property.
It probably changes because your font is now no longer well-formed CSS and it sets it back to default.

Categories

Resources