Im using a form that contains a more than 40-50 textareas,
when the
md-no-autogrow option is enabled which it is by default,this causes a huge performance issue.
Function responsible
https://github.com/angular/material/blob/0b55529940d516a94777ca1d179e65df7835dd2a/src/components/input/input.js#L532
if I disable md-no-autogrow the resize functionalities are lost what could be a better solution?
Possible Solution
<textarea
ng-model="$ctrl.model"
ng-keydown="$ctrl.onKeyDown($event)"
ng-keyup="$ctrl.onKeyUp($event)"
md-no-autogrow="true"
>
onKeyUp(e) {
if (e.key === 'Enter') {
return;
}
let element = e.target;
element.style.height = 'auto';
if (element.scrollHeight > 54) {
element.style.height = element.scrollHeight + 'px';
}
}
onKeyDown(e) {
if (e.key !== 'Enter') {
return;
}
let element = e.target;
let numberOfLines = element.value.split('\n').length;
if (numberOfLines >= 2) {
element.style.height = 'auto';
element.style.height = (element.scrollHeight + 26) + 'px';
}
}
Related
i have an issue concerning a JS scrolling function.
const scroll = document.querySelectorAll(".scroll");
const maxIndex = 3; //NB DE PAGES
let index = 0;
let animationEnd = true;
let boolUp = 0;
const start = {
x: 0,
y: 0
};
function touchStart(event) {
event.preventDefault();
start.x = event.touches[0].pageX;
start.y = event.touches[0].pageY;
}
function touchMove(event) {
event.preventDefault();
const offset = {};
offset.x = start.x - event.touches[0].pageX;
offset.y = start.y - event.touches[0].pageY;
scrollHandler({
deltaY: offset.y
});
}
function scrollHandler(e) {
if(e.preventDefault) e.preventDefault();
if (animationEnd) {
if (e.deltaY > 0) index++;
else index--;
if (index < 0) index = 0;
if (index > scroll.length - 1) index = scroll.length - 1;
scroll[0].style.marginTop = "-" + index * 100 + "vh";
animationEnd = false;
setTimeout(() => animationEnd = true, 450)
}
}
function keyScroll(e) {
if (e.key == "ArrowUp") {
index--;
if (index < 0) {
index = 0;
}
scroll[0].style.marginTop = "-" + index * 100 + "vh";
animationEnd = false;
setTimeout(() => animationEnd = true, 450);
} else if (e.key == "ArrowDown") {
if (index < maxIndex) {
index++;
scroll[0].style.marginTop = "-" + index * 100 + "vh";
animationEnd = false;
setTimeout(() => animationEnd = true, 450);
}
}
}
I'm calling those by body event listeners :
document.addEventListener("scroll", (e) => e.preventDefault())
document.body.addEventListener("keydown", keyScroll);
document.body.addEventListener("wheel", scrollHandler,);
document.body.addEventListener("touchstart", touchStart, false);
document.body.addEventListener("touchmove", touchMove, false);
It's working perfectly => example at https://darleanow.github.io .
But when i'm on smartphone (Iphone), scroll might bug and the height of divs would appear different, you can try it on your own smartphone to see what i'm talking about, try scrolling a bit fast etc...
If anybody has an idea :)
This isn't a solution necessarily, but you might try printing scroll[0].stlye.marginTop to the console every time it changes.
If that value is never erroneous, I'd guess the issue is with the animation (maybe scrolling while it's animating, or something like that).
i have a script for move DOM object, but it doesn't work, i think troubles in my keydown countruction where im trying to add/subtract and nothing happens. Can somebody explain why?
mouse.setAttribute('tabindex', '0')
alert(typeof(+mouse.style.left));
mouse.addEventListener('click', (event) => {
mouse.style.position = 'fixed';
mouse.style.left = mouse.getBoundingClientRect().left + 'px';
mouse.style.top = mouse.getBoundingClientRect().top + 'px';
})
mouse.addEventListener ('focus', (event) => {
mouse.addEventListener('keydown', (event) => {
if (event.keyCode == 37){
console.log('left');
let left = +mouse.style.left
mouse.style.left = left - 20 + 'px';
}
if (event.keyCode == 38){
console.log('up');
let up = +mouse.style.top;
mouse.style.top = up - 20 + 'px';
}
if (event.keyCode == 39){
console.log('right');
let right = +mouse.style.left
mouse.style.left = right + 20 + 'px';
}
if (event.keyCode == 40){
console.log('down');
let down = +mouse.style.top
mouse.style.top = down + 20 + 'px';
}
})
})
</script>
+ does not parse a string such as '20px' as 20. As mentioned in the comments, you need to parse your styles as a number. This means using a function such as parseInt as demonstrated below.
Also, registering an event handler inside an event handler may not result in what you wish. In particular: If you focus the div twice, the event handler will run twice.
var mouse = document.getElementById('mouse');
mouse.setAttribute('tabindex', '0')
mouse.addEventListener('click', (event) => {
mouse.style.position = 'fixed';
mouse.style.left = mouse.getBoundingClientRect().left + 'px';
mouse.style.top = mouse.getBoundingClientRect().top + 'px';
})
mouse.addEventListener ('focus', (event) => {
mouse.addEventListener('keydown', (event) => {
if (event.keyCode == 37){
console.log('left');
let left = parseInt(mouse.style.left)
mouse.style.left = left - 20 + 'px';
}
if (event.keyCode == 38){
console.log('up');
let up = parseInt(mouse.style.top);
mouse.style.top = up - 20 + 'px';
}
if (event.keyCode == 39){
console.log('right');
let right = parseInt(mouse.style.left)
mouse.style.left = right + 20 + 'px';
}
if (event.keyCode == 40){
console.log('down');
let down = parseInt(mouse.style.top)
mouse.style.top = down + 20 + 'px';
}
})
})
<div id="mouse" style="background-color: yellow">Hi</div>
Window.onscroll = () => {
if (Window.innerHeight + Window.scrolly >= document.body.offsetHeight) {
document.querySelector('body').style.background = 'green';
} else {
document.querySelector('body').style.background = 'white';
}
}
I am new at coding, learning from an online course. Now I am stuck at it. i don't know what is wrong in here
As was mentioned in the comment you got wrong letter cases: window, scrollY
const body = document.querySelector('body');
body.style.height = '200vh'; // without content there's no scroll, so this will produce scroll;
window.onscroll = () => {
if (window.innerHeight + window.scrollY >= document.body.offsetHeight) {
body.style.background = 'green';
} else {
body.style.background = 'white';
}
}
I have a main.js file which I am initiating a game with two class instances. Head and Apple. I want to monitor css changes from my main.js file but it is not staying updated on the changes happening in the Head instance, namely, every 500 ms the position of it changes due to changes in its css. I would like to do certain actions depending on that "head's" positioning and therefore its css. Should I be using a jquery method to monitor this? I am not sure where to go. I have tried accessing the css properties by defining them with this in the constructor and also using variables in the main.js file. neither have worked.
main.js
$(document).ready(function() {
const head = new Head($('#board'));
const apple = new Apple($('#board'));
$('body').on('keydown', function(e) {
if (e.keyCode === 37) {
console.log('pressed left');
head.currentDirection = 'left';
} else if (e.keyCode === 39) {
console.log('pressed right');
head.currentDirection = 'right';
} else if (e.keyCode === 38) {
console.log('pressed up');
head.currentDirection = 'up';
} else if (e.keyCode === 40) {
console.log('pressed down');
head.currentDirection = 'down';
}
});
let position = head.node.position();
if (position.top === apple.randomTop && position.left === apple.randomLeft) {
this.endGame();
}
});
Apple
class Apple {
constructor($el) {
this.node = $('<img id="apple"></img>');
this.node.attr('src', 'src/assets/apple.jpg');
$el.append(this.node);
this.randomTop = Math.floor(Math.random() * 13) * 50
this.randomLeft = Math.floor(Math.random() * 13) * 50
this.node.css({ top: this.randomTop, left: this.randomLeft });
}
}
Head
// creates a constructor function - research ES6 classes
class Head {
// this is what's called when you use the "new" keyword
constructor($el) {
this.node = $('<div id="head"></div>');
this.currentDirection = 'right';
this.SPEED = 500;
$el.append(this.node);
this.node.css({ top: 0, left: 0 });
this.toBeCleared = setTimeout(this.move.bind(this), this.SPEED);
}
// same as Head.prototype.move = function() {...}
move() {
let direction = this.currentDirection;
let position = this.node.position();
if (position.left === 700 || position.top === 700 || position.left === -50 || position.top === -50) {
console.log('Game Over');
this.endGame();
}
if (direction === 'right') {
position.left += 50;
} else if (direction === 'left') {
position.left -= 50;
} else if (direction === 'up') {
position.top -= 50;
} else if (direction === 'down') {
position.top += 50;
}
this.node.css(position);
this.toBeCleared = setTimeout(this.move.bind(this), this.SPEED);
}
endGame() {
console.log('game has ended')
// this.node.css(position);
clearTimeout(toBeCleared);
}
}
I know you have to invert the properties and I've done that. I also replaced the style.right.replace function with style.left.replace and changed the other parts to move the left property ${left + 1} and it worked! This confirms there is no typo. style.right just doesn't work at all for me. Any thoughts on this code?
//This Works!
var dodger = document.getElementById('dodger')
function moveDodgerLeft() {
var leftNumbers = dodger.style.left.replace('px', " ")
var left = parseInt(leftNumbers, 10)
if (left > 0) {
dodger.style.left = `${left - 1}px`
}
}
document.addEventListener('keydown', function(e) {
if (e.which === 37) {
moveDodgerLeft()
}
})
// This doesn't work
function moveDodgerRight() {
var rightNumbers = dodger.style.right.replace('px', " ")
var right = parseInt(rightNumbers, 10)
if (right > 0) {
dodger.style.right =`${right - 1}px`
}
}
document.addEventListener('keydown', function(e) {
if (e.which === 39) {
moveDodgerRight()
}
})