to change some css property once backing to an already-visited page - javascript

There are 2 pages, a link from first page to second one.www.example.com/second.html.
then a link from second page to a specific section on first one www.example.com/first.html#specificSection.
is there a way to change some css property on first page once backing from second one by Java Script?

Yes.
let urlChunks = window.location.href.split('#');
if (urlChunks.length === 2 && urlChunks[1] === 'specificSection') {
// add your class
}
If length is 2, it means a parameter was found after #, checking its value is safe in the condition that follows the and.

You can check the url on first page load, and if it is www.example.com/first.html#specificSection assume that the user came from the second page and apply any styling to your elements.
So you would check
(function () {
if (window.location.href === 'www.example.com/first.html#specificSection') {
// do anything here
}
})();
UPDATE according to #Ravenous comment
You can also check document.referrer and compare it with the url of your second page. That would be more precise way to detect if the user came from the second page I think.

Related

Next/Prev buttons to step through div contents

First of all a disclaimer, I'm not a dev. I'm halfway through The Odin Project and have covered some HTML and CSS, but, have not yet started on JS. In order to help with my learning I've created my own blog. My aim is for each blog post to have its own stylesheet (so with each new post I learn a little more about CSS).
Anyway, I plan to write a post about the benefits of using an eReader, specifically the Kindle. I've styled the page to look like a Kindle Oasis, and I'd like the reader to be able to step through the article contents via the Kindle's next/prev buttons, but, as I'm not a dev, this is where I'm stuck. Via Stack overflow I've managed to add some JS that will display page 1, 2 and 3 via dedicated buttons for each dive element, but, what I really need is to step through x number of pages via the prev/next buttons.
Here's what I have so far: https://codepen.io/dbssticky/pen/yLVoORO. Any help would be much appreciated. What I should do of course is finish The Odin Project and come up with a solution on my own, but, I'd really like to get this Kindle article published sooner rather than later. Hence my rather cheeky request for assistance.
Here's the JS I'm currently using:
function swapContent(id) {
const main = document.getElementById("main_place");
const div = document.getElementById(id);
const clone = div.cloneNode(true);
while (main.firstChild) main.firstChild.remove();
main.appendChild(clone);
}
You have the right idea and it just needs a few adjustments to get the previous/next functionality.
Currently your div IDs are following the format operation1, operation2, and so on. Since you want the previous/next functionality you'll need to change your 'swapping' function, which currently takes the full ID, to use the numeric portion only.
Add a new function which appends the number to 'operation' instead of using the whole thing:
function goToPage(pageNumber){
const main = document.getElementById("main_place");
const div = document.getElementById("operation" + pageNumber);
const clone = div.cloneNode(true);
while (main.firstChild) main.firstChild.remove();
main.appendChild(clone);
}
And then change your Page 1/2/3 buttons to use goToPage(1), goToPage(2) and so on.
Now for the previous/next functionality you'll need a way to track which page you're on, so that you can figure out which page to load.
Add a variable at the top (outside functions)
var currentPage = 0;
Then add a line in your goToPage function to track the page you're on.
currentPage = pageNumber;
Now that you're tracking you can add a previous and next function.
function goNextPage(){
goToPage(currentPage-1);
}
function goPreviousPage(){
goToPage(currentPage+1);
}
Then call it from the previous and next buttons.
<button onClick="goNextPage()" class="next-button"></button>
<button onClick="goPreviousPage()" class="previous-button"></button>
Here's a codepen: https://codepen.io/srirachapen/pen/WNZOXQZ
It's barebones and you may have to handle things like non existent div IDs.
HTML
<button class="next-button" onclick="nextContent()"></button>
<button class="previous-button" onclick="prevContent()"></button>
JS
var pageid = 0;
var maxpage = 3;
function nextContent() {
if(pageid == maxpage) return
pageid++
swapContent(`operation${pageid}`)
}
function prevContent() {
if(pageid == 1) return
pageid--
swapContent(`operation${pageid}`)
}
you can try this to switch between pages. But you may need to edit the "swapContent" method more sensibly.
Track the Current Page
Whatever solution you use to render pages & links (manual hardcoded links & content vs externally-stored & auto-generated), one thing is unavoidable: You need to track the current page!
var currentPage = 0
Then, any time there's a page change event, you update that variable.
With the current page being tracked, you can now perform operations relative to it (e.g. +1 or -1)
I'd suggest making a goToPage(page) function that does high-level paging logic, and keep your swapContent() function specifically for the literal act of swapping div content. In the future, you may find you'd want to use swapContent() for non-page content, like showing a "Welcome" or "Help" screen.
Example:
function goToPage(page) {
// Update `currentPage`
currentPage = page
// ... other logic, like a tracking event or anything else you want you occur when pages change
// Do the actual content swap, which could be your existing swapContent()
swapContent('operation'+page)
}
You'd invoke the function like so:
goToPage(3) // Jump to a specific page
goToPage(currentPage + 1) // Go to the next page
goToPage(currentPage - 1) // Go to the prev page
You can make separate helper functions like "goToNextPage()" if you desire, but for sure you start with a fundamental page-change function first.

Format text as user inputs in a contenteditable div

I'm attempting to make a page that allows users to input text and it will automatically format the input -- as in a screenplay format (similar to Amazon's StoryWriter).
So far I can check for text with ":contains('example text')" and add/remove classes to it. The problem is that all of the following p tags inherit that class.
My solution so far is to use .next() to remove the class I added, but that is limited since there might be need for a line break in the script (in dialogue for instance) and that will remove the dialogue class.
$('.content').on('input', function() {
$("p.input:contains('INT.')").addClass("high").next(".input").removeClass("high");
$("p.input:contains('EXT.')").addClass("high").next(".input").removeClass("high");
});
I can't get || to work in the :contains parameter either, but that's the least of my issues.
I have a JS fiddle
I've worked on this for a while now, and if I could change only the node that contains the text (INT. or EXT. in this example) and leaves the rest alone that would work and I could apply it to the rest of the script.
Any help would be appreciated, I'm new to the stackoverflow so thank you.
See the comments in the code below for an explanation of what's going on.
Fiddle Example
JQuery
var main = function(){
var content = $('.content');
content.on('input', function() {
$("p.input").each(function() {
//Get the html content for the current p input.
var text = $(this).html();
//indexOf will return a positive value if "INT." or "EXT." exists in the html
if (text.indexOf('INT.') !== -1 || text.indexOf('EXT.') !== -1) {
$(this).addClass('high');
}
//You could include additional "if else" blocks to check and apply different conditions
else { //The required text does not exist, so remove the class for the current input
$(this).removeClass('high');
}
});
});
};//main close
$(document).ready(main);

Counting classes on another page and displaying them

To save me a lot of work editing a number in when adding a document to a site I decided to use javascript to count the number of elements with a class doc .
I am two main problems:
There is trouble displaying the variable. I initially thought this was because I hadn't added function, however when I tried adding this the variable was still not displayed.
The elements with the class I want to count are on another page and I have no idea how to link to it. For this I have tried var x = $('URL: /*pageURL*/ .doc').length; which hasn't worked.
Essentially I want the total elements with said class name and this to be displayed in a span element.
Currently I have something similar to what's displayed below:
<script>
var Items = $('.doc').length;
document.getElementById("display").innerHTML=Items;
</script>
<span id="display"></span>
Found an example of something similar here where the total numbers of articles are displayed.
Edit:
#ian
This code will be added to the homepage, domain.net/home.html. I want to link to the page containing this documents, domain.net/documents.html. I've seen this done somewhere before and if I remember correctly they used url:domainname.com/count somewhere in their code. Hope this helps.
Here is a jQuery call to retrieve the url "./" (this page) and parse the resulting data for all elements with class "lsep" "$('.lsep', data)". You should get back a number greater than 5 or so if you run this from within your debug console of your browser.
$.get("./", function(data, textStatus, jqXHR)
{
console.log("Instances of class: " + $('.lsep', data).length)
});
One important thing to remember is that you will run into issues if the URL your are trying to call is not in the same origin.
Here's an updated snippet of code to do what you're describing:
$(document).ready(
function ()
{
//var url = "/document.html" //this is what you'd have for url
//var container = $("#display"); //this is what you'd have for container
//var className = '.data'; //this is what you'd have for className
var url = "./"; //the document you want to parse
var container = $("#question-header"); //the container to update
var className = '.lsep'; //the class to search for
$.get(url, function (data, textStatus, jqXHR) {
$(container).html($(className, data).length);
});
}
);
If you run the above code from your browser's debug console it will replace the question header text of "Counting classes on another page and displaying them" with the count of instances the class name ".lsep" is used.
First, you have to wait until the document is ready before manipulating DOM elements, unless your code is placed after the definition of the elements you manipulate, wich is not the case in your example. You can pass a function to the $ and it will run it only when the document is ready.
$(function () {
//html() allows to set the innerHTML property of an element
$('#display').html($('.doc').length);
});
Now, if your elements belongs to another document, that obviously won't work. However, if you have used window.open to open another window wich holds the document that contains the .doc elements, you could put the above script in that page, and rely on window.opener to reference the span in the parent's window.
$('#display', opener.document.body).html($('.doc').length);
Another alternative would be to use ajax to access the content of the other page. Here, data will contain the HTML of the your_other_page.html document, wich you can then manipulate like a DOM structure using jQuery.
$.get('your_other_page.html', function(data) {
$('#display').html($('.doc', data).length);
});

Text not changing in jQuery

I seem to be doing something wrong in the following code: http://jsfiddle.net/yunowork/qKj6b/1/
When you click next, the text within the span .hiddentext should be displayed in the span .showtext on top and correspond to the right Race (Rn). For example when R3 is highlighted the content of that .hiddentext "Race 3Oregon 14:30" should be displayed within the span .showtext.
This is the line where I make a mistake:
$('.showtext').text($('.hiddentext').first('td:first').text());
What am I doing wrong here?
Let's start simple:
Your problem:
$('.showtext').text($('.hiddentext').first('td:first').text());
you are saing, that, grab all .hiddentext, choose the first that has a td ... witch is not what you have in code, you have, td that contains hiddentext... so, the other way around.
What you want to do is simply get the current NEXT td and grab the hiddentext, so, just change to:
$('.showtext').text($nextCol.find('.hiddentext').text());
Now, can you see that the <br/> is not correctly rendered? That's because you are setting the text property, and you should set the html property.
the final code should be something like:
$('.showtext').html($nextCol.find('.hiddentext').html());
live example: http://jsfiddle.net/qKj6b/8/
Your code:
every time you need to have placeholders to provide some data to a context, please, DO NOT USE HTML TAGS to hold such values and hide them... make the use of the data- attribute, witch is a HTML5 complience, and works very well in any browser even if it does not have not HTML5 support, like IE6.
your table definition (td) that currently is:
<td class="visible" id="r2">
<span class="hiddentext">Race 2<br />Santa Fe 12:00</span>
<strong>R2</strong>
</td>
should be something like:
<td class="visible" id="r2" data-text="Race 2<br />Santa Fe 12:00">
R2
</td>
witch is way easier to read, and from your javascript code, you can easily get this as:
var hiddenText = $nextCol.data("text");
Your code (part 2):
This one is quite simple to know
Every time you are repeating yourself, you're doing it wrong
You have the methods for Next and Prev almost exactly as each other, so, you are repeating everything, for this, you should refactor your code and just use one simple method, this way, any future change only happens in one place, and one place only.
$(".next").click(function(e){
e.preventDefault();
var $nextCol = $('.highlighted').next('td');
MoveCursor($nextCol, 'next');
});
$(".previous").click(function(e){
e.preventDefault();
var $prevCol = $('.highlighted').prev('td');
MoveCursor($prevCol, 'prev');
});
function MoveCursor(col, side) {
var maxCol = 8;
if((side === 'next' && col.length != 0) ||
(side == 'prev' && col.length != 0 && col.index() >= maxCol)) {
$('.highlighted').removeClass("highlighted");
col.addClass("highlighted");
// show current title
$('.showtext').html(col.data('text'));
if (col.hasClass("invisible")) {
col.removeClass("invisible");
col.addClass("visible");
var $toRem;
if(side == 'prev')
$toRem = col.next('td').next('td').next('td').next('td').next('td').next('td');
else
$toRem = $nextCol.prev('td').prev('td').prev('td').prev('td').prev('td').prev('td');
$toRem.removeClass("visible");
$toRem.addClass("invisible");
}
}
}
Live Example: http://jsfiddle.net/qKj6b/22/
It should be
$('.showtext').html($('.highlighted .hiddentext').html());
Similar for the prev link...
or even better, thanks to #balexandre:
$('.showtext').html($nextCol.find('.hiddentext').html());
$('.showtext').html($prevCol.find('.hiddentext').html());
Fiddle
Update to match #balexandre hint: Fiddle 2
Do the following:
var $currCol = $('.highlighted'); //to get the current column
$('.race strong').text($currCol.closest('.highlighted').first('td:first').text());
.hiddentext class selects all the spans and the first() will always return you the first td.
Just make sure you select .hiddentext from the currently highlighted column and you are good to go.
$('.showtext').text($('.highlighted .hiddentext').first('td:first').text());
Try this (Same for both)
$('.showtext').html($currCol.find('span.hiddentext').html());
Working Example.

jQuery UI Tabs: Targeting Dynamic Tab from a Link

Recently I've been looking at opening a tab using this script:
$('.tofour').click(function() { // bind click event to link
$tabs.tabs('select', 3); // switch to third tab
return false;
});
However my specific problem is that the site I'm working on does not always load the same tab set. The tabs can change dependent on whether certain information exists. Example:
In certain situations we'll have enough data for:
Product Data (#overview)
Specifications (#specs)
Accessories (#accessories)
Services (#services)
Customer Reviews (#reviews)
And in other situations there will be only enough data to populate two tabs
Product Data (#overview)
Accessories (#accessories)
As you can imagine this creates a problem as the tab number can change; the Specification tab (#specs) might be either the second tab, or the first tab (if Product Data doesn't exist), or Specifications tab might not exist at all.
So, for the sake of argument, lets say I wish to target the Specifications tab. I guess the first thing would be to check if the div id #specs exists. Then I guess I've got to create a link that will target that. But can I target an id instead of a tab number, as in the usual example (above)?
Can anyone help with this? My jQuery skills are, I'm ashamed to admit, pretty poor.
I thank you kindly in advance.
You could get the index via this code, then check if it's -1 (that means it doesn't exist)
Note: This assumes that the a tag for the tab has the id of specs
var index = $('#tabs a').index($('#specs'));
if (index > -1) {
$('#tabs').tabs('select', index);
}
Create a javascript array containing the tab id as the key and the tab index as the value:
// if you're using php and the tabs that need to be generated are in a variable called $tabs
// you could work this out in other languages
$count = count($tabs);
for($i=0;$i<=$count;$i++){
$tab = $tabs[$i];
echo 'tab_indexes[' . $tab['id'] . '] = ' . $i . ';'; // id as in #specs, etc
}
Then use the array in jQuery:
$('#to_specs').click(function() { // bind click event to link
$('#tabs').tabs('select', tab_indexes['#specs']); // switch to specs tab
return false;
});
This should be good for the scenario
You can replace element.id.match('specs') with your desired condition
$('.tofour').click(function(evt) {
$('#tabs a').each(function(index,element){
if(index != -1 && element.id.match('specs')){
$('#tabs').tabs('select', index);
return false;
}
});
});
$("#m").live('click',function(){
$('#tabs').tabs({ selected: "#tabs-1" });
});
Try this. Let me know further.

Categories

Resources