PFB Function of javascript.It is performing good in Chrome.But the performance is very poor in IE.If the function is taking 4ms in chrome,It is taking 170ms in IE.Someone please help me on this.
Identified the issue is not because of Javascript.It is because of the ExecuteScript from webdriver
Is there any way to improve the performance in IE in this case?
public string OnMouseMoveListner()
{
string onMouseMove = #"
function OnMouseMove (event)
{
window.onEscape=null;
window.isRefresh='set';
var posX = event.clientX, posY = event.clientY;
// displays the coordinates used for the elementFromPoint method
// get the element that is located under the mouse y
var overElem = document.elementFromPoint (posX, posY);
if (overElem && overElem.tagName === undefined)
{ // in case of text nodes (Opera)
overElem = overElem.parentNode; // the parent node will be selected
window.control= overElem ;
}
// the body and the html tag won't be selected
if (overElem && overElem.tagName.toLowerCase () !='body' && overElem.tagName.toLowerCase () != 'html')
{
window.control= overElem ;
}
window.outerHeight=window.outerHeight;
window.innerHeight=window.innerHeight;
}
window.isRefresh='set';
";
return onMouseMove;
}
((IJavaScriptExecutor)webDriver).ExecuteScript(js.OnMouseMoveListner());
Related
One feature of my mobile web app involves scrolling users to a particular point on the page. The following code accomplishes this, but it only works on iPhone Safari. On Chrome browser / Android, it scrolls to the bottom of the page instead. Why the inconsistency?
Please note: I don't want to use jQuery.
var $ = function(elID) {
return document.getElementById(el);
}
// Get info about target element's position and dimensions
var getRect = function(el) {
return el.getBoundingClientRect();
}
var scrollJump = function(){
var page = $('dPageContainer');
headerHeight = getRect($('dFixedHeader')).height;
return function(el){
// If a jQuery object, convert to raw DOM el
if ('get' in el) {
el = el.get(0);
}
var rect = getRect(el);
// Scroll the page to the element's position
page.scrollTop+= rect.top - rect.height - headerHeight;
}
};
var scrollToEl = scrollJump();
scrollToEl( $('my_DIV_ID') );
I was able to solve this problem by simplifying and cleaning up the code. In particular, I used the offsetTop method instead of relying only on getBoundingClientRect:
var $ = function(el) {
return document.getElementById(el);
}
var scrollJump = function(){
var page = $('dPageContainer'),
headerHeight = $('dFixedHeader').getBoundingClientRect().height;
return function(el){
// If a jQuery object, convert to raw DOM el
if ('get' in el) el = el.get(0);
// Scroll the page to the element's position
page.scrollTop = el.offsetTop - headerHeight;
}
};
var scrollToEl = scrollJump();
scrollToEl( $('my_DIV_ID') );
I have the following JS function, which I am using to detect when the cursor is hovering over a particular image on an HTML5 canvas:
function cursorOverAssetsBox(mouseX, mouseY){
if((mouseX >= assetsDescriptionBox.img_x && mouseX <= assetsDescriptionBox.img_x + assetsDescriptionBox.img_width) &&
(mouseY <= assetsDescriptionBox.img_y && mouseY >= assetsDescriptionBox.img_y - assetsDescriptionBox.img_height))
document.getElementById('tipsParagraph').innerHTML = tips[34];
console.log(tips[34]);
}
The function works correctly, but for some reason, the line
document.getElementById('tipsParagraph').innerHTML = tips[34];
doesn't appear to be firing...
'tipsParagraph' is the ID I have given to an HTML <p></p> tag in the <body></body> of my HTML. 'tips' is an array, each element of which contains some text.
I want to display the text stored in position 34 of that array whenever the cursor is in the location specified by my if statement. I know that the function works, because the line console.log(tips[34]); is displaying the contents of that element of the array in the console whenever the cursor is in that location. But for some reason, the text in the paragraph is not updated to display the contents of that array element.
Can anyone figure out why this is?
I am calling the function from within the mousemove function of a local copy of the KineticJS library. I'm using a local copy of the library, as there are a couple of slight adjustments I wanted to make to its functionality, such as this one. The 'mousemove' function currently looks like this:
_mousemove: function(evt) {
this._setUserPosition(evt);
var dd = Kinetic.DD;
var obj = this.getIntersection(this.getUserPosition());
getMousePosition(evt);
document.getElementById('mouseLocation').innerHTML = "mouseX = " + evt.clientX + ". mouseY = " + evt.clientY;
/*Add an if statement, so that cursorOverAssetsBox function is only called when the cursor's y value is greater than
400. This will improve performance, as the code will only check if it needs to call the function when the cursor is
below that line. */
if(mouseY >= 400){
cursorOverAssetsBox(mouseX, mouseY);
}
/*Write an if statement that says, "if 'draggingImage' variable is set to true, check the x & y of that image to see if
it's over its description box- if it is, do something, if not, don't", if 'draggingImage' variable is not set
to true, don't check.*/
//cursorOverAssetsBox(mouseX, mouseY);
if(obj) {
var shape = obj.shape;
if(shape) {
if((!dd || !dd.moving) && obj.pixel[3] === 255 && (!this.targetShape || this.targetShape._id !== shape._id)) {
if(this.targetShape) {
this.targetShape._handleEvent('mouseout', evt, shape);
this.targetShape._handleEvent('mouseleave', evt, shape);
}
shape._handleEvent('mouseover', evt, this.targetShape);
shape._handleEvent('mouseenter', evt, this.targetShape);
this.targetShape = shape;
}
else {
shape._handleEvent('mousemove', evt);
}
}
}
/*
* if no shape was detected, clear target shape and try
* to run mouseout from previous target shape
*/
else if(this.targetShape && (!dd || !dd.moving)) {
this.targetShape._handleEvent('mouseout', evt);
this.targetShape._handleEvent('mouseleave', evt);
this.targetShape = null;
}
// start drag and drop
if(dd) {
dd._startDrag(evt);
}
}
I found this script by theZillion (http://thezillion.wordpress.com/2012/08/29/javascript-draggable-no-jquery/) that makes a div draggable. I'm trying to use this script to move a div by class name. And not by ID.
I have an event handler that works, but not when I'm adding the script... The console shows no errors either. Any ideas about how to make this work?
This is the code I have:
function wrappmover(){
var moveEvent = "dice-window-wrapper";
var addClassArr= document.getElementsByClassName(moveEvent);
for(var i=0; i<addClassArr.length; i++){
var addClass = addClassArr[i];
addClass.addEventListener("click", movewrapp, true);
}
function movewrapp() {
var classToMove = "dice-window-wrapper";
var elems = document.getElementsByClassName(classToMove);
var tzdragg = function(){
return {
startMoving : function(evt){
evt = evt || window.event;
var posX = evt.clientX,
posY = evt.clientY,
a = document.getElementsByClassName(classToMove),
divTop = a.style.top,
divLeft = a.style.left;
divTop = divTop.replace('px','');
divLeft = divLeft.replace('px','');
var diffX = posX - divLeft,
diffY = posY - divTop;
document.onmousemove = function(evt){
evt = evt || window.event;
var posX = evt.clientX,
posY = evt.clientY,
aX = posX - diffX,
aY = posY - diffY;
tzdragg.move('elem',aX,aY);
}
},
stopMoving : function(){
document.onmousemove = function(){}
},
move : function(divid,xpos,ypos){
var a = document.getElementById(divid);
document.getElementById(divid).style.left = xpos + 'px';
document.getElementById(divid).style.top = ypos + 'px';
}
}
}();
Okay, so you want to have draggable elements on your page?
Take a look at the following code (and here's a working example). I hope you will find it self-explanatory, but just in case there are also comments:
// Wrap the module in a self-executing anonymous function
// to avoid leaking variables into global scope:
(function (document) {
// Enable ECMAScript 5 strict mode within this function:
'use strict';
// Obtain a node list of all elements that have class="draggable":
var draggable = document.getElementsByClassName('draggable'),
draggableCount = draggable.length, // cache the length
i; // iterator placeholder
// This function initializes the drag of an element where an
// event ("mousedown") has occurred:
function startDrag(evt) {
// The element's position is based on its top left corner,
// but the mouse coordinates are inside of it, so we need
// to calculate the positioning difference:
var diffX = evt.clientX - this.offsetLeft,
diffY = evt.clientY - this.offsetTop,
that = this; // "this" refers to the current element,
// let's keep it in cache for later use.
// moveAlong places the current element (referenced by "that")
// according to the current cursor position:
function moveAlong(evt) {
that.style.left = (evt.clientX - diffX) + 'px';
that.style.top = (evt.clientY - diffY) + 'px';
}
// stopDrag removes event listeners from the element,
// thus stopping the drag:
function stopDrag() {
document.removeEventListener('mousemove', moveAlong);
document.removeEventListener('mouseup', stopDrag);
}
document.addEventListener('mouseup', stopDrag);
document.addEventListener('mousemove', moveAlong);
}
// Now that all the variables and functions are created,
// we can go on and make the elements draggable by assigning
// a "startDrag" function to a "mousedown" event that occurs
// on those elements:
for (i = 0; i < draggableCount; i += 1) {
draggable[i].addEventListener('mousedown', startDrag);
}
}(document));
Load or wrap it in <script></script> tags as close as possible to </body> so that it doesn't block the browser from fetching other resources.
Actually, if you remove the comments, it's a very small function. Much smaller and more efficient than the one from the website you've provided.
A possible improvement
Consider replacing the anonymous wrapper with something like makeDraggable(selector); where selector is a CSS selector, so you could do crazy stuff like:
makeDraggable('#dragMe, #dragMeToo, .draggable, li:nth-child(2n+1)');
It can be achieved by using document.querySelectorAll that is able to perform complex CSS queries instead of a simple class name lookup by document.getElementsByClassName.
Things to watch out for
If the page has any scrolling - the drag will look broken; consider adjusting the positioning of the dragged element by scrollX and scrollY
This will obviously not work in Internet Explorer (figure it out yourself).
There might be memory leaks (needs profiling and testing).
EDIT: A solution for adding new draggable elements
So you want to be able to add more draggable elements? There are several approaches to tackle this. For example you could write a makeDraggable(element); function and call it on the element you're adding to the DOM. It will work of course, but let's have a look at something different, shall we?
Instead of querying the DOM in search of draggable elements and assigning them event listeners, why don't we assign just one for the "mousedown" event on document body.
When triggered, the event object will contain a reference to the target element which is the object the event has been dispatched on (the element you mousedown-ed). The relevant part of the code will now resemble this:
// Performs a check if the current element is draggable and if yes,
// then the dragging is initiated:
function startDragIfDraggable(evt) {
// Check if the target element (referenced by evt.target) contains a
// class named "draggable" (http://stackoverflow.com/questions/5898656/):
if (evt.target.classList.contains('draggable')) {
// Invoke startDrag by passing it the target element as "this":
startDrag.call(evt.target, evt);
}
}
// Listen for any "mousedown" event on the document.body and attempt dragging
// the target element (the one where "mousedown" occurred) if it's draggable:
document.body.addEventListener('mousedown', startDragIfDraggable);
And here's a working example of the above code. As a bonus it features a simulation of adding new draggable elements to the DOM.
In addition to being able to drag dynamically-added draggable elements, this approach will also save us some memory because we can now avoid assigning a bunch event listeners to a bunch of elements. However, if the application you're developing is very click-intensive (e.g. a game) then you might waste a little bit of CPU because of checks on every click.
I'm trying to drag and drop items on a page, but insteads of moving the item itself, I create a copy of it.
Here is my code. "copyDragDrop" is a div at the bottom of the page. It remains empty until the user strats dragging something.
function coordSouris()
{
return {
x:event.clientX + document.body.scrollLeft - document.body.clientLeft,
y:event.clientY + document.body.scrollTop - document.body.clientTop
};
}
function drag()
{
var pos = coordSouris(event);
copie = event.srcElement.cloneNode(true);
document.getElementById('copieDragDrop').appendChild(copie);
copie.style.position = 'absolute';
copie.style.display = 'block';
document.onmousemove = mouseMove;
document.onmouseup = drop;
}
function mouseMove()
{
if (copie != null)
{
var pos = coordSouris(event);
copie.style.left = pos.x;
copie.style.top = pos.y;
}
}
function drop()
{
var divCopie = document.getElementById('copieDragDrop');
if (divCopie.hasChildNodes() )
{
while ( divCopie.childNodes.length >= 1 )
{
divCopie.removeChild(divCopie.firstChild);
}
}
}
This code creates the copy, starts to move it, but after a few pixels, the copy stops following the mouse. If I release the mouse, "onmouseup" is not fired, but the copy starts to follow the mouse again ! I've tried the code on several items, the same bug occurs
I don't understand anything, any help is more than welcome.
UPDATE : I juste realised that all elements I tried the code on had something in common : they contained or were included in an ASP.net hyperlink control. The same code works well on regular HTML elements. There must be some auto-generated javascript for links that interferes with my code.
Couldn't find the auto-generated code responsible for the issue, so I simply solvec this by replacing Hyperlink controls by standard HTML anchors.
I have a div layer with overflow set to scroll.
When scrolled to the bottom of the div, I wanna run a function.
The accepted answer was fundamentally flawed, it has since been deleted. The correct answer is:
function scrolled(e) {
if (myDiv.offsetHeight + myDiv.scrollTop >= myDiv.scrollHeight) {
scrolledToBottom(e);
}
}
Tested this in Firefox, Chrome and Opera. It works.
I could not get either of the above answers to work so here is a third option that works for me! (This is used with jQuery)
if (($(window).innerHeight() + $(window).scrollTop()) >= $("body").height()) {
//do stuff
}
Hope this helps anyone!
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight)
{
//your code here
}
I too searched it and even after checking all comments here and more,
this is the solution to check if reached the bottom or not.
OK Here is a Good And Proper Solution
You have a Div call with an id="myDiv"
so the function goes.
function GetScrollerEndPoint()
{
var scrollHeight = $("#myDiv").prop('scrollHeight');
var divHeight = $("#myDiv").height();
var scrollerEndPoint = scrollHeight - divHeight;
var divScrollerTop = $("#myDiv").scrollTop();
if(divScrollerTop === scrollerEndPoint)
{
//Your Code
//The Div scroller has reached the bottom
}
}
This worked for me:
$(window).scroll(function() {
buffer = 40 // # of pixels from bottom of scroll to fire your function. Can be 0
if ($(".myDiv").prop('scrollHeight') - $(".myDiv").scrollTop() <= $(".myDiv").height() + buffer ) {
doThing();
}
});
Must use jQuery 1.6 or higher
I found an alternative that works.
None of these answers worked for me (currently testing in FireFox 22.0), and after a lot of research I found, what seems to be, a much cleaner and straight forward solution.
Implemented solution:
function IsScrollbarAtBottom() {
var documentHeight = $(document).height();
var scrollDifference = $(window).height() + $(window).scrollTop();
return (documentHeight == scrollDifference);
}
Resource: http://jquery.10927.n7.nabble.com/How-can-we-find-out-scrollbar-position-has-reached-at-the-bottom-in-js-td145336.html
Regards
I created a event based solution based on Bjorn Tipling's answer:
(function(doc){
'use strict';
window.onscroll = function (event) {
if (isEndOfElement(doc.body)){
sendNewEvent('end-of-page-reached');
}
};
function isEndOfElement(element){
//visible height + pixel scrolled = total height
return element.offsetHeight + element.scrollTop >= element.scrollHeight;
}
function sendNewEvent(eventName){
var event = doc.createEvent('Event');
event.initEvent(eventName, true, true);
doc.dispatchEvent(event);
}
}(document));
And you use the event like this:
document.addEventListener('end-of-page-reached', function(){
console.log('you reached the end of the page');
});
BTW: you need to add this CSS for javascript to know how long the page is
html, body {
height: 100%;
}
Demo: http://plnkr.co/edit/CCokKfB16iWIMddtWjPC?p=preview
This will actually be the correct answer:
function scrolled(event) {
const container = event.target.body
const {clientHeight, scrollHeight, scrollY: scrollTop} = container
if (clientHeight + scrollY >= scrollHeight) {
scrolledToBottom(event);
}
}
The reason for using the event is up-to-date data, if you'll use a direct reference to the div you'll get outdated scrollY and will fail to detect the position correctly.
additional way is to wrap it in a setTimeout and wait till the data updates.
Take a look at this example: MDN Element.scrollHeight
I recommend that check out this example: stackoverflow.com/a/24815216... which implements a cross-browser handling for the scroll action.
You may use the following snippet:
//attaches the "scroll" event
$(window).scroll(function (e) {
var target = e.currentTarget,
scrollTop = target.scrollTop || window.pageYOffset,
scrollHeight = target.scrollHeight || document.body.scrollHeight;
if (scrollHeight - scrollTop === $(target).innerHeight()) {
console.log("► End of scroll");
}
});
Since innerHeight doesn't work in some old IE versions, clientHeight can be used:
$(window).scroll(function (e){
var body = document.body;
//alert (body.clientHeight);
var scrollTop = this.pageYOffset || body.scrollTop;
if (body.scrollHeight - scrollTop === parseFloat(body.clientHeight)) {
loadMoreNews();
}
});
To do the same in React/JSX, here is the snippet.
export const scrolledToEnd = event => {
const container = event.target;
if (container.offsetHeight + container.scrollTop >= container.scrollHeight) {
return true;
}
return false;
};
And in your component add
<Component onScroll={scrolledToEnd}>
There is experimental onscrollend event https://developer.mozilla.org/en-US/docs/Web/API/Document/scrollend_event
For now works only in firefox 109+, if other browsers catch up will be very nice.
Have polyfill for that https://github.com/argyleink/scrollyfills
Use like
import "scrollyfills";
...
scrollContainer.addEventListener(
"scrollend",
(ev) => { console.log('scroll END') }
);
I found this methode to get the end of the scroll :
let TheBody = document.getElementsByTagName("body"); // I choose the "body" element for my exemple
function OnScrolling(){ // put this on a scrolling EVENT
let ScrollEnd = TheBody[0].scrollHeight - window.innerHeight; // this is the scroll end Pixel
if (ScrollEnd.toFixed() == window.scrollY.toFixed()){
//do stuff
}
}
Okay now for your DIV or any other element that have a scrolling I found this method on JavaScript :
let D = document.getElementById("D1"); // I gave "D1" as id to my div
// this one is to calculate the scroll end Pixels
let Calc = D.scrollHeight - D.clientHeight;
function ScrollingInD1() {
//this one is to calculate the scrolling percent while going through the <div> it can help for "Responsivity"
let percent = (D.scrollTop * 100) / Calc;
if (D.scrollTop == Calc) {
// do Stuffs
}
}