First time ever touching javascript here, so bear with me.
My file structure looks like so:
I want to change the image in my HTML using js. Here's the relevant HTML code:
<!DOCTYPE html>
<html>
<head>
<title>Assignment 3A</title>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="style/assignment_3.css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="data/data.js"></script>
<script src="script/htmlMaker.js"></script>
<script src="script/assignment_3.js"></script>
<script id="news-detail-template" type="text/html">
<img class='news_photo' src='{{photo}}' >
<div class='news_heading'>{{heading}}</div>
<div class='date'>{{Date}}</div>
<div class='news_detail'>{{details}}</div>
</script>
<script id="news-item-template" type="text/html">
<div news_id='{{id}}' class='news_item' > {{heading}} </div>
<img class='news_img' src='data/NBA.jpg'>
</script>
</head>
<body>
<div class="newsDiv">
<div class="left">Latest</div>
<div id="news" class="marquee"></div>
<img id="toggle" class="right" src="data/pause.png" onclick="toggle(this)">
</div>
<div id="detail" class="detail">
</div>
</body>
</html>
And then the corresponding js code in assignment_3.js:
function toggle(image) {
if (image.src != "data/pause.png")
{
image.src='data/pause.png';
}
else if (image.src == "data/pause.png")
{
image.src='data/play.png';
}
}
Obviously, something is amiss here, as the browser doesn't seem to recognize my image paths at all. How would I go about doing this correctly?
When you use image.src, it returns the full path of the image. In the if condition, you only checks the relative path of the image. To check for the relative path of the image, you can use image.getAttribute('src').
function toggle(image) {
if (image.getAttribute('src') == "data/pause.png") {
image.setAttribute('src', 'data/play.png');
} else {
image.setAttribute('src', 'data/pause.png');
}
}
<body>
<div class="newsDiv">
<div class="left">Latest</div>
<div id="news" class="marquee"></div>
<img id="toggle" class="right" src="data/pause.png" onclick="toggle(this)">
</div>
<div id="detail" class="detail">
</div>
</body>
I have modelled a minimal, complete and verifiable example of your problem in this JSFiddle. I don't see any issues in your toggle logic. The only thing you need to consider is using img.getAttribute('src') instead of img.src. This is because
img.getAttribute('src') - Gives you the actual value that the HTML markup has set
img.src - Effective absolute path of the source
function toggle(img) {
// var playSrc = "data/play.png"; // to use your file instead
var playSrc = "https://cdn.iconscout.com/icon/premium/png-256-thumb/play-button-1516951-1285078.png";
// var pauseSrc = "data/pause.png"; // to use your file instead
var pauseSrc = "http://www.pngall.com/wp-content/uploads/5/Pause-Button-Transparent.png";
if (img.getAttribute('src') != pauseSrc)
{
img.setAttribute('src', pauseSrc);
}
else // The part if (image.src == "data/pause.png") is redundant
{
img.setAttribute('src', playSrc);
}
}
With that out of the way, you have a lot of junk in the <head> tag, which you need to remove (I have put them below). Probably, the code isn't working because of that.
<script id="news-detail-template" type="text/html">
<img class='news_photo' src='{{photo}}' >
<div class='news_heading'>{{heading}}</div>
<div class='date'>{{Date}}</div>
<div class='news_detail'>{{details}}</div>
</script>
<script id="news-item-template" type="text/html">
<div news_id='{{id}}' class='news_item' > {{heading}} </div>
<img class='news_img' src='data/NBA.jpg'>
</script>
As Harshana points out, you need to use the getAttribute function to check equality. You can set the image source using a regular assignment operator, but you cant use == to check for equality.
Related
I'm trying to get the child image of a clicked div.
I want to get it's src value. But it's returning undefined.
Could someone point me in the right direction?
Tried using Jquery .find() https://api.jquery.com/find/
Tried using Jquery .children() https://api.jquery.com/children/
Both return undefined.
for (let i = 0; i < $('#draw-raster > div').length; i++) {
$(document).on('click', '#raster-item'+i, () => {
let image = $(this).children('img').attr('src'); //undefined
let image2 = $(this).find('img').attr('src'); //undefined
if (image) {
console.log(image);
return alert("image child found!");
}
return setTimeout(() => {
$('#raster-item'+i).children('img').hide();
}, 4500);
});
$('#image'+i).hide();
}
load html:
for(let i = 0; i < 16; i++)
{
let image = displayImages();
$('#draw-raster').prepend(
"<div id=raster-item" + i + " class='imageh"+i+"' data-id=" + i + "><img src='"+ displayImages() +"' class='image "+i+"' id='image"+ i +"' alt='Failed to load image' width='173.19' height='107.3'></div>"
);
}
html page:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Memory</title>
<script src="inc/js/jquery.min.js"></script>
<link rel="stylesheet" href="inc/css/boostrap.min.css">
<link rel="stylesheet" href="inc/css/memory.css">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</head>
<body>
<div class="container justify-content-center">
<div class="wrapper">
<div class="row">
<div class="col-lg-9">
<div class="card">
<div class="card-header bg-dark" style="color:white;">
<h2>Memory</h2>
</div>
<div class="card-body">
<section class="col-12 mx-auto" id="draw-raster">
</section>
</div>
</div>
</div>
<div class="col-lg-3">
<div class="card">
<div class="card-header bg-dark" style="color:white;">
<h2>Turns</h2>
</div>
<div class="card-body">
<div id="turns">Turns: 0</div>
<div id="sets">Sets: 0</div>
</div>
</div>
<div class="form-group">
<button class="btn btn-success col-12" type="button" id="reset">Reset scores</button>
</div>
</div>
</div>
</div>
</div>
<script src="inc/js/memory.js"></script>
</body>
</html>
Both attempts return undefined, i'm uncertain what would work.
Yes, I've been spamming google too. :'^)
A couple of notes on your code:
1) If you want to use this you'll need to switch from an arrow function back to a regular anonymous function. Arrow functions don't have a this of their own and will borrow the context from their outer lexical environment. It's why your code keeps return undefined.
2) You don't need a loop. The benefit of using jQuery is that you can operate on collections of elements all at once. In your case you're attaching a single event listener to a parent element (here: document) and waiting for events to bubble up from the .raster-item imgs and be "captured". This is called event delegation and is useful when you want to process new elements added to the DOM after it has loaded.
2) You will find it easier to use a class instead of many ids.
Here's an example based on your code with these changes:
// Use event delegation to add an event listener to the element with
// the container class that watches out for click events on **all**
// elements with the raster-item class that contain images
$('.container').on('click', '.raster-item img', function () {
// `$(this)` will be the image element, so simply grab its src
// from the attribute
console.log($(this).attr('src'));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="raster-item"><img src="https://dummyimage.com/50x50/555/fff.png" /></div>
<div class="raster-item"><img src="https://dummyimage.com/50x50/777/fff.png" /></div>
<div class="raster-item"><img src="https://dummyimage.com/50x50/999/fff.png"/></div>
<div class="raster-item"><img src="https://dummyimage.com/50x50/bbb/fff.png" /></div>
</div>
You don't need jQuery for this. You can harness the power of event bubbling with vanilla JavaScript.
In the web page below, the code inside the script tags, listen for a click event and runs some code if that event happens, i.e. bubbles, through a DIV element:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Clicked div img</title>
</head>
<body>
<div class="catcher">
<p>This is a div with an image inside</p>
<img src="image-to-pick.jpg" alt="image to pick" ()>
</div>
<script>
document.addEventListener('click', function (event) {
if (event.target.tagName == 'DIV') {
var imgToPick = event.target.querySelector('img');
console.log(imgToPick.src); // add your code here
}
}, false);
</script>
</body>
</html>
In other words, you trigger a "click event" whenever you click on that page, that event bubbles up until it reaches the root of the HTML document (which you can imagine as an upside-down tree where the root is the html tag).
If you don't need or don't want to let it bubble to the elements "above" you DIV, you can also stop the propagation of that click event by using event.stopPropagation(), right after you handle the img src.
You can find more info about how this works here on MDN (Mozilla Dev. Network)
I'm not quite sure in what context you need to do this, but with jquery it's pretty straight forward.
If you have multiple images within a parent div, you can set the child images as the selecters for the click event, and return each image src when clicked on directly.
The resulting jquery is only three lines long this way, and you can add as many images as you like to the parent div:
<div class="image-container">
<img id="first" src="first-source-goes-here.jpg" alt="img text" />
<img id="second" src="second-source-goes-here.jpg" alt="img text" />
<img id="third" src="third-source-goes-here.jpg" alt="img text" />
</div>
$(".image-container > img").click(function() {
// replace 'alert' with what ever you need it to be
alert( $(this).attr("src") )
})
EDIT:
In response to Andy's comment on my answer below, if you are loading images once the DOM has been loaded, then you could run a check on the click parent div to see if there are any images within it before returning the source:
$(".image-container").click(function() {
if( $(this).children("img").length > 0 ) {
alert( $(this).find("img").attr("src") )
} else {
alert('there are no images here')
}
})
I am working on a website and am planning on having it so that certain links will have a value set, this will change what container is displayed when the page loads. How would I have it so the link passes a value that would be used for the onload functions?
Here is a mockup of my HTML code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Lunch</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
<script src="script.js"></script>
</head>
<body onload="navBar(); dateChange(); tabulate(0);">
<nav>
<ul>
<li>Appitizers</li>
<li>Breakfast</li>
<li>Lunch</li>
<li>Dinner</li>
<li>Dessert</li>
<li>Ten-Course Dinner</li>
<li>Send in your Recipes!</li>
</ul>
</nav>
<div class="main">
<div class="box">
<ul>
<li><a onclick="tabulate(this.id);" id="1">Chicken Clubhouse Sandwiches</a></li>
<li><a onclick="tabulate(this.id);" id="2">Smokey Tomato Soup</a></li>
</ul>
</div>
<div id="0" class="recipe" style="display: block;">
<div class="tabs">
<a class="tab"> </a>
</div>
<div class="page">
<p>The recipes you'll find here are ones you can use to impress guests at your next get together</p>
</div>
</div> <!--recipe card end-->
<div class="recipe" id="1">
<h1>Chicken Clubhouse Sandwiches</h1>
</div> <!--recipe card end-->
<div class="recipe" id="2">
<h1>Smokey Tomato Soup</h1>
</div> <!--recipe card end-->
</div>
</body>
</html>
And here is my tabulate function:
function tabulate(tabNum){
$('.recipe').each(function() {
if(tabNum==this.id){
this.style.display="block";
}
else{
this.style.display="none";
}
});
}
You would need to make use of the URL's GET parameters:
lunch.html?item=2
In conjunction with passing the variable into the JavaScript function:
// Set up an object for GET parameter
var $_GET = {};
// Find and extract the various GET parameters
if(document.location.toString().indexOf('?') !== -1) {
var query = document.location.toString().replace(/^.*?\?/, '').replace(/#.*$/, '').split('&');
for(var i=0, l=query.length; i<l; i++) {
var aux = decodeURIComponent(query[i]).split('=');
$_GET[aux[0]] = aux[1];
}
}
// Target a specific get parameter, given the GET parameter name
var tabNum = $_GET['item']; // Comes through as '2' in this example
// Pass the parameter into the function
function tabulate(tabNum){
$('.recipe').each(function() {
if(tabNum==this.id){
this.style.display="block";
}
else{
this.style.display="none";
}
});
}
See this post and this post for further reference.
Hope this helps! :)
I haven't tested this, but you should be able to get by with passing a GET variable via PHP into tabulate(), in a way like this:
function tabulate(tabNum){
$('.recipe').each(function() {
if(tabNum==this.id){
this.style.display="block";
}
else{
this.style.display="none";
}
});
}
window.addEventListener('DOMContentLoaded', function(evt) {
var id = <?php echo htmlspecialchars($_GET['id'], ENT_COMPAT, 'utf8'); ?>;
tabulate(id);
});
I'm trying to use a variable from a page loaded inside a DIV in another DIV.
The text in the "bar" DIV on the "index.html" page should be replaced by the item id selected from the "page.html" loaded as an <object></object> inside the "content" DIV.
Or the item id should at least be stored in a global variable - which hasn't been working either - because when I run a function from the "index.html" page to retrieve it, it displays as "undefined".
All the code is below:
index.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="index_style.css">
<title>Access element of other DIV</title>
</head>
<body>
<div id="bar">This text should be replaced by the Item ID selected below</div>
<div id="content">
<object type="text/html" data="page.html" width="100%" height="100%"></object>
</div>
</body>
</html>
index_style.css
body{
margin: 0px;font-family:arial;font-size:30px;text-align:center;color:#fff;
}
#bar{
position:relative;height:100px;line-height:100px;background-color:#555c60;color:#74de90;
}
#content{
position:absolute;top:100px;bottom:0px;right:0;left:0;overflow-y:hidden;
}
page.html
<link rel="stylesheet" href="page_style.css">
<script type="text/javascript" src="main.js"></script>
<center>
This is <b>page.html</b> which has been loaded <u>inside</u> the "content" DIV<br><br>
</center>
<div class="items" onclick="use_item_id(this);" id="item1">Item 1</div>
<div class="items" onclick="use_item_id(this);" id="item2">Item 2</div>
<div class="items" onclick="use_item_id(this);" id="item3">Item 3</div>
page_style.css
body{font-family:arial;font-size:30px;color:#fff;background-color:#1b1e4b;text-align:center;}
.items{cursor:pointer;}
.items:hover{color:#ff0000;}
main.js
function use_item_id(selected)
{
current_item = selected.getAttribute("id");
document.getElementById('bar').innerHTML = current_item;
alert(current_item);
}
The line document.getElementById('bar').innerHTML = current_item; in "main.js" seems to be the problem and I can't get it to work. The alert(current_item); works fine when the line above it isn't there so it's definitely getting the item id's correctly from "page.html". It's just not setting them as the innerHTML on the "index.html" page, or even storing them in a global variable to be retrieved from a function run on the "index.html" page (as mentioned above). Any code examples would be greatly appreciated.
I think it might be because the use_item_id() function is being executed from another page, so I might need some alternatives or other functions to get it to work.
It'd be great if anyone knows what the issue is. I appreciate all replies. Thanks in advance :)
You are not on the same document ... then in main.js
replace
document.getElementById('bar').innerHTML = current_item;
with
parent.document.getElementById('bar').innerHTML = current_item;
this solves your problem.
If you're trying to access variables from HTML documents it's highly recommended to use the data attribute. This is an example for a comment section:
In my item I set the data key for loading
<div class='resp-col col-12 comment-user-data'>
<div class='resp-col col-9'>
<div class="post-profile-image" style='background-image:url("<?=$user->profile_image?>")'></div>
<?=Html::a("<p class='post-user'>".$username."</p>", Url::to(['/account/'.$user->id.'/'.$user->username]))?>
</div>
<div class='resp-col col-3'><button class='reply-to' data-assoc-id='<?=$model->id?>' data-assoc-name='<?=$username?>'><i class="material-icons">reply</i></button></div> <-- set the data-assoc-id
</div>
<div class='resp-col col-12 comment-content-data'>
<?=$model->content?>
</div>
jQuery to load data key
$('.reply-to').on('click',function(){
$('#submit-comment').data('assoc-id', $(this).data('assoc-id'));
$('#comment-content').val('#'+$(this).data('assoc-name')+' ');
$('.base-modal').animate({
scrollTop: $("#comment-content").offset().top
}, 2000);
if($('#comment-content').css('display') == 'none'){
toggleCommentVisibility();
}
});
I have this piece of code :
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div class="container">
<p class="demo">test </p>
<a href="xx" class="focusme">
<img src="images/testimage.gif" alt="" >
</a>
<a href="xx" class="focusme">
<img src="images/testimage.gif" alt="">
</a>
</div>
<script type="text/javascript" src="js/jquery.2.1.4.min.js"></script>
<script>
$(function () {
$(".focusme").focus(function(){
$(this).img.invert();
});
});
</script>
</html>
What I want to do is to invert the images when the <a> tag got focus, but I'm stuck to register the focus and blur event for them.
Here is what I'm trying to achieve :
for example, the html :
<a href="xx" class="focusme">
<img src="images/testimage.gif" alt="" id="img1">
</a>
So at this point, it's easy to access the img above because it has an ID :
$("#img1").invert();
but what i want is :
$(function () {
$(".focusme").focus(function(){
var img = $(this).img;
img.invert();
});
});
P/s : the invert() function is from a seperated js file, and is working well if I manually call it like this :
$("#img1").invert();
How can this be done?
Use the focus on <a> and use find() for the image
$(function () {
$("a.focusme").focus(function(){
$(this).find('img').invert();
});
});
The problem is that <img> tags cannot be focused by default. However, you can allow them to be focused by setting the tabIndex property.
$(".focusme").each(function(i) {
$(this).attr('tabIndex', i + 1)
})
After adding that, your code will be executed when you click on the images, and when you tab between them.
example: http://codepen.io/anon/pen/xZzzOm?editors=1010
I recently came across ContentTools.js and i thought that might be nice addition to the site im working on. Going through getting started/tutorials gets me nowhere - script is not working however I look at it.
Copying exact same scripts from author page or running it back from master bin works but implementing to actual website fails.
The only thing that worked for me (on empty html page) was that script loaded editable fields erasing it's content either saved or canceled edit (if that makes and sense to you).
$(document).ready(function() {
window.onload = function() {
var editor;
editor = ContentTools.EditorApp.get();
editor.init('.editable', 'data-name');
editor.bind('save', function(regions) {
var xhr, payload, name;
this.busy(true);
payload = new FormData();
for (name in regions) {
if (regions.hasOwnProperty(name)) {
payload.append(name, regions[name]);
}
}
function onStateChange(ev) {
if (ev.target.readyState == 4) {
editor.busy(false);
if (ev.target.status == '200') {
new ContentTools.FlashUI('ok');
} else {
new ContentTools.FlashUI('no');
}
}
}
xhr = new XMLHttpRequest();
xhr.addEventListener('readystatechange', onStateChange);
xhr.open('POST', '/save-my-page');
xhr.send(payload);
});
}).call(this);
<link href="http://getcontenttools.com/styles/content-tools.css" rel="stylesheet" />
<script src="http://getcontenttools.com/scripts/content-tools.js"></script>
<!DOCTYPE html>
<html>
<body>
<p class="editable" data-name="c1">asd</p>
<p class="editable" data-name="c2">123</p>
<p class="editable" data-name="c3">asd123</p>
<div class="ct-app">
<div class="ct-widget ct-ignition ct-ignition--ready ct-widget--active">
<div class="ct-ignition__button ct-ignition__button--edit"></div>
<div class="ct-ignition__button ct-ignition__button--confirm"></div>
<div class="ct-ignition__button ct-ignition__button--cancel"></div>
<div class="ct-ignition__button ct-ignition__button--busy"></div>
</div>
</div>
</body>
</html>
Ofc all libraries are loaded and there is no js errors. It just doesn't work.
First off, you have error in your code, some brackets are not aligned, also you should have one div element around your p elements and init editor around it, in this case it will init editor for each p, here is fiddle http://jsfiddle.net/zx4sw47L/
P.S. There is a problem with loading fonts, because of cross-domain issue, but example is working.
I'm also starting using getContentTools.
From what I understand you have some errors in your HTML markup and you're missing another js file to init getContentTools
<!DOCTYPE html>
<html>
<head>
<link href="http://getcontenttools.com/styles/content-tools.css" rel="stylesheet" />
<script src="http://getcontenttools.com/scripts/content-tools.js"></script>
<script src="/path/to/editor.js"></script>
</head>
<body>
<div data-editable data-name="c1">
<p class="editable">asd</p>
</div>
<div data-editable data-name="c2">
<p class="editable">123</p>
</div>
<div data-editable data-name="c3">
<p class="editable">asd123</p>
</div>
<!-- this should be deleted as it is generated by getContentTools -->
<!--
<div class="ct-app">
<div class="ct-widget ct-ignition ct-ignition--ready ct-widget--active">
<div class="ct-ignition__button ct-ignition__button--edit"></div>
<div class="ct-ignition__button ct-ignition__button--confirm"></div>
<div class="ct-ignition__button ct-ignition__button--cancel"></div>
<div class="ct-ignition__button ct-ignition__button--busy"></div>
</div>
-->
</body>
</html>
The editor.js file should look like this to start
window.addEventListener('load', function() {
var editor;
});
Hope this helps