Well, i don't know if the return in the transform function can work, but, someone know if there is a way where i can get something similar to this? Put a function inside an object...
var t = $(this).scrollTop();
var h = $(window).height();
function transform(val){
return "-webkit-transform": "translateY(" + val + "%)",
"-ms-transform": "translateY(" + val + "%)",
"transform": "translateY(" + val + "%)";
}
$("#header").css({
opacity: 50 * (t/h),
tranform(50 * (t/h))
});
You could use a CSS extension language (like LESS or SCSS) to handle variables, then simply process and use some simple stylesheet.
If you want to stick with JS, I would suggest returning a hash from transform and extending that later, like:
function transform(val) {
return {
"-webkit-transform": "translateY(" + val + "%)",
"-ms-transform": "translateY(" + val + "%)",
"transform": "translateY(" + val + "%)"
}
}
function transformWithOpacity(val) {
var base = transform(val);
base["opacity"] = val;
return base;
}
var num = 50 * (t/h);
$("#header").css(transformWithOpacity(num));
You can use JQuery extend function for this
$("#header").css($.extend({
opacity: 50 * (t/h)
},
tranform(50 * (t/h))
));
Related
<script>
var animate = function (element, target, callback) {
clearInterval(element.timer);
element.timer = setInterval(function () {
var step = (target - element.offsetLeft) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
element.style.left = element.offsetLeft + step + 'px';
// console.log(element.offsetLeft);
if (element.offsetLeft == target) {
clearInterval(element.timer);
callback && callback();
}
}, 20)
};
window.addEventListener('load', function () {
var ul = document.querySelector('.local-nav');
console.log(ul);
for (var i = 0; i < ul.children.length; i++) {
ul.children[i].children[0].children[0].style.backgroundPosition = '0 ' + -i * 32 + 'px';
}
var ul2 = document.querySelector('.subnav-entry ul');
console.log(ul2);
for (var i = 0; i < ul2.children.length; i++) {
console.log(ul2.children[i].children[0].children[0]);
ul2.children[i].children[0].children[0].style.backgroundPosition = '0 ' + -i * 32 + 'px';
}
var focus_ul = document.querySelector('.focus ul');
var ol = document.querySelector('.focus ol');
var count = 0;
var focus_timer = setInterval(function () {
if (count == 2) {
animate(focus_ul, focus_ul.offsetLeft - 375);
// console.log('i run');
// console.log(focus_ul.offsetLeft + ' ' + count);
// focus_ul.style.left = focus_ul.offsetLeft + 375 * 2 + 'px';
focus_ul.style.left = 0 + 'px'; // Here is my problem
console.log(focus_ul);
console.log(focus_ul.offsetLeft + ' ' + count);
}
else {
console.log('before animation ' + focus_ul.offsetLeft + ' ' + count);
animate(focus_ul, focus_ul.offsetLeft - 375);
console.log(focus_ul.offsetLeft + ' ' + count);
}
// focus_ul.style.left = focus_ul.offsetLeft + 375 + 'px';
count++;
count = count % 3;
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
ol.children[count].className = 'current-choice';
console.log('after a round ' + focus_ul.offsetLeft + ' ' + count);
}, 2500)
})
</script>
I meant to do a photo show that can play automaticly, like a Carousel or swiper, The 375px means that the screen is 375px wide, according to the code, when comming to the last photo, as the animation end, it should change back to the initial one which style.left == 0px, but 0px only occur a small while, next time it would be -1125px, -1500px and so on, I'm confused why i set style.left to 0 but fruitless. I'm new in front end ,thanks helping
You can use more of CSS (and less JavaScript) for this animation.
Declare two separate CSS class definitions for focus_ul. Use JavaScript to change the className of focus_ul.
Use CSS transition for animation of CSS offset-left property.
See: https://www.w3schools.com/css/tryit.asp?filename=trycss3_transition1
Write that custom className instead :hover in above example.
I want to duplicate the "voting-bar-container" div that carries jQuery functionality with it. However, because each duplicate carries with it the same ".classes" (and my jQuery Selectors target those classes), the jQuery is executed on each duplicate regardless of which "voting-bar-container" div is being interacted with.
I want the jQuery events to be executed ONLY on the elements being interacted with.
I believe the answer lies in my choice of Selectors as I know I don't need to duplicate my jQuery code for each duplicate HTML element with different "ID's".
https://jsfiddle.net/STEEZENS/aqd87b2d/
OR
Here is my HTML & jQuery:
<div class="voting-bar-container">
<button class="upvote">
<span class="upvote-counter">0</span>
</button>
<div class="vote-meter">
<div class="upvotes"></div>
<div class="downvotes"></div>
</div>
<button class="downvote">
<span class="downvote-counter">0</span>
</button>
</div>
jQuery:
$(document).ready(function () {
var $downvoteCount = 0;
var $upvoteCount = 0;
$(".upvote").click(function () {
$upvoteCount++;
$(".upvote-counter").text(" " + $upvoteCount);
var $totalVoteCount = $upvoteCount + $downvoteCount;
var $upvoteProportion = Math.round(($upvoteCount / $totalVoteCount) * 100);
var $downvoteProportion = Math.round(($downvoteCount / $totalVoteCount) * 100);
if (($upvoteProportion + $downvoteProportion) > 100) {
$(".upvotes").width(($upvoteProportion - 0.5) + "%");
$(".downvotes").width(($downvoteProportion - 0.5) + "%");
} else {
$(".upvotes").width($upvoteProportion + "%");
$(".downvotes").width($downvoteProportion + "%");
}
});
$(".downvote").click(function () {
$downvoteCount++;
$(".downvote-counter").text(" " + $downvoteCount);
var $totalVoteCount = $upvoteCount + $downvoteCount;
var $upvoteProportion = Math.round(($upvoteCount / $totalVoteCount) * 100);
var $downvoteProportion = Math.round(($downvoteCount / $totalVoteCount) * 100);
if (($upvoteProportion + $downvoteProportion) > 100) {
$(".upvotes").width(($upvoteProportion - 0.5) + "%");
$(".downvotes").width(($downvoteProportion - 0.5) + "%");
} else {
$(".upvotes").width($upvoteProportion + "%");
$(".downvotes").width($downvoteProportion + "%");
}
});
});
you need to use $(this)
$(this).find(".upvote-counter")
instead of
$(".upvote-counter")
while you asked for (*What I want is for the jQuery events to be executed ONLY on the elements being interacted with) .. your code should be something like this .. you will need to use .closest() as well >> to get the downvote div related with the upvote div and reverse
$(document).ready(function () {
var $downvoteCount = 0;
var $upvoteCount = 0;
$(".upvote").click(function () {
$upvoteCount++;
$(this).find(".upvote-counter").text(" " + $upvoteCount);
var $totalVoteCount = $upvoteCount + $downvoteCount;
var $upvoteProportion = Math.round(($upvoteCount / $totalVoteCount) * 100);
var $downvoteProportion = Math.round(($downvoteCount / $totalVoteCount) * 100);
if (($upvoteProportion + $downvoteProportion) > 100) {
$(this).width(($upvoteProportion - 0.5) + "%");
$(this).closest('voting-bar-container').find(".downvotes").width(($downvoteProportion - 0.5) + "%");
} else {
$(this).width($upvoteProportion + "%");
$(this).closest('voting-bar-container').width($downvoteProportion + "%");
}
});
$(".downvote").click(function () {
$downvoteCount++;
$(this).find(".downvote-counter").text(" " + $downvoteCount);
var $totalVoteCount = $upvoteCount + $downvoteCount;
var $upvoteProportion = Math.round(($upvoteCount / $totalVoteCount) * 100);
var $downvoteProportion = Math.round(($downvoteCount / $totalVoteCount) * 100);
if (($upvoteProportion + $downvoteProportion) > 100) {
$(this).closest('voting-bar-container').find(".upvotes").width(($upvoteProportion - 0.5) + "%");
$(this).width(($downvoteProportion - 0.5) + "%");
} else {
$(this).closest('voting-bar-container').find(".upvotes").width($upvoteProportion + "%");
$(this).width($downvoteProportion + "%");
}
});
});
DEMO
Note: this answer upon to your request .. you will need to work on it a little bit to reach a style you want
You need to be traversing the DOM to find the elements in question relative to the element that was clicked, instead of globally.
First, as you have multiple elements that have upvotes associated with them, the value of this and it's iteration needs to occur based on the existing upvote value of the element that is closest to upvote. Please observe below:
$(".upvote").click(function () {
var upvote_counter = $(this).find('span'),
downvote_counter = $(this).parent().find('.downvote-counter'),
upvotes = $(this).parent().find('.upvotes'),
downvotes = $(this).parent().find('.downvotes'),
$upvoteCount = upvote_counter.text(),
$downvoteCount = downvote_counter.text();
$upvoteCount++;
upvote_counter.text($upvoteCount);
var $totalVoteCount = $upvoteCount + $downvoteCount;
var $upvoteProportion = Math.round(($upvoteCount / $totalVoteCount) * 100);
var $downvoteProportion = Math.round(($downvoteCount / $totalVoteCount) * 100);
if (($upvoteProportion + $downvoteProportion) > 100) {
upvotes.width(($upvoteProportion - 0.5) + "%");
downvotes..width(($downvoteProportion - 0.5) + "%");
} else {
upvotes.width($upvoteProportion + "%");
downvotes.width($downvoteProportion + "%");
}
});
This will allow you to properly select the elements that are closest associated with the upvote element that is clicked. Do something similar for the downvote function.
This is my lift programm. But I have error.
var person = {
name: "Roman",
position: 2,
goal: 9
};
var lift = {
getPosition : function() {
var x = Math.floor((Math.random() * 10) + 1);
return x;
} ()};
console.log("Ok " + person.name + "! You are at " + person.position + " floor");
console.log("Lift is at " + lift.getPosition() + " floor");
Error lift.getPosition is not a function.
How can I fix it??
you code looks broken:
var lift = {
getPosition : function() {
var x = Math.floor((Math.random() * 10) + 1);
return x;
} ()};
it seems this should be
var lift = {
getPosition : function() {
var x = Math.floor((Math.random() * 10) + 1);
return x;
}
};
When you declared getPosition you assigned this property a self invoked anonymous function. (The () at the end, self invokes it)
var lift = {
getPosition: function() {
var x = Math.floor((Math.random() * 10) + 1);
return x;
}()
};
You can remove them () and call the method like you did "lift.getPosition()":
var lift = {
getPosition: function() {
var x = Math.floor((Math.random() * 10) + 1);
return x;
}
};
console.log("Lift is at " + lift.getPosition() + " floor");
or leave them and just call the property without the () "lift.getPosition":
var lift = {
getPosition: function() {
var x = Math.floor((Math.random() * 10) + 1);
return x;
}()
};
console.log("Lift is at " + lift.getPosition + " floor");
But that would return the same value every time you use it, because it is only executed once. It really depends on what you are trying to accomplish.
So, I have a function (i am workng with jquery ui and running this on drag event, though for this question I don't think that is important)
Basically I have the following repetitive if else code:
And I am curious if there is a way to write this in one line(ish) and not have a 100 else if lines if I want to be able to support 100 steps (divisions of a total slider value).
var thisPos = $( ".sliderknob" ).position();
var x = thisPos.left - window['sliderhome'].left;
console.log("(" + x + ")");
l = Object.keys(obj_frameindex).length;
framefraction = 290/l;
if (x>-1 && x<framefraction){
console.log('frame 1');
frameselector(0);
$('#framecounter').html("FRAME " + 1);
}
else if (x>framefraction && x<framefraction*2){
console.log('frame 2');
frameselector(1);
$('#framecounter').html("FRAME " + 2);
}
else if (x>framefraction*2 && x<framefraction*3){
console.log('frame 3');
frameselector(2);
$('#framecounter').html("FRAME " + 3);
}
else if (x>framefraction*3 && x<framefraction*4){
console.log('frame 4');
frameselector(3);
$('#framecounter').html("FRAME " + 4);} //etc..........
Showing only 4 here, but imagine it goes on...
Any ideas?
One possible approach:
var frameNo = Math.max(0, Math.floor(x / framefraction)) + 1;
console.log('frame ' + frameNo);
frameselector(frameNo - 1);
$('#framecounter').html('FRAME ' + frameNo);
Do something like:
if x < 0 { return };
var f = Math.ceil(x / framefraction);
console.log(`frame` + f);
frameselector(f - 1);
$(`#framecounter`).html("FRAME " + f);
I have a bit of Javascript that detects the browser and applies a transform to an elements depending on the browser. The one for Webkit works fine on Chrome however the Firefox one doesn't. Can someone please tell me if my code below is correct:
if(typeof navigator.vendor.toLowerCase().indexOf('chrome')!=-1){
document.getElementById('jj_preview7').style.WebkitTransform = 'scale(' + jj_input23 + ') ' + 'rotate(' + jj_input24 + 'deg)' + 'translate(' + jj_input25 + 'px, ' + jj_input26 + 'px)' + 'skew(' + jj_input27 + 'deg, ' + jj_input28 + 'deg)';
}
if(typeof navigator.vendor.toLowerCase().indexOf('firefox')!=-1){
document.getElementById('jj_preview7').style.MozTransform = 'scale(' + jj_input23 + ') ' + 'rotate(' + jj_input24 + 'deg)' + 'translate(' + jj_input25 + 'px, ' + jj_input26 + 'px)' + 'skew(' + jj_input27 + 'deg, ' + jj_input28 + 'deg)';
}
Thanks in advance
// Test element we apply both kinds of transforms to:
var testEl = document.createElement('div');
testEl.style.MozTransform = 'translate(100px) rotate(20deg)';
testEl.style.webkitTransform = 'translate(100px) rotate(20deg)';
var styleAttrLowercase = testEl.getAttribute('style').toLowerCase();
// when we check for existence of it in the style attribute;
// only valid ones will be there.
var hasMozTransform = styleAttrLowercase.indexOf('moz') !== -1;
var hasWebkitTransform = styleAttrLowercase.indexOf('webkit') !== -1;
Doing this you can now do:
var transformParts = [];
if (jj_input23 !== '') {
transformParts.push('scale(' + jj_input23 + ')');
}
if (jj_input23 !== '') {
transformParts.push('rotate(' + jj_input24 + 'deg)');
}
if (jj_input25 !== '' && jj_input26 !== '') {
transformParts.push('translate(' + jj_input25 + 'px, ' + jj_input26 + 'px)');
}
if (jj_input27 !== '' && jj_input28 !== '') {
transformParts.push('skewX(' + jj_input27 + 'deg) skewY(' + jj_input28 + 'deg)');
}
var transformTxt = transformParts.join(' ');
if (hasWebkitTransform) {
document.getElementById('jj_preview7').style.WebkitTransform = transformTxt;
}
if (hasMozTransform) {
document.getElementById('jj_preview7').style.MozTransform = transformTxt;
}
Here is the solution: http://jsfiddle.net/Adu49/1/
As you are reading from inputs directly without parse it, so you may generate CSS declaration like: scale() translate(deg,deg) which is obviously illegal. And in this case, Firefox prefer to drop it, while Chrome prefer to accept partial correct declaration. That's why your code doesn't work on Firefox but on Chrome, and after you fill all the fields it will eventually work on both browsers.
So I placed some value || default in your code, which will guaranty a proper default value is set when the input box is empty (if you want to interact with user, you need more validation code here.)
And some off-topic here. Please change the way you naming variables and elements, it's too confusing.