Referring to sibling of parent div in HTML - html

I have two div elements:
<div id="one">
Link to two
</div>
<div id="two">
Link to me
</div>
This causes the following when I click on the link with href attribute being #two:
http://domain.com/one#two
but I want:
http://domain.com/#two
Is this possible without using javascript?

Solution
Considering the strange behavior of your page, NO, it's not possible without JavaScript.
On click event of the links, go to the location specified in the href:
Javascript
window.onload = function(){
/* On window load event, we loop through each link */
var a = document.getElementsByTagName('a');
for (var elem in a)
{
/* If it's a DOMElement */
if(a[elem].nodeType ==1)
{
/* We bind the window.location.href event, sending it to the value of the href attribute of the selected anchor element. */
a[elem].addEventListener("click",function(e){window.location.href = this.getAttribute('href');alert(window.location.href);});
/* console.log(window.location.href); */
}
}
}
-->Live Demo<--

Related

JQuery populate div with link content but also need to move (like anchor link) to area where div located

I have unordered list of links. Using JQuery, when clicked, the link's contents (a div with image and text) are loaded into the section specified. This all works beautifully. But I'm wondering how to also get the onclick function to move the view to the div's location on the page similarly to how anchor tag works. Here is the site where you can see the div being populated, but not moving down to view it. https://www.thecompassconcerts.com/artists.php
My JQuery knowledge is not awesome (I'm being generous).
I followed Osama's suggestion to add event listener and I got almost correct results. Upon first click...contents are loaded but do not move. But on every successive click, it functions perfectly: Contents loaded and move to div (like an anchor link) works! BUT...not on Safari or Mobile Safari.
Here is my jQuery. I assume if first click is not working that I must add listener before the first click?? Can the event listeners be added on page load BEFORE the function to prevent default click, etc.?
<script>
// BEGIN FUNCTION TO CAPTURE AND INSERT CONTENT
$(document).ready(function () {
// PREVENT DEFAULT LINK ACTION
$('.bio').click(function (e) {
e.preventDefault();
// ADD LISTENER TO EACH ITEM BY CLASS
var list = document.getElementsByClassName("bio");
for (let i = 0; i < list.length; i++) {
list[i].onclick = moveToDiv;
}
// FUNCTION TO MOVE TO LOCATION
function moveToDiv() {
document.location = "#performbio";
}
// STORE the page contents
var link = $(this).attr("href");
// load the contents into #performbio div
$('#performbio').load(link);
});
});
</script>
Here is the HTML with links in unordered list
<!-- CONTRIBUTING ARTISTS LIST AND BIOS -->
<section id="artists">
<h2>Contributing Artists</h2>
<ul class="cols">
<li><a class="bio" href="performers/first-last.html">First Last</a></li>
<li><a class="bio" href="performers/first-last.html">First Last</a></li>
<li><a class="bio" href="performers/first-last.html">First Last</a></li>
</ul>
</section>
Here is HTML of Section where code is being inserted by function
<!-- Performer Bios Dynamically updated -->
<section id="performbio">
</section>
Here is div contents that are being inserted
<div class="artistbio">
<p class="artistname">First Last</p>
<img class="artistimg" src="performers/img/name.jpg">
<p>lots of text here</p>
</div>
If I understand it right, you want to scroll to the section where the details appear on clicking any item in the list but through js and not HTML. In that case, you would add an onclick listener on to the list elements like so:
listElement.onclick = moveToDiv;
The function:
function moveToDiv() {
document.location = "#performbio";
}
A simple way to add a listener to all of the elements:
var list = document.getElementsByClassName("bio");
for (let i = 0; i < list.length; i++) {
list[i].onclick = moveToDiv;
}
For the edited post, you need to move the function definition out of the document.ready function. you would change the script to:
// FUNCTION TO MOVE TO LOCATION
function moveToDiv() {
document.location = "#performbio";
}
$(document).ready(function () {
// PREVENT DEFAULT LINK ACTION
$('.bio').click(function (e) {
e.preventDefault();
// ADD LISTENER TO EACH ITEM BY CLASS
var list = document.getElementsByClassName("bio");
for (let i = 0; i < list.length; i++) {
list[i].onclick = moveToDiv;
}
// STORE the page contents
var link = $(this).attr("href");
// load the contents into #performbio div
$('#performbio').load(link);
});
});
Another Solution: Using scrollIntoView
First, get all the elements into a variable using querySelectorAll
var elements = document.querySelectorAll(".bio");
Then create a function, for the scrolling part:
function scroll(element) {
element.scrollIntoView();
}
Then just add the onclick listener:
for (let i = 0; i < elements.length; i++) {
elements[i].addEventListener('click', function() {
scroll(elements[i]);
});
}
I found it very frustrating to try to accomplish these two tasks so instead of a jQuery solution I opted for a CSS solution.
I populated my DIV with all the php includes, gave them unique id's for the anchors to work and then used CSS to hide them by default until clicked and it works like a charm....shows only what I need to show and goes there like an anchor is supposed to.
I must thank Ghost for all of your help and efforts to try and solve this via jQuery. You were very kind and generous.
Here is the code I used:
My collection of links.
<li><a class="bio" href="#artist-name1">Name 1</a></li>
<li><a class="bio" href="#artist-name2">Name 2</a></li>
which anchors to these divs
<div class="bio-container" id="artist-name1">
<?php include('performers/name-lastname.html'); ?>
</div>
<div class="bio-container" id="artist-name2">
<?php include('performers/name-lastname.html'); ?>
</div>
Then I use this CSS to hide those divs until the anchors are clicked.
I'm using [id*="artist-"] to target only links with such text...very easy. Not ideal for a massive list...but mine is not so large so it will do for this situation.
[id*="artist-"] {display: none;}
[id*="artist-"]:target {display: block;}

Remove Certain CSS Style from Html Page

I have a Html page which has anchor tag, I Need to remove certain style applied already in html page for anchor tag while the html page is opened throw Iframe.
HTML Content as below:
<html>
<body>
<div>some content<a href="http://www.website.com" name="test1"/> some content </div>
</body>
</html>
I tried as below:
a[name^="test1"]:before{
content:"[prefix text]";
display:inline;
color:red;
}
a[name^="test1"]:after{
content:"suffix text";
display:inline;
color:green;
}
iframe a[name^="test1"]:before{
display:none;
}
iframe a[name^="test1"]:after{
display:none;
}
But inside "iframe" also these styles has been applying.
You have to first detect if your page is rendered inside an iframe and in that case apply an alternative CSS. It' can't be done with vanilla CSS then it has to be done with some JavaScript:
<script type="text/javascript">
function getTopWindow() {
try {
return window.top;
} catch {
// If we can't access window.top then browser is restricting
// us because of same origin policy.
return true;
}
}
function isRendererdInFrame() {
// If top window is null we may safely assume we're in iframe
return window.self !== getTopWindow();
}
function loadCss(location) {
if(document.createStyleSheet) {
document.createStyleSheet('http://server/stylesheet.css');
} else {
var styles = "#import url('" + location + "');";
var newSS=document.createElement('link');
newSS.rel='stylesheet';
newSS.href='data:text/css,'+escape(styles);
document.getElementsByTagName("head")[0].appendChild(newSS);
}
}
</script>
Code to load CSS from JavaScript is from How to load up CSS files using Javascript?.
With all that code you may simply write (even just after that inside <script> block):
var cssToLoad = isRendererdInFrame() ? "iframe.css" : "not-iframe.css";
loadCss("http://server/" + cssToLoad);
Of course same technique can be applied to patch CSS with iframe specific styles:
if (isRenderedInFrame())
loadCss("http://server/iframe-patch.css");
i dont know how to detect if page is opened in iframe or not, but there is one possible(not very nice) workaround, you can set iframe to width which is not commonly used by devices (example 463px) and then set media query for this resolution which apply when content is shown in this iframe. This is really nasty way since its not 100% and i would not recommending that.

Apply style to grandparent of the grandchild with specific value [duplicate]

This question already has answers here:
Is there a CSS parent selector?
(33 answers)
Closed 8 years ago.
I have the following code:
<div class="photos-wrapper" id="detailPhoto">
<div class="pseudo">
fixedTEXT
</div>
<div class="image-wrapper">
</div>
<div class="activites">
</div>
<div class="commentaire">
</div>
</div>
I want to include my own CSS style to this first and main <div class="photos-wrapper" id="detailPhoto"> but the only way to do this is by identify the grandchild selector i.e <a href="#/123456/"> because there are multiple occurrences of the same code.
Maybe it will be a bit more clear when I show what I tried:
a[href*="123456"] > div.pseudo > div.photos-wrapper[id^="detailPhoto"] {
display: none !important;
}
div.photos-wrapper[id^="detailPhoto"] < div.pseudo < a[href*="123456"] {
display: none !important;
}
That's the way I tried to do so but it obviously is not working.
The thing I am probably trying to do here is called a parent selector but I'm not quite sure.
#edit
Let's take a look on this code, it's actually more detailed:
http://jsfiddle.net/60ezqtL7/
The goal is to hide by display: none; style whole divs that are containing exactly the same values i.e. PHOTO 1
There's no need to use jQuery in this case (or many other cases).
detailPhoto.classList.toggle('hide', detailPhoto.querySelector('[href=#/123456]'))
As I mentioned in my comment to your answer, there is not parent or ancestor selecor. The easiest and most efficient way to to it via jQuery is the has() method.
$('#detailPhoto').has('a[href*="123456"]').hide(); // or use .addClass() instead
Use Google to host jquery for you.
Demo : I've used the class selector in the demo as id should be unique.
addClass Demo
UPDATE
Given your update and assuming you want to display 1 and only 1 of each photo, additional wrappers with photos with the same href will be hidden.
/*Loop through each link in div with cass psudo
in a div with class photos-wrapper*/
var found = {};
$(".photos-wrapper .pseudo a").each(function(){
var $this = $(this);
var href = $this.attr("href");
//if the href has been enountered before, hide the .photos-wrapper ancestor
if(found[href]){
$this.closest(".photos-wrapper").hide();
/*Other options:
Use Css direct
$this.closest(".photos-wrapper").css("display", "none");
Assign a duplicate class, then style that class ass appropriate
$this.closest(".photos-wrapper").addClass("duplicate");
*/
}else{
//otherwise add it to the array of what has been found
found[href] = true;
}
});
Demo
If you're not familiar with jquery, make sure to read up on how it is implemented and the purpose of $(document).ready();
Update 2
To hide all containers with replicated href use:
//Loop through each a tag
$(".photos-wrapper .pseudo a").each(function () {
var $this = $(this);
//Get the href
var href = $this.attr("href");
//Check if more than one exists
if ($('.photos-wrapper .pseudo a[href="' + href + '"]').size() > 1) {
//Hide all .photo-wrapper containers that have the replicated href
$('.photos-wrapper .pseudo a[href="' + href + '"]').closest(".photos-wrapper").hide();
}
});
Another Demo
I still suggest removing duplicates server-side if at all possible.
On a complete side note, the <center> tag was depreciated back at HTML4 and should no longer be used. Use CSS instead. There are pleanty of examples out there on how to center content using CSS.
At this time there is not a way to do this with only CSS, but you can do it easily with JQuery. This will search the descendants of #detailPhoto and hide the href (set it to display: none;).
<script>
$(function() {
$('#detailPhoto').find('a[href$="#/123456/"]').hide();
});
</script>
To search parents, you'd use this.
<script>
$(function() {
$('a[href$="#/123456/"]').closest('#detailPhoto').hide();
});
</script>
To use this you will also need the JQuery library added to the head of your document.
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>

How to create a "placeholder" for DIV that act like textfield?

Div don't have a placeholder attribute
<div id="editable" contentEditable="true"></div>
I want <Please your enter your Name> to show in DIV when the User backspace the whole text in the DIV, or no text on inside, How can I do it?
Here is a pure CSS only solution:-
<div contentEditable=true data-ph="My Placeholder String"></div>
<style>
[contentEditable=true]:empty:not(:focus):before{
content:attr(data-ph)
}
</style>
Here, we basically select all contentEditable <divs> that are empty & blurred. We then create a pseudo element before the CSS selection (the editable div) and fix our placeholder text (specified the data-ph attribute) as its content.
If you are targeting old school CSS2 browsers, change all occurrences of data-ph to title
Correction.......the :empty selector is not supported in IE version 8 and earlier.
What I find in other answers is that when using :not(:focus) pseudo class, I have to click again in order to get the blinking cursor and be able to type. Such issue doesn't happen if I click on an area other than the placeholder.
My workaround is simply removing :not(:focus). Even though in this way the placeholder will still be there after I click on the editable div, I'm able to type no matter where in the div I click, and the placeholder disappears immediately after I type something.
BTW, I inspected YouTube's comment div implementation, seems they are doing the same thing, e.g. #contenteditable-root.yt-formatted-string[aria-label].yt-formatted-string:empty:before
.editableDiv1,
.editableDiv2 {
border-bottom: 1px solid gray;
outline: none;
margin-top: 20px;
}
.editableDiv1[contentEditable="true"]:empty:not(:focus):before {
content: attr(placeholder)
}
.editableDiv2[contentEditable="true"]:empty:before {
content: attr(placeholder)
}
<div class="editableDiv1" contentEditable=true placeholder="If you click on this placeholder, you have to click again in order to get the blinking cursor and type..."></div>
<div class="editableDiv2" contentEditable=true placeholder="Click on placeholder is fine, it'll disappear after you type something..."></div>
You can try this one !
html:
<div contentEditable=true data-text="Enter name here"></div>
css:
[contentEditable=true]:empty:not(:focus):before{
content:attr(data-text) }
check it out (demo)
in HTML
<div id="editable" contenteditable="true">
<p>Please your enter your Name</p>
</div>
in JavaScript
jQuery.fn.selectText = function(){
var doc = document;
var element = this[0];
console.log(this, element);
if (doc.body.createTextRange) {
var range = document.body.createTextRange();
range.moveToElementText(element);
range.select();
} else if (window.getSelection) {
var selection = window.getSelection();
var range = document.createRange();
range.selectNodeContents(element);
selection.removeAllRanges();
selection.addRange(range);
}
};
$("#editable").click(function() {
$("#editable").selectText();
});
jsFiddle

CSS selector in the URL

When you have a url like this www.example.com/#signup, what the browser does is just to focus it's view on the HTML element with id signup, is that right?
Is it possible to change the element's CSS style if it's focused in that way?
E.g. let's say I have a div element, with the id signup, then if I enter www.example.com, the div's background is white and if I enter www.example.com/#signup it's yellow. Like "emphasizing" the sign up form. Is this at all possible?
:target { background-color: yellow; }
The :target psuedo-class does exactly this.
You can read the window.location.hash property when the page loads and apply the corresponding css classs. Something like:
<script type='text/javascript>
function init(){
var hash = window.location.hash.substr(1);
var element = document.getElementById(hash);
if(element){
element.className += " emphasize";
}
}
</script>
<body onload="init()">
...
</body>