在我的html加载后,我无法加载导入的javascript文件。
我最近开始使用react进行编码,对此我很陌生。我在我的网站上包含一个图片库。每当我运行代码时,我都会收到此错误:
TypeError: Cannot read property 'querySelector' of null
据我了解,这是因为导入的“ homebasescript.js”首先运行,因此没有任何返回值。 如何更改代码以使其正常工作?我将非常感谢您的帮助!
import React, { Component } from 'react';
import './Homebase.scss';
import Shuffle from 'shufflejs';
import Demo from './Homebasescript.js';
class homebase extends Component {
render() {
return (
<section className="about-page">
<div className="container-about">
<div className="row-about">
<div className="col-12@sm">
<h1 className="about-title">Shuffle homepage demo</h1>
</div>
</div>
</div>
<div className="container-about">
<div className="row-about">
<div className="col-4@sm col-3@md">
<div className="filters-group">
<label htmlFor="filters-search-input" className="filter-label">Search</label>
<input className="textfield filter__search js-shuffle-search" type="search" id="filters-search-input" />
</div>
</div>
</div>
<div className="row-about">
<div className="col-12@sm filters-group-wrap">
<div className="filters-group">
<p className="filter-label">Filter</p>
<div className="btn-group filter-options">
<button className="btn btn--primary" data-group="space">Space</button>
<button className="btn btn--primary" data-group="nature">Nature</button>
<button className="btn btn--primary" data-group="animal">Animal</button>
<button className="btn btn--primary" data-group="city">City</button>
</div>
</div>
<fieldset className="filters-group">
<legend className="filter-label">Sort</legend>
<div className="btn-group sort-options">
<label className="btn active">
<input type="radio" name="sort-value" value="dom" defaultChecked /> Default
</label>
<label className="btn">
<input type="radio" name="sort-value" value="title" /> Title
</label>
<label className="btn">
<input type="radio" name="sort-value" value="date-created" /> Date Created
</label>
</div>
</fieldset>
</div>
</div>
</div>
<div className="container-about">
<div id="grid" className="row-about my-shuffle-container-about">
<div className="col-1@sm col-1@xs my-sizer-element"></div>
</div>
</div>
</section>
);
};
};
export default homebase;
import Shuffle from 'shufflejs';
class Demo {
constructor(element) {
this.element = element;
this.shuffle = new Shuffle(element, {
itemSelector: '.picture-item',
sizer: element.querySelector('.my-sizer-element'),
});
// Log events.
this.addShuffleEventListeners();
this._activeFilters = [];
this.addFilterButtons();
this.addSorting();
this.addSearchFilter();
}
/**
* Shuffle uses the CustomEvent constructor to dispatch events. You can listen
* for them like you normally would (with jQuery for example).
*/
addShuffleEventListeners() {
this.shuffle.on(Shuffle.EventType.LAYOUT, (data) => {
console.log('layout. data:', data);
});
this.shuffle.on(Shuffle.EventType.REMOVED, (data) => {
console.log('removed. data:', data);
});
}
addFilterButtons() {
const options = document.querySelector('.filter-options');
if (!options) {
return;
}
const filterButtons = Array.from(options.children);
const onClick = this._handleFilterClick.bind(this);
filterButtons.forEach((button) => {
button.addEventListener('click', onClick, false);
});
}
_handleFilterClick(evt) {
const btn = evt.currentTarget;
const isActive = btn.classList.contains('active');
const btnGroup = btn.getAttribute('data-group');
this._removeActiveClassFromChildren(btn.parentNode);
let filterGroup;
if (isActive) {
btn.classList.remove('active');
filterGroup = Shuffle.ALL_ITEMS;
} else {
btn.classList.add('active');
filterGroup = btnGroup;
}
this.shuffle.filter(filterGroup);
}
_removeActiveClassFromChildren(parent) {
const { children } = parent;
for (let i = children.length - 1; i >= 0; i--) {
children[i].classList.remove('active');
}
}
addSorting() {
const buttonGroup = document.querySelector('.sort-options');
if (!buttonGroup) {
return;
}
buttonGroup.addEventListener('change', this._handleSortChange.bind(this));
}
_handleSortChange(evt) {
// Add and remove `active` class from buttons.
const buttons = Array.from(evt.currentTarget.children);
buttons.forEach((button) => {
if (button.querySelector('input').value === evt.target.value) {
button.classList.add('active');
} else {
button.classList.remove('active');
}
});
// Create the sort options to give to Shuffle.
const { value } = evt.target;
let options = {};
function sortByDate(element) {
return element.getAttribute('data-created');
}
function sortByTitle(element) {
return element.getAttribute('data-title').toLowerCase();
}
if (value === 'date-created') {
options = {
reverse: true,
by: sortByDate,
};
} else if (value === 'title') {
options = {
by: sortByTitle,
};
}
this.shuffle.sort(options);
}
// Advanced filtering
addSearchFilter() {
const searchInput = document.querySelector('.js-shuffle-search');
if (!searchInput) {
return;
}
searchInput.addEventListener('keyup', this._handleSearchKeyup.bind(this));
}
/**
* Filter the shuffle instance by items with a title that matches the search input.
* @param {Event} evt Event object.
*/
_handleSearchKeyup(evt) {
const searchText = evt.target.value.toLowerCase();
this.shuffle.filter((element, shuffle) => {
// If there is a current filter applied, ignore elements that don't match it.
if (shuffle.group !== Shuffle.ALL_ITEMS) {
// Get the item's groups.
const groups = JSON.parse(element.getAttribute('data-groups'));
const isElementInCurrentGroup = groups.indexOf(shuffle.group) !== -1;
// Only search elements in the current group
if (!isElementInCurrentGroup) {
return false;
}
}
const titleElement = element.querySelector('.picture-item__title');
const titleText = titleElement.textContent.toLowerCase().trim();
return titleText.indexOf(searchText) !== -1;
});
}
}
document.addEventListener('DOMContentLoaded', () => {
window.demo = new Demo(document.getElementById('grid'));
});
错误:
TypeError: Cannot read property 'querySelector' of null
出现在我的“ Homebasescript.js”中。
答案 0 :(得分:0)
是的,问题似乎在于尝试在const storage = require('@google-cloud/storage')();
const myBucket = storage.bucket('my-bucket');
const file = myBucket.file('my-file');
const contents = 'This is the contents of the file.';
file.save(contents, function(err) {
if (!err) {
// File written successfully.
}
});
//-
// If the callback is omitted, we'll return a Promise.
//-
file.save(contents).then(function() {});
事件侦听器中创建新的Demo
实例。此事件将不考虑所有React组件的呈现,仅考虑实际HTML的初始加载(这可能是非常基本的,例如单个DOMContentLoaded
)。因此,在触发div
之后将不会渲染ID为"grid"
的元素,这就是为什么该元素显示为DOMContentLoaded
的原因。
在React项目中创建几乎所有东西的推荐方法是在其他组件中这样做。您可以将null
实例的创建移到Demo
类的生命周期方法中。但是,看起来您是在homebase
类内部呈现了一些HTML,然后使用homebase
类直接修改DOM来更改该HTML。
一种更好的方法是让Demo
也是一个React组件,并使其以Demo
的身份呈现div
。这种直接操作DOM的方法类似于旧的jQuery呈现方式,并且使用React,您可以使用JavaScript提前决定要呈现的内容,而不是呈现然后进行修改。组件也可以在内部保持自己的状态,而不需要将所有内容存储在CSS类中。所有这些功能一起使代码更具可读性。
基本上,您会得到类似的东西:
"grid"
您提供的代码中有很多内容要讨论,但是希望本示例演示了一些如何在React中控制渲染的方法。我真的建议您浏览intro docs,因为它们很容易使用,您会学到很多东西。让我知道是否可以在这里澄清任何内容!