I have the following code in jQuery:
$('body').on('click', '#gtco-offcanvas ul a:not([class="external"]), .main-nav a:not([class="external"])', function (event) {
var section = $(this).data('nav-section');
if ($('[data-section="' + section + '"]').length) {
$('html, body').animate({
scrollTop: $('[data-section="' + section + '"]').offset().top - 55
}, 500, 'easeInOutExpo');
}
and I need to rewrite it in pure vanilla JS. I have tried to do this, but I just got a lot of errors and don't know how to correct them...
This is my version of the code:
document.body.addEventListener('click', function (e) {
if (e.target.closest('body #gtco-offcanvas ul a:not([class="external"]), .main-nav a:not([class="external"])')) {
var section = document.querySelector('data').dataset('nav-section');
if (document.querySelectorAll('[data-section="' + section + '"]').length) {
document.querySelectorAll('html, body').animate({
scrollTop: document.querySelectorAll('[data-section="' + section + '"]').offset().top - 55
}, 500, 'easeInOutExpo');
}
};
And the output is:
Uncaught TypeError: Cannot read property 'dataset' of null
If I try to let this line in jQuery to test that the rest part of the code is working, I get no errors, but it doesn't do anything also...
Assuming your html element has the data attribute data-nav-section="" what you are looking for would be:
var section = e.target.dataset.navSection;
e.target would be the equivilant of $(this) and dataset is not a function but a property having to use a camelcase naming convention when using dashes in the attribute name
You can use the matches method without the closest to test if the receiving element is the one delegated:
if (e.target.matches('#gtco-offcanvas ul a:not([class="external"]), .main-nav a:not([class="external"])')) {
var section = e.target.dataset['navSection'];
// ...
}
Related
A couple weeks ago, i've been using this code to make the scroll event into a specific page, and was working very good.
But, yesterday, the client asked to change de attribute name from "Ouro" to "Ouro Envelhecido".
The first functional code was like that:
jQuery(document).ready(function($) {
$("[data-title=Ouro]").click(function() {
$('html, body').animate({
scrollTop: $(".custom-product-page").offset().top - 100
}, 1000);
})
And after the attribute name change, we just added the " Envelhecido", like this:
jQuery(document).ready(function($) {
$("[data-title=Ouro Envelhecido]").click(function() {
$('html, body').animate({
scrollTop: $(".custom-product-page").offset().top - 100
}, 1000);
})
And the code stop working. At the console, I got the warning saying Uncaught Error: Syntax error, unrecognized expression: [data-title=Ouro Envelhecido], but, the attribute name is 100% correct.
imgs:
https://prnt.sc/13py6mv
https://prnt.sc/13py8zy
Any help would be appreciated!
You should use quotes to wrap your data-title value
jQuery(document).ready(function($) {
$("[data-title='Ouro Envelhecido']").click(function() {
$('html, body').animate({
scrollTop: $(".custom-product-page").offset().top - 100
}, 1000);
})
})
I was wondering how I would use this method:
$('[data-jump-spy]').each(function(){
var dataObj = .data('jump-spy');
$(this).onclick ({
scrollTop: $("#" + dataObj ).offset().top();
});
});
to attach it to a link like so:
Who we are
....
....
....
....
<div class="box radius box-grey --animate" id="divContentThatsFarDownPage">
....
</div>
Final Solution can be found below
This function will allow you to code your website more easily. Simply type <div class="whatever iconArrow-to-Content LinkText-to-Content Img-to-Content" data-jump-spy="page-content"
$('[data-jump-spy]').each(function(){
var dataObj = $(this).data('jump-spy');
$(this).click(function() {
$("html, body").animate({
scrollTop: $("#" + dataObj ).offset().top
}, 1000);
});
});
A couple of changes
$('[data-jump-spy]').each(function(){
var dataObj = $(this).data('jump-spy'); // needs $(this) at beginning since .data needs to run on some object
$(this).click(function(){ // used click instead of onclick and you need to pass a function as an argument
$('html,body').animate({scrollTop: $("#" + dataObj ).offset().top}); // use .top instead of .top() as it is a property and not a method
});
});
I'm getting a few errors and not sure why.
I just want it to scroll to the parents div ID when it's clicked, it's getting the ID okay as I did a console log, so the issue is the scrolling part.
Error:
Uncaught TypeError: clickedPanel.offset is not a function
JS
$('#accordion .panel-heading .panel-title').click(function() {
$(this).parent().next().slideToggle(iconCallback);
$(".panel-collapse").not($(this).parent().next()).slideUp(iconCallback);
//scroll to clicked pabel
var container = $('#accordion'),
clickedPanel = $(this).parent().attr('id');
container.animate({
scrollTop: clickedPanel.offset().top - container.offset().top + container.scrollTop()
})
function iconCallback() {
var iconClass = $(this).is(':visible') ? 'fa-minus' : 'fa-plus';
$(this).prev().find('i').removeClass('fa-plus fa-minus').addClass(iconClass);
}
});
In your example clickedPanel is a string which does not have the offset() method. Instead set that variable to be the jQuery object returned from parent():
clickedPanel = $(this).parent();
I am currently trying to implement a menu with many clickable buttons - appetizers, soups, etc. By using parameters, I can send the type of food to my JavaScript.
These are the buttons.
http://puu.sh/kugEs/5048221343.jpg
This is the code when I click on appetizers.
function scroll(type) {
var test = "('#" + type + "')";
alert(test); //('#appetizers')
$("html, body").animate({ scrollTop: $test.offset().top-150 }, 600); //this doesnt work
$("html, body").animate({ scrollTop: $('#appetizers').offset().top-150 }, 600); //this works
}
Of course I want to make it so that I don't have to manually use the working line. I want to use the one that doesn't work that it can be applied to all buttons running the same function with only different parameters.
How can I use the var test in order to run the line that doesn't work?
You should use $ and take care about your quotes::
var $test = $('#' + type); // Now it's a jQuery Object
In your example:
function scroll(type) {
var $test = $('#' + type);
$("html, body").animate({ scrollTop: $test.offset().top-150 }, 600);
}
You should define $test as an object, instead of a string.
function scroll(type) {
var test = $('#' + type);
alert($test.attr("id")); // appetizers
$("html, body").animate({ scrollTop: $test.offset().top-150 }, 600);
}
Try it with this code. It should work.
function scroll(type) {
var test = "('#" + type + "')";
alert(test); //('#appetizers')
$("html, body").animate({ scrollTop: $('#'+type).offset().top-150 }, 600);
}
I am stuck at jquery div jump to problem. The problem is that i am creating dynamic and dynamic div also say <div id="1_1_div"></div> i am using following jquery function to scroll to a particular div
<script>
$(document).ready(function (){
$("#click").click(function (){
alert ("test");
//$(this).animate(function(){
$('html, body').animate({
scrollTop: $("#div1").offset().top
}, 1000);
//});
});
});
</script>
My question is how to pass dynamic id to $("") Any help would be highly appreciated.
$(document).ready(function (){
$(".click").click(function (){
alert ("test");
var divID = '#' + $(this).attr('id') + '_div';
$('html, body').animate({
scrollTop: $(divID).offset().top
}, 1000);
});
});
And add <a class="click" ...
String Concatenation:
$("#" + this.id + "_div").offset().top
Note that there is no need to create unique IDs, DOM duo to having tree-like structure provides many different methods for traversing and selecting the target elements.
Since you are generating the elements dynamically you should also delegate the events, you can add classes to your elements and use the on method:
$('#aStaticParentElement').on('click', '.anchors', function() {
// TODO:
// select the target element either by traversing
// or by using an identifier
});
Visualize it here
First, since you have multiple links, use a class to group them:
HTML
Click me 1_1
Click me 1_2
Click me 1_3
jQuery
$(document).on('click', '.click', function (e) {
var theID = $(this).attr('id');
$('html, body').animate({
scrollTop: $('#' + theID + '_div').offset().top
}, 1000);
return false;
});
I did this with the slight assumption you were dynamically creating these links (hence the delegation). If they are static and won't change during page load, you can use $('.click').click(function()... instead of $(document).on('click', '.click', function()...
User this line
$("#" + $(this).attr("id") + "_div").offset().top
...