work on asp.net vs05.i want to set mouse event on gridview
Then based on the event type if event is mouseover it zoom the row else if the event is mouseout it changes the row’s zoom back to its original before the event occurred.
if (e.Row.RowType == DataControlRowType.DataRow )
{
e.Row.Attributes.Add("onmouseover","MouseEvents(this, event)");
e.Row.Attributes.Add("onmouseout", "MouseEvents(this, event)");
}
<script type = "text/javascript">
function MouseEvents(objRef, evt)
{
if (evt.type == "mouseover")
{
objRef.style.height = "100%";
objRef.style.width = "100%";
}
</script>
the above code does not act in this way,Whatever i want .I want zoom in and zoom out?
Although you'd be better off using a JavaScript library to handle this in the long term, I'll just explain how to achieve the zoom effect you're looking for to keep things simple.
Your markup and .NET code is correct the way it is. You'll need to adjust your JavaScript and add some CSS do what you're looking for.
At it's most basic level, what you want to do is this:
function MouseEvents(objRef, evt) {
if (evt.type == "mouseover") {
objRef.style.fontSize= "120%";
} else {
objRef.style.fontSize= "100%";
}
}
Changing the height and width like you did in your question will only change the dimensions of the cells, not the contents. The easiest way to achieve a zoom effect is to increase the font size.
Once you've done this, you need to consider how the flow of your table will be affected by making the font bigge. As the font gets bigger, the height & width of each cell will increase. This can make the layout jump around and become annoying to deal with.
To address height shifts, change the line-height in your table cells. This will ensure that rows don't shift up or down as you hover over them.
To deal with the width shifts, the width of your cells (or better, the table itself) should be set to be large enough that the table itself won't grow as the row needs more space to fit the larger text.
This is how you would address those issues:
tr {line-height: 25px}
/* change the "200px" to be whatever your table needs */
table { 200px }
To take this even further, we can improve the JavaScript to be more flexible...
It is a bad practice to include presentation details in JavaScript. Think about what happens if you need to change the look of a hovered row in the future. If this happens, you'll have to modify code logic, which can be annoying to deal with as your app grows. Presentational rules should be in one place, a central style sheet.
It is better to have JavaScript swap out CSS classes instead. Then you can put your "hover" styling rules in a CSS file. To do this you would change your JavaScript to the following:
function MouseEvents(objRef, evt) {
if (evt.type == "mouseover") {
objRef.className = "hover";
} else {
objRef.className = "";
}
}
Once you've done this, now you can move your "zoom" styles into CSS as the following:
.hover{font-size: 120%}
The JavaScript just adds or removes this CSS class. Anything without this class will have the default 100% font size, and then when that class is added, it will get bigger. Keeping things in CSS also allows you to add other things like changing the background color of the row, the font-weight, the text color, etc. so it is a good idea to do it like this.
A live demo of the code in this answer can be found here: http://jsbin.com/ideve
As I mentioned in the beginning of my post though, you'll be better off using a JavaScript framework like jQuery, Dojo, YUI, MooTools or Prototype. This will allow you to completely separate your JavaScript code from your markup (and also your ASP.NET code logic), making it much easier to work with. It also allows you to avoid the perils of cross-browser quirks in JavaScript events, which I'm assuming is why you're using HTML attributes for triggering JavaScript events in the first place, since it's much easier than doing it from scratch entirely in JavaScript with no frameworks.
Related
edit
Since originally posting this question, I've gone down a couple more paths trying to solve the issue. It's still not solved, but now my questions are different. The original question is below, and then I'll add a section below that with updates.
original question
I'm working on a Rails 4 application and having some trouble with JavaScript and the Chartkick gem.
I have two JavaScript functions that make it so that a user can click an icon and an element will drop down below the icon/appear on the page, and the icon will switch from a right-pointing arrow to a down-pointing arrow. The code is this:
function ReverseDisplay(d)
{
if(document.getElementById(d).style.display == "none")
{
document.getElementById(d).style.display = "block";
}
else
{
document.getElementById(d).style.display = "none";
}
}
$(function() {
$('.toggle-icon').click(function() {
$(this).find('i').toggleClass('fa-arrow-circle-o-right fa-arrow-circle-o-down');
});
});
And the haml:
%a{href: "javascript:ReverseDisplay('toggle-stats#{item.id}')", class: 'toggle-icon'}
%i.fa.fa-arrow-circle-o-right
%div{id: "toggle-stats#{item.id}", style: "display: none;"}
= the items to be displayed
It works. However, I expect the items that drop down to take up the full width of the page, like so:
But instead, when I first click the toggle icon, they show up squished, like this:
If I then resize the browser just a tiny bit, the graph pops out to full-width, and it stays that way no matter what I do from there. I can't figure out how to get ahold of the generated mark-up, because this chart comes from Chartkick, as a gem. The generated html in the browser has this line:
<div dir="ltr" style="position: relative; width: 300px; height: 300px;">
Where the width: 300px is what's being changed to width: 1000px when I change the browser size. I don't have to change the browser size permanently or significantly. Once that width has changed to 1000px the first time it stays there - but the minute I refresh the page and click the icon to toggle the chart again, it's back to 300px. I don't know how to hook into this div, because it's generated by the gem and I don't know how to add a class to it. I've tried adding styling to a parent element that ensures all of that parent elements' children are width: 100%, but that doesn't do anything.
Anyway, I don't think that adding a class to it is the solution here. I just have no idea what is - I don't JavaScript incredibly well. I'm pretty much completely new to all front-end work as a whole. What's going on here, and how can I make these charts always be the full width of the page when they're toggled?
Notes: Am testing this in Chrome. I tested in Firefox and it does the same thing.
OK, I'm starting to wonder if this has something to do with the fact that I'm using a JavaScript function in order to capture dynamic item IDs - a page may have any number of these toggle-able charts, and so calling a jQuery function on each id seems impossible, because I don't know what ID is.
I removed the jQuery call, however, and the problem persists.
One of those times when rubber-ducking the Stack Overflow question box has not yet answered my question. So I guess I'll submit and hope for outside help here. :/
adjusted question
This question in the Github issues for Chartkick has lead me down a different path. The solution is not necessarily in attempting to restyle the charts at all. Instead, what I'm trying to do is trigger a resize event, because the chart automatically regenerates when the browser window is resized. This is both what's causing the problem and where the solution seems to lie.
My code:
.row
.col-sm-12
%h3.title-block.second-child
Stats by Video
.panel-groupd#faqList
- #claim.presenter.videos.each_with_index do |video, index|
.panel.panel-default
.panel-heading
%h4.panel-title
%a.chart{data: { toggle: "collapse", parent: "#faqList" }, href: "#video#{index}" }
= "'#{video.title}' at #{video.event.display_name} on #{display_date(video.recorded_at)}"
%div.panel-collapse.collapse{id: "#video#{index}"}
.panel-body
- if video.impressions.count > 0
%h4
Impressions by Hours (24 hours)
= line_chart video.impressions.group_by_day(:created_at, range: 1.day.ago...Time.now).count
...a couple more charts
:javascript
$(".chart").click(function() {
window.dispatchEvent(new Event('resize'));
});
So the intention here is that when I click the .panel-heading, this both drops down the .panel-body with the charts in it and resizes the window, which makes the charts resize correctly (or, rather, should).
It kind of works, in that, when I first click the .panel-heading trigger, it does not resize the charts, but when I click it again, the charts are resized perfectly for a split second... just before they become hidden from view again. :(
I've tried adding a time out to the javascript, like so:
:javascript
$(".chart").click(function() {
setTimeout(1000);
window.dispatchEvent(new Event('resize'));
});
But it doesn't appear to do anything at all.
So what I'm wondering here is how to get this resize event to work once the dropdown .panel-body is out so that the charts will resize appropriately on their own.
Here's a screen cast of the current problem, in case I didn't describe it clearly enough:
https://youtu.be/5quMGABoDs8
I don't know anything about Ruby or Chartkick, but in order to override that inline styling, you would have to use !importantin the css.
So, if you try that technique of giving all the children of the parent element width: 100% again, you might want to implement it something like this:
.importantRule { width: 100% !important; }
$( "parentElement > childElement" ).addClass('importantRule');
(First line goes in your CSS file, second line goes in JS)
my question is how can I add specific movement to x-y axis for an HTML element according to mouse movements.
Look at the site here and scroll to second slide:
http://community.saucony.com/kinvara3/
How can i achieve such effect!?
If you're going to write the library-free version, you will need to start with the following:
Learn DOM-manipulation.
var myEl = document.querySelector("#my-el");
Learn the <element>.style interface.
myEl.style.position = "absolute";
Learn the CSS properties, their values and how to read/use them from the style interface.
myEl.style.left = 10 + "px";
You'll need to understand the following CSS properties at a minimum:
"display"
"position"
"top"
"left"
"z-index"
Learn how to parse numbers from strings, properly, in JS.
...this will be unimportant, working with the mouse,
but very important, working with the DOM.
Learn how to write event-handlers.
window.addEventListener("mousemove", function (evt) {/*mousemove event object*/});
Learn the properties of event-objects (specifically the event-types that are important, like mouse, keyboard, touch).
Learn how to manage events, and control the number/frequency of operations, based on an ideal framerate, when the browser won't do it for you.
Learn how to make all of these things happen in a cross-browser, IE8+ way.
Learn a little linear-algebra (honestly, learning enough of it to understand an inverted-axis scaled-parallax is just a tiny bit harder than Grade 6 geometry.
You can get a similar effect CSS only, no JS needed!
You can see an example here: Pure CSS 3D Meninas, by Román Cortés. In his blog, there is also the explanation.
Basically, you have to split the target element in small elements, and on hover, set the position of different background layers according to your trigonometric calculations.
From his explanation,
There are 80 vertical hover elements of 5*455 pixels each, covering
the full effect. Each hover element contains inside elements to define
every layer position, the background image and the lateral background
image. When the hover element is not active (without the mouse over
it), all is inside elements showing images are hidden, with display:
none.
When the hover element is active, the images are set to display:
block, and the position of these are set. These positions have been
calculated and are written in the CSS code for each layer and each of
the 80 vertical hover elements. This is what does the magic.
I want to make table cells responsive - even squares filling all available space(window).
If table width is 100% - it takes all available space, distributing cells evenly but only horizontally. I have written small javascript with jquery, calling this function on window resize event:
function windowReszie(){
$("td").each(function(){
$(this).css({"height":$(this).width()});
})
}
But this approach is slow, because I have a lot of cells - is there a way to do it just with css or any other better , faster way?
I see some problem with your approach, you're computing the width for every cell.
I'd do something along the lines of
function windowReszie(){
var size =$("td").width();
$("td").height(size);
}
Another approach would be to set a class and change the css rule associated with the class, but that could be a bit tricky (see : Changing a CSS rule-set from Javascript)
try adding class only at first <td> in <tr> and then loop over that class... no need to check every <td> item.
I have a website template where I do not know the number of menu items or the size of the menu items that will be required. The js below works exactly the way I want it to, however this is the most js I've every written. Are there any disadvantages or potential problems with this method that I'm not aware of because I'm a js beginner? I'm currently manually setting the padding for each site. Thank you!
var width_of_text = 0;
var number_of_li = 0;
// measure the width of each <li> and add it to the total with, increment li counter
$('li').each(function() {
width_of_text += $(this).width();
number_of_li++;
});
// calculate the space between <li>'s so the space is equal
var padding = Math.floor((900 - width_of_text)/(number_of_li - 1));
// add the padding the all but the first <li>
$('li').each(function(index) {
if (index !== 0)
{
$(this).css("padding-left", padding);
}
});
You can do this hackily in CSS, using display: inline-block, and text-align: justify
<ul>
<li>thing</li>
<li>thing2</li>
<li>thing3</li>
<li>thing4</li>
<li class="hack"></li>
</ul>
And then:
ul { text-align: justify }
li { display: inline-block }
li.hack { width: 100% } /* force the justified text to wrap */
Demo
Yes, there are disadvantages of using JS for formatting.
It is strongly recommended to avoid using JS for formatting and positioning, use CSS whenever possible.
Javascript is interpreted and run very differently from browser to browser, from OS to OS, from OS/browser version to version.
CSS rendering is a native browser engine function and its rendering priority is higher than that of JS.
CSS rendering is much more speedy than JS.
Etc.
What you are doing now I would never suggest doing. IMHO, this is a very wrong approach. JS is absolutely definetely misused in this case. You have to use CSS for this task, and I would suggest posting a question about how to use CSS correctly for this task.
I would suggest having a default spacing between them in a way that would not push them out of their container. The extra javascript to enable them to space equally should be an enhancement only.
I think the answer to your question is, if it works, then it works (and will continue to work), but that doesn't mean that this is the best way to handle it. If you *care about the best way, then investigate how to improve your approach using mostly (or even exclusively) CSS. If you're just looking to get the job done, and it's working, then you're good to go.
Depending on your site visitors, there will be around 3% who visit you with JS disabled. And you want the site to work for them to. Maybe not the unnessecary parts of the site but you want the critical parts to work. Navigation is one of the most important parts of a website.
Make sure the navigation works without JS (doesn't have to be as fancy as with JS) and then you could make some improvements with JS.
You don't need JavaScript as long as you can rely on a CSS algorithm that adapt width to its content: the table layout algorithm :)
See http://jsfiddle.net/r9yrM/1/ from my previous answer for examples.
Don't forget to have a minimum padding on each "cell", text stuck to a border isn't very readable (and ugly). You'll also probably want text-align: center on cells (last CSS rule).
With JS, you could decide of a maximum number of tabs (or a minimum "reasonable" width) and above (below) that number, add a class on the parent that will trigger each tab to render as float: left and block and not table-cell anymore. Then it'll occupy 2 or more lines (like the extension Tab Mix Plus on Firefox)
Note: there're at least 2 algorithms for table: with and without table-layout: fixed, depending on freedom left to the browser when adapting.
Note on your jQuery code above: "each li except the first" can be expressed by $('li + li') (the first one isn't preceded by a li)
How to distinguish between blank areas and non-blank areas in a webpage with JavaScript? Blank areas including:
areas that are not occupied by DOM elements.
margins, borders and paddings of DOM elements.
EDIT:
As response to the first comment: I am working on a web-based ebook reader. Cursor is set to {cursor:move} for blank areas so that the user can drag and scroll the webpage.
You could recursively go through each element and attach onmouseover and onmouseout events (where the former enables the text cursor and the latter enables the move cursor) on each which has text in it, e.g:
function attachEvents(e) {
if (n.nodeType == 3) { // Node.TEXT_NODE
// A text node - add the parent as an element to select text in
e.parentNode.onmouseover = elmMouseOver /* define your own event fns */
e.parentNode.onmouseout = elmMouseOut
}
else if (n.nodeType == 1) { // Node.ELEMENT_NODE
for (var m=e.firstChild; m != null; m = m.nextSibling) {
attachEvents(m)
}
}
}
The best way I can think of to make sure it's actually "text" which is moused over and not a blank area is to use e.g. <div><span>content</span></div> and put the mouseover/mouseout events in the <span> so that blank areas don't trigger events. This is what I'd recommend doing if you can, as things can get very complicated if you use block elements with padding from my experience. For example:
| The quick brown fox jumps |
| over the lazy dog | <- onmouseover/out of SPANs will ignore the space
after "dog" while DIVs won't and you won't need
to calculate padding/margins/positions which
makes it faster and more simple to implement
If you have to use block DIVs: You could use something like jQuery's jSizes plugin to get margins/padding in pixels or this (for a way to get the inherited CSS values and parse yourself by removing the px part from the end etc)
After that, you could figure out the position using position() in jQuery. I personally don't use jQuery for my stuff, but I use those specific "find positions" functions and found them to be one of the best I think in large part because of number of users testing them.
Good luck!
My advice would be to go for a simple scrollbar. That's far more foolproof. By trying to implement the cool drag-and-scroll feature you risk with a lot of buggy behavior in dozens of edge-cases none of us can even imagine.
If you really want to detect clicks in whitespace, you could try attaching to the onmousedown/onmouseup/onmousemove events for the page itself. JavaScript events bubble nicely, so you'll handle the whole page at once (unless it has some JavaScript in itself, in which case you're screwed anyway). These events supply both the mouse X/Y coordinates and the element that was clicked. Then you can check for padding of that element (careful with inline elements) and figure out if it's in the padding or not. You do not need to check the margin because clicking there will instead originate the click in the parent element.
Although the effect you get this way is a lot of scattered "drag-zones" that the user will have to hunt for in order to scroll the page. I doubt this will sit well with your users. Better then make the whole page "draggable", but then you will loose the ability to select text. Or do like Acrobat, which only allows grabbing in the considerable padding area of the page itself (then you should make sure that there is a considerable padding area). Which in my eyes is not much better than a scrollbar. :P