Let's start with I'm not fluent in javascript, but I know a little. I'm on a platform that is running code I can't see on the back-end. That means I can only control so much. For example, there is a tag:
{{ component.quality_switch }}
When the page loads, it swaps that with:
<div class="co-quality-switch" data-behavior="quality_switch">
<a class="co-quality-switch" href="#" data-behavior="switch-low" style="">
<i class="co-icon-video-camera"></i>
watch in high quality
</a>
</div>
My goal, is to replace the text of the "a" link from "watch in high quality" to "toggle captions". So I experimented and removed the first {{component.quality_switch}} tag and replaced it with the outer div it normally pulls, with an ID added to the div:
<div id="captiontoggle" class="co-quality-switch" data-behavior="quality_switch">
</div>
When the page loaded, it spat back the same as before, with my added id on the div. Progress!
<div id="captiontoggle" class="co-quality-switch" data-behavior="quality_switch">
<a class="co-quality-switch" href="#" data-behavior="switch-low" style="">
<i class="co-icon-video-camera"></i>
watch in high quality
</a>
</div>
So apparently there is some java on the back-end on the data-behavior="quality_switch" part that is adding all this code. The kicker is, I need all the other things that come with that data-behavior command as that is what swaps my video source to the caption version and back when clicked. So I can't remove it. So my next thought was let's just use JS to change the innerHTML of that "a" link. The innerHTML is:
<i class="co-icon-video-camera"></i>watch in low quality
So if I can just swap that to "toggle captions" I'd be all set. But how can I swap the innerHTML of the "a" link when it doesn't have an ID? I can only assign an ID to it's parent DIV (captiontoggle). I tried adding this script:
<script>
var x = document.getElementById("captiontoggle");
var y = x.getElementsByTagName("a");
y.innerHTML = "test";
</script>
... but it didn't change anything. From my experimenting it looks like maybe I can't do this 2 layers down... Like I could change the innerHTML of captiontoggle, but not it's "a" element.
I'm open to suggestions! Thanks.
You need to use parent reference to get children and change there innerHTML
<script>
var x = document.getElementById("captiontoggle");
var y = x.children[0];
y.innerHTML = "test";
</script>
Working snippet:
var x = document.getElementById("captiontoggle");
var y = x.children[0];
y.innerHTML = "test";
<div id="captiontoggle" class="co-quality-switch" data-behavior="quality_switch">
<a class="co-quality-switch" href="#" data-behavior="switch-low" style="">
<i class="co-icon-video-camera"></i> watch in high quality
</a>
</div>
Related
I'm using Jcink Forums - I can style divs based on the user group which can be used as a html variable (for IDs).
How can I change the link based on the ID?
I'm assuming this cannot be done via just css and html however I'm not well-versed in JS
For Example (not the full code, just a really abridged version):
Stylesheet:
#admin .avatar {background-image:url("admin.jpg");}
#mod .avatar {background-image:url("mod.jpg");}
HTML:
<div id="<!-- |g_id| -->">
<a href="link changes based on div id">
<div class="avatar"></div>
</a>
</div>
If you can script, you can do something like (inline for demonstration, you can loop over all divs and change their links)
<div id="<!-- |g_id| -->">
<a href="whatever" onclick="this.href=this.closest('div[id]').id=='xxx'?'zzz':'yyy'">
<div class="avatar"></div>
</a>
</div>
where an ID of xxx will set the href to zzz otherwise set it to yyy
You can use setAttribute to set the link href according to the id
var ele=document.querySelectorAll("div");
Object.values(ele).forEach((e)=>{
if (e.getAttribute("id") == "abcd") {
var link = e.querySelector("a");
link.removeAttribute("href");
link.setAttribute("href", "www.link2.com");
}
})
<div id="abcd">
<a href="link1">
<div class="avatar">aa</div>
</a>
Don't know if title makes sense to you, let me expand:
I have a base html file, that contains, among other things iframe1. iframe1 contains 6 links that should link to anchors in a div in iframe2; and iframe2 is loaded in place of iframe1 with target="_self". Now, the trick is, that it should scroll the div, not the iframe2 itself, as there are other things in iframe2 that should stay in view.
A lot of searching didn't get me anywhere, so I don't even know if this is possible, so I thought I'll give it a try here, before being forced to rework this entire convoluted structure to something else. I'm new to javascript, but I know what a function or variable is :) Thanks.
So, in the master html I have:
<div class="content">
<iframe class="iframes" src="iframes/i-servlinks.html"></iframe>
</div>
In iframe1 (called i-servlinks.html here) I have 6 of these:
<div class="works">
<a class="worklinks" href="i-servs.html" target="_self">Linktoanchor</a>
</div>
And in iframe2 (called i-serv.html here) I have:
<div class="servlinks">
<a class="tab-item" href="#link1">1</a>
<a class="tab-item" href="#link2">2</a>
<a class="tab-item" href="#link3">3</a>
<a class="tab-item" href="#link4">4</a>
<a class="tab-item" href="#link5">5</a>
<a class="tab-item" href="#link6">6</a>
</div>
<div class="servs">
<!-- a lot of text, with the 6 anchors spread out in it, and this is the div that should scroll, servlinks div should stay in view on top of iframe2 -->
</div>
Well, I gave up, after trying a thousand scrollTo type plugins and scripts, it just wouldn't work right in my setup. So, instead I moved the contents of iframe1 and iframe2 into my main html, and put iframe1 into a div that keeps the content of iframe2 just outside the main container, until I hide it with any of the 6 links onclick (with like two lines of javascript). I reworked my html and css a little, and BANG, it works like a charm.
Same functionality, but actually much cleaner, less files and less scripts. So this just goes to demonstrate that thinking simpler is usually better.
I think you would need to use some Javascript to override the default scroll behaviour. I have create a jsFiddle to illustrate.
$('a').on('click',function(e){
e.preventDefault();
var $this=$(this);
var id = $this.attr('href');
var offset = $(id)[0].offsetTop;
var wrapY=$('.wrap')[0].offsetTop;
$('.wrap').scrollTop(offset-wrapY);
});
I have a working example here
http://enginiku.byethost17.com/stack.php
What I want is to copy the data to clipboard based on the block clicked. That works perfectly fine. However the problem is I need to click on the block, move cursor away from the block, click again and only then does the data gets copied. I understand that maybe it is because of the area turning into flash object.
But I want it to copy the data in one click only(the first time). Kindly suggest a way out !!
Here is my script
<script>
function copytocb(el){
var id = $(el).attr('id');
ZeroClipboard.setDefaults({moviePath:'http://enginiku.byethost17.com/ZeroClipboard.swf'});
var clip = new ZeroClipboard($('#'+id));
clip.on('complete',function(client,args){
alert('Copied');
});
}
</script>
And here is the relevant html
<div class="central">
<div class="maincontent">
<div class="leftcontent">
<span id="ss">Some text</span>
</div>
<div class="rightcontent">
<span id="block1" onclick="copytocb(this)" data-clipboard-text="Img1">Img</span>
<span id="block2" onclick="copytocb(this)" data-clipboard-text="Img2">Img</span>
<span id="block3" onclick="copytocb(this)" data-clipboard-text="Img3">Img</span>
<span id="block4" onclick="copytocb(this)" data-clipboard-text="Img4">Img</span>
<span id="block5" onclick="copytocb(this)" data-clipboard-text="Img5">Img</span>
</div>
</div>
</div>
Once the clip has been created and assigned to the span in question the click on it produces the desired result. Have you tried putting the contents of your copytocb() function in the on-document-ready section ($(function(){}))?
Edit:
$(document).ready(function() {
ZeroClipboard.setDefaults({moviePath:'http://enginiku.byethost17.com/ZeroClipboard.swf'});
var DOMarr=$('#rightcontent span').map(function(){return this;});
var clip = new ZeroClipboard(DOMarr);
clip.on('load',function(client,args){alert("Clipboard is ready for action.");});
})
Also: leave out the onclick="copytocb(this)" on the spans themselves. This should not be necessary since the overlaying flash movie will look for the click event itelf (hopefully).
Just tested this. Also look at the given examples of their page.
2. Edit:
The clipboard-texts can also be generated dynamically by setting an appropriate mouseoverevent on the underlying spans like
$('#rightcontent span').mouseover(function(){
var clip.setText($(this).text());
console.log(clip.options.text); // just to show the effect ...
});
I also tried using mousedown on the same elements but that did not work, because the clip-event will always be triggered before the mousedown event of the span.
My website is based on a platform and I can change a little bit of the layout, but certain parts render code automatically. My problem? It is in English and I need it in Spanish. I can add javascript before the body of the website but I can't change the html directly so I was thinking I could use onload to change the text. What do you guys think? I can use jQuery, too, if that helps.
I need to change this:
<div class="c_wrapper">
<h3 class="d_customize_title" align="left">
<span id="left_title">
Playera Max
</span>
<a onclick="d.showProductInfo(); return false;" href="#">
Product details
</a>
</h3>
</div>
to this:
<div class="c_wrapper">
<h3 class="d_customize_title" align="left">
<span id="left_title">
Playera Max
</span>
<a onclick="d.showProductInfo(); return false;" href="#">
Detalles del producto
</a>
</h3>
</div>
Two options:
Find the part in the theme (platform) that is rendering the code and change it from there (best option)
Use jQuery to replace the html:
$(".c_wrapper a").text("Detalles del producto");
Example:
<script type="text/javascript">
$(".c_wrapper a").text("Detalles del producto");
</script>
</body>
Working Example:
http://jsfiddle.net/vtHBV/
As others have mentioned it's a bit hacky to do this with Javascript but here's another way to do it without jQuery:
// helper to make sure we get a sibling that is an element
function getNextSibling(node){
sibling = node.nextSibling;
while (sibling.nodeType != 1){
sibling = sibling.nextSibling;
}
return sibling;
}
// set text
getNextSibling(document.getElementById('left_title')).innerHTML = 'Detalles del producto';
Demo: http://jsfiddle.net/louisbros/dkymR/
This is perfect for jQuery, if you don't have control over the content when you initially load it it may be the best option. Below is a working sample for your example:
$(function(){
$("#left_title + a").text("Detalles del producto");
});
I am fairly new to javascript and DOM and I am having a problem with manipulating DOM using javascript for the following html code.
<html>
<head>
<title>Testing</title>
</head>
<body>
<marquee direction=up height=400 scrollAmount=3.7 scrollDelay=70 onmousedown="this.stop()" onmouseover="this.stop()" onmousemove="this.stop()" onmouseout="this.start()">
<span>Lion</span><br><br>
<span>Tiger</span><br><br>
<span>Giraffe</span><br><br>
<span>Dinosaur</span><br><br>
<span>Cat</span><br><br>
<span>Dog</span><br><br>
<span>Llama</span><br><br>
<span>Rat</span><br><br>
<span>Rhino</span><br><br>
<span>Reindeer</span><br><br>
<a href="#" ><span >buffalo</span></a><br><br>
<a href="#" ><span >Yak</span></a><br><br>
<a href="#" ><span >Deer</span></a><br><br>
<a href="#" ><span >moose</span></a><br><br>
<a href="#" ><span >Rabbit</span></a> <br><br>
<a href="#" ><span >Duck</span></a> <br><br>
<a href="#" ><span >Peacock</span></a><br><br>
<a href="#" ><span >Crow</span></a><br><br>
<a href="#" ><span >Raven</span></a><br><br>
<a href="#" ><span >Swan</span></a><br><br>
</marquee>
<input type="button" value="Set Me Fixed" onclick="setMeFixed();" />
</body>
</html>
Sorry if the above html code is bad.I am writing a greasemonkey script for the same which is produced by a site which i have simplified here. So i have no control over it whatsoever.
I want the [marquee] tag to be replaced with the [div] tag so that it becomes static and i don't have to wait forever for the 100th link in the marquee to come up. ;-). So I wrote the following script. (I am new to js programming and yes i know that my script sucks :-) )
function setMeFixed(){
var fixedElement=document.createElement('div');
var marqueeElement=document.getElementsByTagName('marquee')[0];
//var clonedMarqNodes=marqueeElement.cloneNode(true);
for(i=0;i<marqueeElement.childNodes.length;i++){
fixedElement.appendChild(marqueeElement.childNodes[i]);
}
marqueeElement.parentNode.replaceChild(fixedElement,marqueeElement);
}
Many problems occured. The resulting output did not show few links on it.
Peacock, Crow, Swan, Raven are not seen in the output and all the tags are messed up after it becomes static with spaces printed above and no breaks between the links.
As a beginner javascript programmer i am stuck here and any assistance in the right direction would be much appreciated. Any way to elegantly solve this problem? Thanks.
paul bullard.
PS: I am using Fx 3.0.11.
As for the reason that your resultant document ended up missing a few nodes, I can tell you why:
When you appendChild to another node, the DOM removes it from wherever it used to be. So when you go through the first node, it's removing children at the same time as it advances i down the DOM. Assume that A, B, C, etc. are child nodes, and this is what happens at the start of your loop:
i=0 ↓
MARQUEE: A B C D E F
DIV:
i=1 ↓
MARQUEE: B C D E F
DIV: A
i=2 ↓
MARQUEE: B D E F
DIV: A C
i=3 ↓
MARQUEE: B D F (accessing this gives you an exception!)
DIV: A C E
You can fix this in one of two ways. Firstly, you could make this change:
fixedElement.appendChild(marqueeElement.childNodes[i]);
// becomes
fixedElement.appendChild(marqueeElement.childNodes[i].cloneNode());
so you're always manipulating a cloned node, and the original <marquee> doesn't have elements removed, or you can make this change:
fixedElement.appendChild(marqueeElement.firstChild);
so that you always take the first item in the <marquee> and don't lose elements that way.
Have you considered using innerHTML?
var marq = document.getElementsByTagName('marquee')[0];
var div = document.createElement('div');
div.innerHTML = marq.innerHTML;
marq.parentNode.appendChild(div);
marq.parentNode.removeChild(marq);
Not the most efficient, but straight-forward.
See: http://jquery.nodnod.net/cases/586
If your goal is to get rid of <marquee>s on all web sites, perhaps the best way to do so is to just edit your userContent.css file to include the following:
marquee {
-moz-binding: none; display: block; height: auto !important;
/* This is better than just display:none !important;
* because you can still see the text in the marquee,
* but without scrolling.
*/
}
(I think that's actually already included in that file as a template, even :)